Skip to content

Commit

Permalink
Merge #122
Browse files Browse the repository at this point in the history
122: doc/tut1: new section on functions and methods  r=saem a=ZoomRmc

This PR adds a new section on functions and methods to the first part of the tutorial.

The added text clarifies the differences between the three and provides some benefits of using `func`s which explains their existence in the language.

This PR aims to answer a repeating question of "which of the three should I use?" coming from new language users, which was observed on multiple occasions by the `@PMunch` and others.

Most of the work is by `@PMunch,` part about functions coauthored by me in a declined edit of the merged PR (nim-lang/Nim#19207)

Co-authored-by: Zoom <[email protected]>
  • Loading branch information
bors[bot] and ZoomRmc authored Dec 12, 2021
2 parents f8bd832 + 84a26cd commit 0563a67
Showing 1 changed file with 39 additions and 2 deletions.
41 changes: 39 additions & 2 deletions doc/tut1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -595,8 +595,10 @@ Procedures

To define new commands like `echo <system.html#echo,varargs[typed,]>`_
and `readLine <io.html#readLine,File>`_ in the examples, the concept of a
*procedure* is needed. (Some languages call them *methods* or *functions*.)
In Nim new procedures are defined with the `proc` keyword:
*procedure* is needed. You might be used to them being called *methods* or
*functions* in other languages, but |NimSkull|
`differentiates these concepts <tut1.html#procedures-funcs-and-methods>`_. In
|NimSkull|, new procedures are defined with the `proc` keyword:

.. code-block:: nim
:test: "nim c $1"
Expand Down Expand Up @@ -874,6 +876,41 @@ The example also shows that a proc's body can consist of a single expression
whose value is then returned implicitly.


Funcs and methods
-----------------

As mentioned in the introduction, |NimSkull| differentiates between procedures,
functions, and methods, defined by the `proc`, `func`, and `method` keywords
respectively. In some ways, |NimSkull| is a bit more pedantic in its definitions
than other languages.

Functions are essentially procedures with additional limitations set on them:
they can't access global state (except `const`) and can't produce side-effects.
This puts |NimSkull| functions closer to the concept of a mathematical function,
which might be familiar to you if you've ever done functional programming. The
main benefit of the imposed limits is that it's much easier to reason about the
code with minimized interdependence of its various parts, as data flows directly
through a function from its arguments to its output. The other notable advantage
is that the self-contained nature of a function makes it inherently more
portable and easier to test.

Even though these benefits apply to |NimSkull| functions, it's important to keep
in mind that a `func` can still change its mutable arguments: those marked as
`var` along with `ref` objects (which possess interior mutability). This still
allows functions to have additional outputs beside the return value, making them
not as "pure" as their mathematical counterparts.

Technically, the `func` keyword is a shorthand alias for `proc` tagged with
`{.noSideEffects.}`.

Unlike procedures, methods are dynamically dispatched. This sounds a bit
complicated, but it is a concept closely related to inheritance and object oriented
programming. If you overload a procedure (two procedures with the same name but
of different types or with different sets of arguments are said to be overloaded),
the procedure to use is determined at compile-time. Methods, on the other hand,
depend on objects that inherit from the `RootObj`. This is something that is covered
in much greater depth in the `second part of the tutorial<tut2.html#object-oriented-programming-dynamic-dispatch>`_.

Iterators
=========

Expand Down

0 comments on commit 0563a67

Please sign in to comment.