-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathhigherorder.edh
66 lines (47 loc) · 1.76 KB
/
higherorder.edh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
{
# partial functions
method f( a, b, c ) {
console.print( 'this is f()', a=a, b=b, c=c )
}
# partial is used to create partially applied functions
f1 = partial ( 1, 2 ) ( f )
# note the (|) pipe operator is flipped procedure call operator, then f2 is
# equivalent to f1, but more idiomatic
let f2 = f|partial( 1, 2 )
# note the pipe (|) operator has a rather low precedence -5, lower than the
# assign (=) operator's precedence 0, so if not writing it as a `let`
# statement, parenthesis is necessary, then f3 is equivalent too
f3 = ( f|partial( 1, 2 ) )
}
f1( 3 )
f2( 5 )
f3( 7 )
{
# args fusion
# with respecting to procedure call via ($) or (|), if an ArgsPack
# takes the place of a procedure (the callee), it just absorbs the other
# positional argument or a whole arguments pack, to form a new ArgsPack
# note (|) has higher precedence than ($), so parenthesis quoting is needed
( ( 2, 11, n=3 ) $ ( 9, 7, m=5 ) ) | console.print
; # this semicolon is necessary or the following round brackets will be
# parsed as procedure call
( 9, 7, m=5 ) | ( 2, 11, n=3 ) | console.print
}
{
# decorator
# %% # A decorator is usually written in the host language, but as well, it can be written in Đ the surface language, in form of an interpreter procedure
interpreter decor( callerScope, fe ) case callerScope.eval( fe ) of { f } -> {
callerScope.eval( expr method @(f.name) ( ***apk ) {
console.info<| 'Calling procedure `' ++ {$ f.name $} ++ '` with: ' ++ apk
{$ f $} ( ***apk )
} )
}
# %% # And used like this
decor$
method g ( a, b, c ) {
console.info<| 'This is g(), we have: ' ++ ( a=a, b=b, c=c, )
}
# %% # The decorated procedure can be used straight forward
g( 1, 2, 3 )
# %#
}