Skip to content

Commit

Permalink
introduce object before tuple in the tutorials (#10664)
Browse files Browse the repository at this point in the history
  • Loading branch information
krux02 authored and narimiran committed Feb 14, 2019
1 parent b081eb4 commit 80992c7
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 31 deletions.
108 changes: 93 additions & 15 deletions doc/tut1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1441,31 +1441,111 @@ string that is "useless" and replace it with "useful".
Note: alternate ways of writing this are ``b[^8..^2] = "useful"`` or
as ``b[11..b.len-2] = "useful"`` or as ``b[11..<b.len-1] = "useful"``.

Objects
-------

The default type to pack different values together in a single
structure with a name is the object type. An object is a value type,
which means that when an object is assigned to a new variable all its
components are copied as well.

Each object type ``Foo`` has a constructor ``Foo(field: value, ...)``
where all of its fields can be initialized. Unspecified fields will
get their default value.

.. code-block:: nim
type
Person = object
name: string
age: int
var person1 = Person(name: "Peter", age: 30)
echo person1.name # "Peter"
echo person1.age # 30
var person2 = person1 # copy of person 1
person2.age += 14
echo person1.age # 30
echo person2.age # 44
# the order may be changed
let person3 = Person(age: 12, name: "Quentin")
# not every member needs to be specified
let person4 = Person(age: 3)
# unspecified members will be initialized with their default
# values. In this case it is the empty string.
doAssert person4.name == ""
Object fields that should be visible from outside the defining module have to
be marked with ``*``.

.. code-block:: nim
:test: "nim c $1"
type
Person* = object # the type is visible from other modules
name*: string # the field of this type is visible from other modules
age*: int
Tuples
------

A tuple type defines various named *fields* and an *order* of the fields.
The constructor ``()`` can be used to construct tuples. The order of the
fields in the constructor must match the order in the tuple's definition.
Different tuple-types are *equivalent* if they specify fields of
Tuples are very much like what you have seen so far from objects. They
are value types where the assignment operator copies each component.
Unlike object types though, tuple types are structurally typed,
meaning different tuple-types are *equivalent* if they specify fields of
the same type and of the same name in the same order.

The assignment operator for tuples copies each component. The notation
``t.field`` is used to access a tuple's field. Another notation is
The constructor ``()`` can be used to construct tuples. The order of the
fields in the constructor must match the order in the tuple's
definition. But unlike objects, a name for the tuple type may not be
used here.


Like the object type the notation ``t.field`` is used to access a
tuple's field. Another notation that is not available for objects is
``t[i]`` to access the ``i``'th field. Here ``i`` must be a constant
integer.

.. code-block:: nim
:test: "nim c $1"
type
Person = tuple[name: string, age: int] # type representing a person:
# a person consists of a name
# and an age
# type representing a person:
# A person consists of a name and an age.
Person = tuple
name: string
age: int
# Alternative syntax for an equivalent type.
PersonX = tuple[name: string, age: int]
# anonymous field syntax
PersonY = (string, int)
var
person: Person
personX: PersonX
personY: PersonY
person = (name: "Peter", age: 30)
# the same, but less readable:
# Person and PersonX are equivalent
personX = person
# Create a tuple with anonymous fields:
personY = ("Peter", 30)
# A tuple with anonymous fields is compatible with a tuple that has
# field names.
person = personY
personY = person
# Usually used for short tuple initialization syntax
person = ("Peter", 30)
echo person.name # "Peter"
Expand All @@ -1484,10 +1564,6 @@ integer.
# --> Error: type mismatch: got (tuple[street: string, number: int])
# but expected 'Person'
# The following works because the field names and types are the same.
var teacher: tuple[name: string, age: int] = ("Mark", 42)
person = teacher
Even though you don't need to declare a type for a tuple to use it, tuples
created with different field names will be considered different objects despite
having the same field types.
Expand Down Expand Up @@ -1519,6 +1595,8 @@ variables! For example:
echo badname
echo badext
Fields of tuples are always public, they don't need to be explicity
marked to be exported, unlike for example fields in an object type.

Reference and pointer types
---------------------------
Expand Down
25 changes: 9 additions & 16 deletions doc/tut2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,16 @@ and more efficient code. In particular, preferring composition over inheritance
is often the better design.


Objects
-------

Like tuples, objects are a means to pack different values together in a
structured way. However, objects provide many features that tuples do not:
They provide inheritance and information hiding. Because objects encapsulate
data, the ``T()`` object constructor should only be used internally and the
programmer should provide a proc to initialize the object (this is called
a *constructor*).
Inheritance
-----------

Objects have access to their type at runtime. There is an
``of`` operator that can be used to check the object's type:
Inheritance in Nim is entirely optional. To enable inheritance with
runtime type information the object needs to inherit from
``RootObj``. This can be done directly, or indirectly by
inheriting from an object that inherits from ``RootObj``. Usually
types with inheritance are also marked as ``ref`` types even though
this isn't strictly enforced. To check at runtime if an object is of a certain
type, the ``of`` operator can be used.

.. code-block:: nim
:test: "nim c $1"
Expand All @@ -71,11 +69,6 @@ Objects have access to their type at runtime. There is an
student = Student(name: "Anton", age: 5, id: 2)
echo student[]
Object fields that should be visible from outside the defining module have to
be marked by ``*``. In contrast to tuples, different object types are
never *equivalent*. New object types can only be defined within a type
section.

Inheritance is done with the ``object of`` syntax. Multiple inheritance is
currently not supported. If an object type has no suitable ancestor, ``RootObj``
can be used as its ancestor, but this is only a convention. Objects that have
Expand Down

0 comments on commit 80992c7

Please sign in to comment.