-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathunshadow.robin
56 lines (44 loc) · 1.41 KB
/
unshadow.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
;'<<SPEC'
-> Tests for functionality "Evaluate Robin Expression (with Env)"
`unshadow` is similar to `unbind`, but only removes the latest binding
for the given identifier; previously shadowed bindings, if any exist,
will be visible instead.
| (unshadow yog-sothoth (if #t (literal x) (literal y)))
= x
| (unshadow if (if #t (literal x) (literal y)))
? abort (unbound-identifier if)
| (bind if (literal what)
| (unshadow if (if #t (literal x) (literal y))))
= x
| (bind q 400
| (unshadow q q))
? abort (unbound-identifier q)
| (bind q 200
| (bind q 400
| (unshadow q q)))
= 200
| (bind q 100
| (bind q 200
| (bind q 400
| (unshadow q (unshadow q q)))))
= 100
| (let ((q 100)
| (q 200)
| (q 400))
| (unshadow q (unshadow q q)))
= 100
`unshadow` is something of a gimmick that shows off Robin's ability
to manipulate the evaluation environment. In practice, the bindings
can be determined lexically, and a different identifier could always
be chosen instead.
'<<SPEC'
(define unshadow
(fexpr (args env)
(bind remove-binding-r (fun (self id li)
(if (empty? li)
li
(if (equal? (head (head li)) id)
(tail li)
(prepend (head li) (self self id (tail li))))))
(eval (remove-binding-r remove-binding-r (head args) env)
(head (tail args))))))