-
Notifications
You must be signed in to change notification settings - Fork 1
/
fun.robin
107 lines (81 loc) · 2.82 KB
/
fun.robin
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
;'<<SPEC'
-> Tests for functionality "Evaluate Robin Expression (with Small)"
You can define functions with `fun`. They can be anonymous.
| ((fun (a) a) (literal whee))
= whee
Function have "closure" behavior; that is, bindings in force when a
function is defined will still be in force when the function is applied,
even if they are no longer lexically in scope.
| ((let
| ((a (literal (hi)))
| (f (fun (x) (list x a))))
| f) (literal oh))
= (oh (hi))
Functions can take functions.
| (let
| ((apply (fun (x) (x (literal a)))))
| (apply (fun (r) (list r))))
= (a)
Functions can return functions.
| (let
| ((mk (fun (x) (fun (y) (prepend y x))))
| (mk2 (mk (literal (vindaloo)))))
| (mk2 (literal chicken)))
= (chicken vindaloo)
Arguments to functions shadow any other bindings in effect.
| (let
| ((a (literal a))
| (b (fun (a) (list a a))))
| (b 7))
= (7 7)
If a function is never called, its contents are not
evaluated.
| (let
| ((b (fun (a) (glerp a))))
| 7)
= 7
A function may have no arguments at all.
| ((fun () 7))
= 7
But, a function must have exactly both a body and a list of formal arguments.
Otherwise, an abort value will be produced.
| ((fun ()))
? abort
| ((fun))
? abort
| ((fun (a) a a))
? abort
An `illegal-arguments` abort will be produced if not enough arguments are
supplied to a function call.
| ((fun (a b) (glerp b a))
| (prepend 1 ()))
? abort (illegal-arguments
An `illegal-arguments` abort will be produced if too many arguments are
supplied to a function call.
| ((fun (a b) (glerp b a))
| 1 (prepend 2 ()) 3)
? abort (illegal-arguments
`fun` is basically equivalent to Scheme's `lambda`.
'<<SPEC'
(define fun (fexpr (args env)
(bind extend-with-args (fexpr (args env)
(bind-args (self env-to-extend formals actuals env-for-actuals) args env
(if (equal? formals ())
(if (equal? actuals ())
env-to-extend
(abort (list (literal illegal-arguments) (head (tail (tail args))))))
(if (equal? actuals ())
(abort (list (literal illegal-arguments) (head (tail (tail args)))))
(let (
(formal (head formals))
(actual (head actuals))
(rest-formals (tail formals))
(rest-actuals (tail actuals))
(evaled-actual (eval env-for-actuals actual))
(binding (list formal evaled-actual))
(extended-env (prepend binding env-to-extend))
)
(self self extended-env rest-formals rest-actuals env-for-actuals))))))
(fexpr (iargs ienv)
(bind extended-env (extend-with-args extend-with-args env (head args) iargs ienv)
(eval extended-env (head (tail args))))))))