In their book "The Seasoned Schemer", Felleisen and Friedman introduce the try
function. According to http://community.schemewiki.org/?seasoned-schemer, this function can be defined as
(define-syntax try
(syntax-rules ()
((try var a . b)
(letcc success
(letcc var (success a)) . b))))
where letcc
is defined as
(define-syntax letcc
(syntax-rules ()
((letcc var body ...)
(call-with-current-continuation
(lambda (var) body ... )))))
Now, while I understand what try
does and how it can be used, I am having trouble to follow the formal definition of it. What exactly is the meaning of the dot in the application of letcc
to success
and (letcc var (success a)) . b
in the lines
(letcc success
(letcc var (success a)) . b)
of try
? Or maybe asked differently: Which part of the definition of try
establishes that try
is evaluated to b
if var
is called in a
?
Edit 1: Sorry, the definition of letcc
was incomplete. Added the missing first line.
Edit 2: The following code can be run in Racket.
(define-syntax letcc
(syntax-rules ()
((letcc var body ...)
(call-with-current-continuation
(lambda (var) body ... )))))
(define-syntax try
(syntax-rules ()
((try var a . b)
(letcc success
(letcc var (success a)) . b))))
(try var (+ 1 1) 4)
; output: 2
(try var (var '(2)) 4)
; output: 4
Syntax rules is pattern matching. A dot indicates the car
and cdr
of a pair just like rest arguments in lambda
/ define
:
(define (my-list . args)
args)
A list is just nested pairs. eg. (1 2 3)
is just fancy way of displaying (1 . (2 . (3 . ())))
.
So (this is random symbols in a list)
will match (try var a . b)
by try
matching this
, is
matches var
, random
matches a
, and (symbols in a list)
matches b
.
When you see the same in the expansion it means the code should splice the match after the dot. Eg (var . b)
with the previous example becomes (is symbols in a list)
. It is similar to having b ...
but cheaper for the system.