From db031e2b4741f7238433bc8b20beb12da5431b80 Mon Sep 17 00:00:00 2001 From: ReneSac Date: Mon, 3 Feb 2014 01:00:01 -0200 Subject: [PATCH 1/3] Expandeded part about different proc call syntaxes. --- doc/manual.txt | 74 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/doc/manual.txt b/doc/manual.txt index b85c49e037..da229d169b 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -2457,14 +2457,80 @@ notation. (Thus an operator can have more than two parameters): assert `*+`(3, 4, 6) == `*`(a, `+`(b, c)) +Method call syntax +------------------ + +For object oriented programming, the syntax ``obj.method(args)`` can be used +instead of ``method(obj, args)``. The parentheses can be omitted if there are no +remaining arguments: ``obj.len`` (instead of ``len(obj)``). + +This `method call syntax`:idx: is not restricted to objects, it can be used +to supply any type of first argument for procedures: + +.. code-block:: nimrod + + echo("abc".len) # is the same as echo(len("abc")) + echo("abc".toUpper()) + echo({'a', 'b', 'c'}.card) + stdout.writeln("Hallo") # the same as writeln(stdout, "Hallo") + +Another way to look at the method call syntax is that it provides the missing +postfix notation. + + +Properties +---------- +Nimrod has no need for *get-properties*: Ordinary get-procedures that are called +with the *method call syntax* achieve the same. But setting a value is +different; for this a special setter syntax is needed: + +.. code-block:: nimrod + + type + TSocket* = object of TObject + FHost: int # cannot be accessed from the outside of the module + # the `F` prefix is a convention to avoid clashes since + # the accessors are named `host` + + proc `host=`*(s: var TSocket, value: int) {.inline.} = + ## setter of hostAddr + s.FHost = value + + proc host*(s: TSocket): int {.inline.} = + ## getter of hostAddr + return s.FHost + + var + s: TSocket + s.host = 34 # same as `host=`(s, 34) + + Command invocation syntax ------------------------- -Routines can be invoked without the ``()`` if the call is syntactially +Routines can be invoked without the ``()`` if the call is syntatically a statement. This `command invocation syntax`:idx: also works for expressions, but then only a single argument may follow. This restriction means ``echo f 1, f 2`` is parsed as ``echo(f(1), f(2))`` and not as -``echo(f(1, f(2)))``. +``echo(f(1, f(2)))``. The method call syntax may be used to provide one +more argument in this case: + +.. code-block:: nimrod + proc optarg(x:int, y:int = 0):int = x + y + proc singlearg(x:int):int = 20*x + + echo optarg 1, " ", singlearg 2 # prints "1 40" + + let fail = optarg 1, optarg 8 # Wrong. Too many arguments for a command call + let x = optarg(1, optarg 8) # traditional procedure call with 2 arguments + let y = 1.optarg optarg 8 # same thing as above, w/o the parenthesis + assert x == y + +The command invocation syntax also can't have complex expressions as arguments. +For example: (`anonymous procs`_), ``if``, ``case`` or ``try``. The (`do +notation`_) is limited, but usable for a single proc (see the example in the +corresponding section). Function calls with no arguments still needs () to +distinguish between a call and the function itself as a first class value. Closures @@ -2479,6 +2545,7 @@ the closure and its enclosing scope (i.e. any modifications made to them are visible in both places). The closure environment may be allocated on the heap or on the stack if the compiler determines that this would be safe. + Anonymous Procs --------------- @@ -2505,6 +2572,9 @@ calls can use the ``do`` keyword: .. code-block:: nimrod sort(cities) do (x,y: string) -> int: cmp(x.len, y.len) + # Less parenthesis using the method plus command syntax: + cities = cities.map do (x:string) -> string: + "City of " & x ``do`` is written after the parentheses enclosing the regular proc params. The proc expression represented by the do block is appended to them. From 300c0376b5a85233dea9b1c9414a60ba585751d1 Mon Sep 17 00:00:00 2001 From: ReneSac Date: Mon, 3 Feb 2014 01:06:19 -0200 Subject: [PATCH 2/3] Fix optarg() and added two more tests. One for 'do notation' in a single function in an expression, another the trick of using the method call syntax to pass two parameters. --- tests/parser/tcommand_as_expr.nim | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/parser/tcommand_as_expr.nim b/tests/parser/tcommand_as_expr.nim index a9747b0acd..3c02f8cb3d 100644 --- a/tests/parser/tcommand_as_expr.nim +++ b/tests/parser/tcommand_as_expr.nim @@ -1,9 +1,11 @@ discard """ output: '''140 -5-120''' +5-120-120 +359''' """ +import math -proc optarg(x:int):int = x +proc optarg(x:int, y:int = 0):int = x + 3 * y proc singlearg(x:int):int = 20*x echo optarg 1, singlearg 2 @@ -13,5 +15,9 @@ proc foo(x, y: int): int = x-y let x = optarg foo 7.foo let y = singlearg foo(1, foo 8) +let z = singlearg 1.foo foo 8 + +echo x, y, z -echo x, y +let a = [2,4,8].map do (d:int) -> int: d + 1 +echo a[0], a[1], a[2] \ No newline at end of file From 5bd3ec0bfb77a1a7342a183876e45c333b804345 Mon Sep 17 00:00:00 2001 From: ReneSac Date: Mon, 3 Feb 2014 01:12:27 -0200 Subject: [PATCH 3/3] Remove spurious import added in the last commit. --- tests/parser/tcommand_as_expr.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/parser/tcommand_as_expr.nim b/tests/parser/tcommand_as_expr.nim index 3c02f8cb3d..22c49ab3f2 100644 --- a/tests/parser/tcommand_as_expr.nim +++ b/tests/parser/tcommand_as_expr.nim @@ -3,7 +3,7 @@ discard """ 5-120-120 359''' """ -import math +#import math proc optarg(x:int, y:int = 0):int = x + 3 * y proc singlearg(x:int):int = 20*x