\chapter{Sample definitions for derived forms}
\label{derivedformsappendix}

This appendix contains sample definitions for some of the keywords
described in this report in terms of simpler forms:

\subsubsection*{{\tt cond}}
The {\cf cond} keyword (section~\ref{cond}) 
could be defined in terms of {\cf if}, {\cf let} and {\cf
  begin} using {\cf syntax-rules} as follows:

\begin{scheme}
(define-syntax \ide{cond}
  (syntax-rules (else =>)
    ((cond (else result1 result2 ...))
     (begin result1 result2 ...))
    ((cond (test => result))
     (let ((temp test))
       (if temp (result temp))))
    ((cond (test => result) clause1 clause2 ...)
     (let ((temp test))
       (if temp
           (result temp)
           (cond clause1 clause2 ...))))
    ((cond (test)) test)
    ((cond (test) clause1 clause2 ...)
     (let ((temp test))
       (if temp
           temp
           (cond clause1 clause2 ...))))
    ((cond (test result1 result2 ...))
     (if test (begin result1 result2 ...)))
    ((cond (test result1 result2 ...)
           clause1 clause2 ...)
     (if test
         (begin result1 result2 ...)
         (cond clause1 clause2 ...)))))%
\end{scheme}
\subsubsection*{{\tt case}}
The {\cf case} keyword (section~\ref{case}) could be defined in terms of {\cf let}, {\cf cond}, and
{\cf memv} (see library chapter~\extref{lib:listutilities}{List utilities}) using {\cf syntax-rules} as follows:

