Merge branch 'devel' of https://github.com/Araq/Nimrod into devel

This commit is contained in:
Araq
2014-02-03 19:03:40 +01:00
2 changed files with 81 additions and 5 deletions

View File

@@ -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.

View File

@@ -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]