Wiki

Changes between Initial Version and Version 1 of AnonMethod

Show
Ignore:
Timestamp:
10/18/09 07:48:41 (15 years ago)
Author:
hopscc
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AnonMethod

    v1 v1  
     1= Anonymous Methods/Closures and lambdas =  
     2 
     3Cobra supports both anonymous methods (also known as closures where they capture the values of surrounding variables if referenced) [[br]] 
     4and a simpler single line expression form known as lambdas.  
     5 
     6Both are introduced with the "'''do'''" keyword.  
     7 
     8The syntax for closures is similar to that of the [wiki:Methods def] statement (defining a classes methods) 
     9except that there is no method name. 
     10 
     11The body of the closure follows the line the '''do''' (plus any paramList) is on, indented one level 
     12 
     13A lambda uses the same "do" keyword as closures, but the argument list is followed by "=<expr>" all on a single line. 
     14 
     15 
     16== Grammar == 
     17Anonymous Method 
     18{{{ 
     19do [as <Type>]        # no parameters 
     20    <body statements...> 
     21 
     22do(<paramList>) [as <Type>] 
     23    <body statements...> 
     24 
     25For these a parameter list is a comma separated list of name (and optionally type) specifications 
     26    <paramName> [as <Type>]  [, ...] 
     27}}} 
     28 
     29 
     30Lambdas 
     31{{{ 
     32do = <expr>               # no parameters 
     33do (<paramList>) = <expr>   # args passed as per invocation 
     34}}} 
     35 
     36 
     37== Examples == 
     38Anonymous Method 
     39{{{ 
     40sig ArithmeticOp(a as int, b as int) as int 
     41sig SimpleMethod 
     42# ... 
     43class Test 
     44    def callArithmeticOp(a as int, b as int, op as ArithmeticOp) as int 
     45        return op(a, b) 
     46 
     47    def invoke(method as SimpleMethod) 
     48        method() 
     49 
     50    #... 
     51    def run 
     52        assert 12 == .callArithmeticOp(3, 4, do(a as int, b as int)) 
     53            return a * b 
     54 
     55        # multiple statements in the anonymous method 
     56        assert 12 == .callArithmeticOp(3, 4, do(a as int, b as int)) 
     57            r = 0 
     58            for i in a 
     59                r += b 
     60            assert r == a * b 
     61            return r 
     62         
     63        # access members 
     64        assert 24 == .callArithmeticOp(3, 4, do(a as int, b as int)) 
     65            return a * b * .two 
     66 
     67        # access local vars 
     68        multiplier = 10 
     69        assert 120 == .callArithmeticOp(3, 4, do(a as int, b as int)) 
     70            return a * b * multiplier 
     71 
     72        count = 0 
     73        .invoke(do)      # no parameters 
     74            count += 1 
     75        assert count == 1 
     76}}} 
     77 
     78Lambda 
     79{{{ 
     80    t = [3, 2, 1] 
     81    t.sort(do(a as int, b as int)=a.compareTo(b)) 
     82}}} 
     83 
     84== Notes == 
     85 
     86The argument types are not yet inferred which is why you should specify them explicitly typed  
     87as in the examples above. 
     88 
     89Multiple closures on a single line are not yet supported. 
     90 
     91You can store a reference to a closure so long as you have a type for its signature. 
     92e.g 
     93{{{ 
     94class Test 
     95     
     96    def main is shared 
     97        t = [3, 2, 1] 
     98 
     99        # embedded closure 
     100        t.sort(do(a as int, b as int)) 
     101            return a.compareTo(b) 
     102 
     103        # store closure in local var 
     104        c as Comparison<of int> = do(a as int, b as int) 
     105            return a.compareTo(b) 
     106        t.sort(c) 
     107}}}