\begin{scheme}
(define-syntax \ide{case}
  (syntax-rules (else)
    ((case expr0
       ((key ...) res1 res2 ...)
       ...
       (else else-res1 else-res2 ...))
     (let ((tmp expr0))
       (cond
         ((memv tmp '(key ...)) res1 res2 ...)
         ...
         (else else-res1 else-res2 ...))))
    ((case expr0
       ((keya ...) res1a res2a ...)
       ((keyb ...) res1b res2b ...)
       ...)
     (let ((tmp expr0))
       (cond
         ((memv tmp '(keya ...)) res1a res2a ...)
         ((memv tmp '(keyb ...)) res1b res2b ...)
         ...)))))%
\end{scheme}

\subsubsection*{{\tt let*}}

The {\cf let*} keyword (section~\ref{let*})
could be defined in terms of {\cf let}
using {\cf syntax-rules} as follows:

\begin{scheme}
(define-syntax \ide{let*}
  (syntax-rules ()
    ((let* () body1 body2 ...)
     (let () body1 body2 ...))
    ((let* ((name1 expr1) (name2 expr2) ...)
       body1 body2 ...)
     (let ((name1 expr1))
       (let* ((name2 expr2) ...)
         body1 body2 ...)))))%
\end{scheme}

\subsubsection*{{\tt letrec}}
The {\cf letrec} keyword (section~\ref{letrec})
could be defined approximately in terms of {\cf let}
and {\cf set!} using {\cf syntax-rules}, using a helper
to generate the temporary variables
needed to hold the values before the assignments are made,
as follows:

\begin{scheme}
(define-syntax \ide{letrec}
  (syntax-rules ()
    ((letrec () body1 body2 ...)
     (let () body1 body2 ...))
    ((letrec ((var init) ...) body1 body2 ...)
     (letrec-helper
       (var ...)
       ()
       ((var init) ...)
       body1 body2 ...))))

(define-syntax letrec-helper
  (syntax-rules ()
    ((letrec-helper
       ()
       (temp ...)
       ((var init) ...)
       body1 body2 ...)
     (let ((var <undefined>) ...)
       (let ((temp init) ...)
         (set! var temp)
         ...)
       (let () body1 body2 ...)))
    ((letrec-helper
       (x y ...)
       (temp ...)
       ((var init) ...)
       body1 body2 ...)
     (letrec-helper
       (y ...)
       (newtemp temp ...)
       ((var init) ...)
       body1 body2 ...))))%
\end{scheme}

The syntax {\cf <undefined>} represents an expression that
returns something that, when stored in a location, causes an exception
with condition type {\cf\&assertion} to
be raised if an attempt to read from or write to the location occurs before the
assignments generated by the {\cf letrec} transformation take place.
(No such expression is defined in Scheme.)

A simpler definition using {\cf syntax-case} and {\cf
generate-\hp{}temporaries} is given in library
chapter~\extref{lib:syntaxcasechapter}{{\cf syntax-case}}.

\subsubsection*{{\tt letrec*}}

The {\cf letrec*} keyword could be defined approximately in terms of
{\cf let} and {\cf set!}  using {\cf syntax-rules} as follows:

\begin{scheme}
(define-syntax \ide{letrec*}
  (syntax-rules ()
    ((letrec* ((var1 init1) ...) body1 body2 ...)
     (let ((var1 <undefined>) ...)
       (set! var1 init1)
       ...
       (let () body1 body2 ...)))))%
\end{scheme}

The syntax {\cf <undefined>} is as in the definition of {\cf letrec} above.

\subsubsection*{{\tt let-values}}
The following definition of {\cf let-values} (section~\ref{let-values})
using {\cf syntax-rules}
employs a pair of helpers to
create temporary names for the formals.

\begin{scheme}
(define-syntax let-values
  (syntax-rules ()
    ((let-values (binding ...) body1 body2 ...)
     (let-values-helper1
       ()
       (binding ...)
       body1 body2 ...))))

(define-syntax let-values-helper1
  ;; map over the bindings
  (syntax-rules ()
    ((let-values
       ((id temp) ...)
       ()
       body1 body2 ...)
     (let ((id temp) ...) body1 body2 ...))
    ((let-values
       assocs
       ((formals1 expr1) (formals2 expr2) ...)
       body1 body2 ...)
     (let-values-helper2
       formals1
       ()
       expr1
       assocs
       ((formals2 expr2) ...)
       body1 body2 ...))))

(define-syntax let-values-helper2
  ;; create temporaries for the formals
  (syntax-rules ()
    ((let-values-helper2
       ()
       temp-formals
       expr1
       assocs
       bindings
       body1 body2 ...)
     (call-with-values
       (lambda () expr1)
       (lambda temp-formals
         (let-values-helper1
           assocs
           bindings
           body1 body2 ...))))
    ((let-values-helper2
       (first . rest)
       (temp ...)
       expr1
       (assoc ...)
       bindings
       body1 body2 ...)
     (let-values-helper2
       rest
       (temp ... newtemp)
       expr1
       (assoc ... (first newtemp))
       bindings
       body1 body2 ...))
    ((let-values-helper2
       rest-formal
       (temp ...)
       expr1
       (assoc ...)
       bindings
       body1 body2 ...)
     (call-with-values
       (lambda () expr1)
       (lambda (temp ... . newtemp)
         (let-values-helper1
           (assoc ... (rest-formal newtemp))
           bindings
           body1 body2 ...))))))%
\end{scheme}

\subsubsection*{{\tt let*-values}}

The following macro defines {\cf let*-values} in terms of {\cf let}
and {\cf let-values} using {\cf syntax-rules}:

\begin{scheme}
(define-syntax let*-values
  (syntax-rules ()
    ((let*-values () body1 body2 ...)
     (let () body1 body2 ...))
    ((let*-values (binding1 binding2 ...)
       body1 body2 ...)
     (let-values (binding1)
       (let*-values (binding2 ...)
         body1 body2 ...)))))%
\end{scheme}


\subsubsection*{{\tt let}}

The {\cf let} keyword could be defined in terms of {\cf lambda} and {\cf letrec}
using {\cf syntax-rules} as
follows:

\begin{scheme}
(define-syntax \ide{let}
  (syntax-rules ()
    ((let ((name val) ...) body1 body2 ...)
     ((lambda (name ...) body1 body2 ...)
      val ...))
    ((let tag ((name val) ...) body1 body2 ...)
     ((letrec ((tag (lambda (name ...)
                      body1 body2 ...)))
        tag)
      val ...))))%
\end{scheme}


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "r6rs"
%%% End: 
