home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
s
/
s48.zip
/
MISC
/
ICON.SCM
< prev
next >
Wrap
Text File
|
1992-06-18
|
2KB
|
68 lines
; For Icon's alternation operator, a | b, we write (either a b).
(define-syntax either
(syntax-rules ()
((either x) x)
((either x y ...)
(%either (lambda () x) (lambda () (either y ...))))))
(define (%either thunk1 thunk2) ;Macro axuiliary
(let ((save *fail*))
((call-with-current-continuation
(lambda (k)
(set! *fail*
(lambda ()
(set! *fail* save)
(k thunk2)))
thunk1)))))
; (accumulate a) returns a list of all the possible values of the
; expression a. Prolog calls this "bagof"; I forget what Icon calls it.
(define-syntax accumulate
(syntax-rules ()
((accumulate x) (%accumulate (lambda () x)))))
(define (%accumulate thunk)
(let ((results '()))
(either (begin (set! results (cons (thunk) results))
(fail))
(reverse results))))
; Generate all the members of list l. E.g.
; (accumulate (+ (member-of '(10 20 30)) (member-of '(1 2 3))))
; => '(11 12 13 21 22 23 31 32 33)
(define (member-of l)
(if (null? l)
(fail)
(either (car l) (member-of (cdr l)))))
; Internal variable representing the failure stack.
(define (fail) (*fail*))
(define *fail* (lambda () (error "You didn't do (init).")))
; Crufty initialization hack that allows you to type failing
; expressions at the R-E-P loop (if there is an R-E-P loop). E.g. try
; evaluating the sequence
; (either 1 2)
; (fail)
; (+ (fail) 10)
(define (init)
(call-with-current-continuation
(lambda (k)
(set! *fail* (lambda () (k 'failed)))
'initialized)))
(display "Type (init) at the read-eval-print loop.")
(newline)