Search code examples
syntaxschemeseasoned-schemer

Scheme/"The Seasoned Schemer": Question about the syntax of the definition of "try" function


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

Solution

  • 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.