-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdynamic-wind-example.scm
75 lines (67 loc) · 2.07 KB
/
dynamic-wind-example.scm
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
;; An implementation of dynamic-wind (originally by Aubrey Jaffer in 1992)
;; and its application to the example code at sec. 6.4 in R5RS
;; cf. https://groups.csail.mit.edu/mac/ftpdir/scheme-mail/HTML/rrrs-1992/msg00194.html
;; https://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.4
(define *winds* '())
(define dynamic-wind
(lambda (<thunk1> <thunk2> <thunk3>)
(<thunk1>)
(set! *winds* (cons (cons <thunk1> <thunk3>) *winds*))
((lambda (ans)
(set! *winds* (cdr *winds*))
(<thunk3>)
ans)
(<thunk2>))))
(define call/cc
((lambda (oldcc)
(lambda (proc)
(define winds *winds*)
(oldcc (lambda (cont)
(proc (lambda (c2)
(_dynamic-do-winds *winds* winds)
(cont c2)))))))
call/cc))
(define _dynamic-do-winds
(lambda (from to)
(set! *winds* from)
(if (not (eq? from to))
(if (null? from)
(begin (_dynamic-do-winds from (cdr to))
((car (car to))))
(if (null? to)
(begin ((cdr (car from)))
(_dynamic-do-winds (cdr from) to))
(begin ((cdr (car from)))
(_dynamic-do-winds (cdr from) (cdr to))
((car (car to)))))))
(set! *winds* to)))
(define length
(lambda (lst)
(if (null? lst)
0
(+ 1 (length (cdr lst))))))
(define reverse
(lambda (lst)
(define _reverse2
(lambda (lst result)
(if (null? lst)
result
(_reverse2 (cdr lst) (cons (car lst) result)))))
(_reverse2 lst '())))
(display
((lambda (path c)
(define add (lambda (s)
(set! path (cons s path))))
(dynamic-wind
(lambda () (add 'connect))
(lambda () (add (call/cc
(lambda (c0)
(set! c c0)
'talk1))))
(lambda () (add 'disconnect)))
(if (< (length path) 4)
(c 'talk2)
(reverse path)))
'() #f))
(newline)
;; => (connect talk1 disconnect connect talk2 disconnect)