home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d07xx / d0764.lha / Gambit_Terp / SchemeIntro < prev    next >
Text File  |  1992-11-21  |  31KB  |  1,210 lines

  1. FILE        "Scheme Intro"
  2. IMPLEMENTS    A brief introduction to the Scheme Programming Language
  3.         and R^4RS hygenic macros.
  4. AUTHOR        Ken Dickey
  5. DATE        1992 April  16
  6. LAST UPDATED    1992 October 5
  7.  
  8. ====================================================================
  9.  
  10.  
  11.         The Scheme Programming Language
  12.  
  13.  
  14.  
  15.  
  16. An Alternate World View
  17.  
  18.  
  19. Each programming language presents a particular world view in the
  20. features it allows, supports, and forbids.  This article describes the
  21. world view of the Scheme Programming Language.  This view contains
  22. many elements desired in a modern programming language: multi-paradigm
  23. support, composable, reusable abstractions, ability to create
  24. languages specialized for particular applications, clean separation of
  25. the generic and the implementation specific, and scalability from
  26. stand alone utilities to major software systems. 
  27.  
  28. Scheme started as an experiment in programming language design  
  29. by challanging some fundamental design assumptions.  It is 
  30. currently gaining favor as a first programming language in 
  31. universities and is used in industry by such companies as DEC, 
  32. TI, Tektronix, HP, and Sun.
  33.  
  34.  
  35.  
  36. WHAT IS SCHEME?
  37.  
  38.  
  39. Scheme is a small, exceptionally clean language which is, very 
  40. importantly, fun to use.  The language was designed to have very 
  41. few, regular constructs which compose well to support a variety 
  42. of programming styles including functional, object-oriented, and 
  43. imperative.  The language standard is only about 50 pages, 
  44. including a formal, denotational definition of its semantics.  
  45. Scheme is based on a formal model (the lambda calculus), so there 
  46. are plenty of nice properties for the theoreticians and one can
  47. build knowledgeable code transformation tools reliably.
  48.  
  49. Scheme has lexical scoping, uniform evaluation rules, and uniform 
  50. treatment of data types.  Scheme does not have the concept of a 
  51. pointer, uninitialized variables, specialized looping constructs, 
  52. or explicit storage management.
  53.  
  54. So what does Scheme look like?  Well, it looks a lot like Lisp.  Don't
  55. let this put you off.  We can change how it looks.  What is important
  56. are the concepts behind it and what you can say with it.  So let me
  57. make a few comparisons between Scheme and, say C.  You already know
  58. that Scheme is prefix and C is infix:
  59.  
  60.         Scheme                C 
  61.  
  62.     (+ 2 3 4)            (2 + 3 + 4)
  63.  
  64.     (< low x high)            ((low < x) && (x < high))
  65.  
  66.     (+ (* 2 3) (* 4 5))        ((2 * 3) + (4 * 5))
  67.  
  68.     (f x y)                f(x, y)
  69.  
  70.         (define (sq x) (* x x))        int sq(int x) { return (x * x) }
  71.  
  72.  
  73.  
  74. In Scheme, all data types are equal.  What one can do to one data 
  75. type, one can do to all data types.  This is different from most 
  76. languages which have some data types that can do special things 
  77. and other data types which are specially restricted.  In most 
  78. languages numbers have special rights because they can be used 
  79. without having names (imagine having to name each number before 
  80. using it!).  Functions are specially restricted because they 
  81. cannot be created without a name.  
  82.  
  83.  
  84. In Scheme, unnamed functions are created with the key word 
  85. lambda.
  86.  
  87. (lambda (x) (* x x))        -> a function
  88.  
  89. (define sq (lambda (x) (* x x))
  90.  
  91. (sq 9)                -> 27
  92.  
  93. ((lambda (x) (* x x)) 9)    -> 27
  94.  
  95.  
  96.  
  97. ((if (foo? x) * +) 2 3 4)    -> if (foo? x) is true,
  98.  
  99.                          then (* 2 3 4)
  100.  
  101.                          else (+ 2 3 4)
  102.  
  103.  
  104.  
  105. (define (curried-add x) (lambda (y) (+ x y))
  106.  
  107. (define add3 (curried-add 3)) ;; add3 is a funciton
  108.  
  109. (add3 7)        -> 10
  110.  
  111. ((curried-add 3) 7)    -> 10
  112.  
  113.  
  114.  
  115. Rubrics:  
  116.  
  117. - Variables can hold values of any type.
  118.  
  119. - Names refer to values; names are not required.
  120.  
  121. - An expression is one or more forms between parentheses.
  122.  
  123. - To evaluate an expression, evaluate all the terms first and 
  124. apply the value of the first form to the values of the other 
  125. forms.  A nested expression counts as a form.
  126.  
  127. - A comment starts at a semicolon (;) and goes to the end of the 
  128. line it is on.
  129.  
  130. - When a function is evaluated, it remembers the environment 
  131. where it was evaluated.  {So add3 remembers that X has the value 
  132. 3 when it evaluates ((lambda (y) (+ x y)) 7).}
  133.  
  134. (define (sq x) (* x x)) is just syntactic sugar for
  135.  
  136. (define sq (lambda (x) (* x x))
  137.  
  138.  
  139.  
  140.  
  141.  
  142. There are seven kinds of expressions:
  143.  
  144.   Constant:            'foo #\Z 3 "a string"
  145.  
  146.   Variable reference:    foo joe a-long-name-for-an-identifier +
  147.  
  148.   Procedure creation:    (lambda (z) (* z z z))
  149.  
  150.   Procedure application:    (cube 37)
  151.  
  152.   Conditional:            (if (< x 3) sqrt modulo)
  153.  
  154.   Assignment:            (set! x 5)
  155.  
  156.   Sequence:            (begin (write x) (write y) (newline))
  157.  
  158.  
  159.  
  160. Scheme has the usual assortment of data types:
  161.  
  162.   Characters: #\a #\A #\b #\B #\space #\newline
  163.  
  164.   Strings: "A little string"
  165.  
  166.   Arrays (called vectors): #(1 2 "string" #\x 5)
  167.  
  168.   Lists: (a little (list of) (lists))
  169.  
  170.   Numbers: 47 1/3 2.3 4.3e14 1+3i
  171.  
  172.   Functions (also called procedures)
  173.  
  174.   Booleans: #t #f
  175.  
  176.   Ports (e.g. open files)
  177.  
  178.   Symbols: this-is-a-symbol foo a32 c$23*4&7+3-is-a-symbol-too!
  179.  
  180.  
  181.  
  182. Rubrics:  
  183.  
  184. - A vector's contents can be any data objects. 
  185.  
  186. - Symbols may include the characters + - . * / < = > ! ? : $ % _ 
  187. & ~ and ^.   
  188.  
  189. - Symbols are case insensitive. 
  190.  
  191. - Symbols are used for identifiers, so identifiers (variable 
  192. names) are case insensitive.  
  193.  
  194. - By convention predicates end in a question mark {e.g. string?} 
  195. and side effecting procedures end in an exclimation mark {e.g. 
  196. set!}.
  197.  
  198.  
  199. Numbers are especially interesting in that an integer is a 
  200. rational is a real is a complex.  There is no classification of 
  201. numbers based on their storage class {e.g. fixed, float, bignum, 
  202. ...} but on whether or not they are exact.
  203.  
  204.   (exact? 3)        -> #t
  205.  
  206.   (exact? 1/3)        -> #t
  207.  
  208.   (exact? 2.3##)    -> #f
  209.  
  210.   (+ 2/3 1/2 5/6)    -> 2
  211.  
  212.   (integer? 2)        -> #t
  213.  
  214.   (integer? 3/7)    -> #f
  215.  
  216.   (real? 2)        -> #t
  217.  
  218.  
  219.  
  220.  
  221.  
  222. The ZEN of SCHEME
  223.  
  224.  
  225.  
  226. One of the joys of Scheme which initially confuses some people is 
  227. the lack of inhibition.  Scheme is very expressive, which means 
  228. that one can say "the same thing" in many ways.  In Scheme one 
  229. has the freedom--and the responsibility--of saying exactly what 
  230. is desired.  We are all used to working around certain language 
  231. features to get something done.  Scheme gets in the way very 
  232. little.
  233.  
  234. As a warming up exercise, let's build a pair.  A pair consists of 
  235. 2 elements obtained by the access routines FIRST and SECOND.  The 
  236. constructor is called PAIR.  The relations to be maintained are 
  237. (first (pair 1 2)) -> 1 ; (second (pair 1 2)) -> 2.  For those of you 
  238. who know LISP, this is not much to get worked up over.  But how 
  239. many ways can we implement the trio: pair, first, second?  There 
  240. is a virtually endless variety.
  241.  
  242.  
  243. ;; vector
  244.  
  245. (define (PAIR a b) (vector a b)) ;; or just: (define PAIR vector)
  246.  
  247. (define (FIRST  aPair) (vector-ref aPair 0))
  248.  
  249. (define (SECOND aPair) (vector-ref aPair 1))
  250.  
  251. ------
  252.  
  253. ;; selector function
  254.  
  255. (define (PAIR a b) (lambda (bool) (if bool a b)))
  256.  
  257. (define (FIRST  aPair) (aPair #t))
  258.  
  259. (define (SECOND aPair) (aPair #f))
  260.  
  261. ------
  262.  
  263. ;; message passing
  264.  
  265. (define (PAIR (a b)
  266.  
  267.   (lambda (msg)
  268.  
  269.      (case msg       ;; we'll implement CASE below
  270.  
  271.         ((first)  a) ;; when the message is the symbol first, return a
  272.  
  273.         ((second) b)
  274.  
  275. ) )  )
  276.  
  277. (define (FIRST  aPair) (aPair 'first))
  278.  
  279. (define (SECOND aPair) (aPair 'second))
  280.  
  281. ------
  282.  
  283. ;; alias
  284.  
  285. (define PAIR   cons)
  286.  
  287. (define FIRST  car)
  288.  
  289. (define SECOND cdr)
  290.  
  291. ------
  292.  
  293. ;; pure functions
  294.  
  295. (define (PAIR a b) (lambda (proc) (proc a b)))
  296.  
  297. (define (FIRST  aPair) (aPair (lambda (x y) x)))
  298.  
  299. (define (SECOND aPair) (aPair (lambda (x y) y)))
  300.  
  301.  
  302.  
  303. The moral of the above is not to assume anything about the 
  304. implementation of interfaces--even simple ones.
  305.  
  306.  
  307.  
  308.  
  309. Now that we are warmed up, let's take a look at ye ol' factorial 
  310. function on integers.
  311.  
  312.  
  313. First, the recursive definition:
  314.  
  315.     (define (fact n)
  316.       (if (< n 2)
  317.           1
  318.           (* n (fact (sub1 n))  ;; (define (sub1 n) (- n 1))
  319.     )
  320.  
  321.  
  322. When I first learned about recursive definitions like the one 
  323. above, the hard thing to get used to was the how the hidden state 
  324. kept on the stack.  A transformation of the above code makes the 
  325. stack visible.
  326.  
  327.  
  328. ;; the identity function just returns its argument
  329.  
  330. (define (identity value) value) 
  331.  
  332.  
  333.  
  334. ;; keep invocation of fact the same, but do something different
  335.  
  336. (define (fact n) (cfact n identity))
  337.  
  338.  
  339.  
  340. ;; the transformed recursive factorial
  341.  
  342. (define (cfact n k)
  343.    (if (< n 2)
  344.       (k 1)
  345.       (cfact (sub1 n) 
  346.               (lambda (result) (k (* n result))))
  347. )  )
  348.  
  349.  
  350.  
  351. Cfact is the continuation-passing version of fact.  The basic 
  352. idea here is that instead of returning a result each function 
  353. takes an extra argument, the continuation, which is invoked with 
  354. the result of the function.
  355.  
  356.  
  357.  
  358. Let's look at what happens for (fact 3).
  359.  
  360. (fact 3) is (cfact 3 identity)
  361.  
  362.  
  363. (cfact 3 identity) is 
  364.  
  365.   (cfact 2 
  366.          (lambda (result) (identity (* 3 result)))) ;; k'
  367.  
  368.  
  369.  
  370.  
  371.  
  372. which is
  373.  
  374.   (cfact 1
  375.          (lambda (result^) ;; k''
  376.         ((lambda (result) (identity (* 3 result))) ; fun k'
  377.          (* 2 result^)) ; argument to k'
  378.  
  379. ->
  380.  
  381.   ((lambda (result^) ;; k''
  382.     ((lambda (result) (identity (* 3 result)))(* 2 result^)))
  383.     1)
  384.  
  385. ->
  386.  
  387.    ((lambda (result) (identity (* 3 result))) (* 2 1))
  388.  
  389. ->
  390.  
  391.   (identity (* 3 (* 2 1)))
  392.  
  393. ->
  394.  
  395.   (* 3 (* 2 1))
  396.  
  397. or {as we knew all along}
  398.  
  399.   6
  400.  
  401.  
  402.  
  403. The point of this is not that we can take something simple and 
  404. make it look bizarre.  So why did I do it?  The point is that we 
  405. can take control which is typically hidden on the stack at run 
  406. time and study and manipulate it as source code.  This lets us do 
  407. some interesting things.  For example, we can ignore the 
  408. continuation passed in and use another one.  If we are writing a 
  409. game or an AI search routine or a mathematical routine which 
  410. converges on a result, we can monitor our progress.  If our 
  411. progress is slow, we can save our continuation--"where we are 
  412. now"--and try a different approach.  If the newer approach is 
  413. even worse, we can go back to our saved continuation and try 
  414. again from there.  We can of course save our attempt at doing 
  415. better to try again just in case it really was better...
  416.  
  417. So continuation passing can let us build some pretty interesting 
  418. control structures.  Let's take another look at the simple 
  419. function, fact.  When we look at (fact 4), (fact 5), and so on, 
  420. we see a common pattern.  Each call just stacks up a 
  421. multiplication.  Since we can see this, we can eliminate the 
  422. stack and do the multiplication directly by introducing an 
  423. accumulator.  We take care of initializing the accumulator by 
  424. noting that anything times one is the same as itself {i.e. the 
  425. multiplicitive identity: x * 1 = x}.
  426.  
  427.  
  428.  
  429. (define (cfact n k)
  430.   ;; lexical scope means we can nest functions
  431.   (define (ifact x acc k^)  
  432.    (if (< x 2)
  433.       (k^ acc)
  434.       (ifact (sub1 x) (* x acc) k^) 
  435.    ) )
  436.  
  437.    (ifact n 1 k)
  438.  )
  439.  
  440.  
  441.  
  442. Now this looks a bit strange too.  But there is an interesting 
  443. detail here.  We did not have to build any new continuations!  
  444. The continuation k^ which is given the final result is exactly 
  445. the original continuation k.  This means that the call of ifact, 
  446. which looks recursive, is really iterative.  When it "calls 
  447. itself" it does not add to the stack.  The "recursive" call to 
  448. ifact is just a goto.
  449.  
  450. Scheme requires no special looping constructs. Any function which 
  451. calls itself in the "tail" position {i.e. as the last thing to be 
  452. done in the function} is just a loop.  Most procedural languages 
  453. do too much work.  They "push a return address" even when they 
  454. don't have to.  Scheme doen't.  In Scheme, function calls can be 
  455. thought of as gotos which can pass parameters--one of which may 
  456. be a "return address".  
  457.  
  458. This means that we can simplify cfact to:
  459.  
  460. (define (cfact n k)
  461.  
  462.   (define (ifact n acc)
  463.      (if (< n 2)
  464.          (k acc)
  465.          (ifact (sub1 n) (* n acc))
  466.   )
  467.  
  468.   (ifact n 1)
  469. )
  470.  
  471.  
  472.  
  473. Taking this a step further, we can redefine fact to call ifact 
  474. directly:
  475.  
  476. (define (fact n) (ifact n acc))
  477.  
  478. (define (ifact n acc)
  479.    (if (< n 2) acc (ifact (sub1 n) (* n acc)) )
  480.  
  481.  
  482.  
  483. Or taking advantage of Scheme's lexical scoping:
  484.  
  485. (define (fact n)
  486.  
  487.   (define (ifact x acc)
  488.      (if (< x 2)
  489.           acc
  490.          (ifact (sub1 x) (* x acc))
  491.    ) )
  492.  
  493.    (ifact n 1)
  494. )
  495.  
  496.  
  497.  
  498. Now we have transformed a recursive function into an iterative 
  499. one.  This can be done in a formal way, proving every code 
  500. transformation.  But a nice feature of Scheme is that such 
  501. transformations can be seen and used directly.  Correct programs 
  502. can be written which are simple but perhaps run slowly or are not 
  503. very space efficient and then reliably transformed into programs 
  504. which are smaller and run much faster--and are also correct.  
  505. Code transformations become second nature to experienced Scheme 
  506. programmers.  When a function similar to the recursive function 
  507. fact is seen, it tends to get written down in the iterative form.
  508.  
  509.  
  510. Scheme has several important advantages.  Its elegantly simple,
  511. regular structure and trivial syntax avoids "special case" confusion.
  512. Its expressiveness means that one spends little time trying to work
  513. around the language--it lets users concentrate on *what* they want to
  514. say rather than on *how* to say it.  Its support of a variety of
  515. styles (including OO, which has not been emphasized here) allows users
  516. to better match their solution style to the style of the problems to
  517. be solved.  Its formal underpinnings make reasoning about programs
  518. much easier.  Its abstractive power makes it easy to separate system
  519. specific optimizations from reusable code.   Its composability makes
  520. it easy to construct systems from well-tested components.
  521.  
  522. If you want to write complex, correct programs quickly, scheme for
  523. success! 
  524.  
  525.  
  526.  
  527.  
  528. ====================================================================
  529.  
  530.  
  531.         Syntax Extension: MACROS
  532.  
  533.  
  534. Just as functions are semantic abstractions over operations, 
  535. macros are textual abstractions over syntax.  Managing complex 
  536. software systems frequently requires designing specialized 
  537. "languages" to focus on areas of interest and hide superfluous 
  538. details.  Macros have the advantage of expanding the syntax of 
  539. the base language without making the native compiler more complex 
  540. or introducing runtime penalties.
  541.  
  542. Macros have always been a source of great power and confusion.  
  543. Scheme has perhaps the most sophisticated macro system of any 
  544. programming language in wide use today.  How has macro technology 
  545. advanced?  What are the problems which have been solved?
  546.  
  547.  
  548.  
  549. PROBLEMS WITH MACROS
  550.  
  551.  
  552. Macros are frequently considered an advanced topic.  Non-trivial 
  553. macros are notoriously hard to get right.  Because macros can be 
  554. used to extend the base language, doing macro design can also be 
  555. viewed as doing language design.
  556.  
  557. In the early days, macros were based on simple text substitution.  
  558. A problem with text substitution is that tokenization rules of 
  559. the programming language are not respected.  Indeed the 
  560. tokenization rules of the preprocessor may not match the rules of 
  561. the target language.  For example, using the m4 preprocessor:
  562.  
  563.     define( glerph, `"ugly' )
  564.  
  565. the token glerph followed by the non-token glop"
  566.  
  567.     glerph glop" 
  568.  
  569. becomes the string token
  570.  
  571.     "ugly glop"
  572.  
  573.  
  574.  
  575. In addition to tokenization confusion, there are problems where 
  576. macro expansion does not respect the structure of source language 
  577. expressions.  For example, a well known problem with the C 
  578. preprocessor:
  579.  
  580.     #define mean( a, b )  a + b / 2
  581.  
  582.     mean( x+y, x*y )
  583.  
  584. becomes
  585.  
  586.     x+y+x*y/2
  587.  
  588. and is interpreted by the compiler as
  589.  
  590.     x + y + ((x * y) / 2)
  591.  
  592.  
  593.  
  594. There are frequently problems relating to the accidental 
  595. collision of introduced names.  Even obscure names may collide 
  596. where there are multiple macro writers or recursive macros.  
  597. Again, using the C preprocessor:
  598.  
  599.     #define swap( a, b )  { int temp; temp = a; a = b; b = temp }
  600.  
  601. ...
  602.  
  603.     swap( temp, x )
  604.  
  605. becomes
  606.  
  607.     {int temp; temp = temp; temp = b; b = temp}
  608.  
  609.  
  610.  
  611. Free names may collide with those used locally:
  612.  
  613.     #define clear(addr,len) fill(addr,len,0)
  614.  
  615. ...
  616.  
  617.     {int fill = 0x5a5aa5a5L;
  618.  
  619. ...
  620.  
  621.       clear(mem_ptr, mem_size); /* local fill shadows hidden global fill */
  622.  
  623.  
  624. In general, macro systems have done poorly on name conflicts 
  625. where lexical scoping and recursion are involved.
  626.  
  627. So what do we want out of a macro system?  We want respect for 
  628. the syntax, expressions, and name bindings.  We want error 
  629. checking.  We want a convenient notation for specifying syntactic 
  630. transcriptions.  And of course we want this in linear processing 
  631. time.
  632.  
  633.  
  634.  
  635.  
  636.  
  637. SOME SOLUTIONS
  638.  
  639.  
  640.  
  641. One thing to notice is that as macro systems have become more 
  642. sophisticated, they have moved closer to the semantic analysis 
  643. phase of the compiler.  LISP systems achieved respect for target 
  644. language syntax by doing macro transformations on parse trees 
  645. rather than source text.  Scheme's system takes things a step 
  646. further by respecting lexical scoping and name bindings.  In 
  647. addition, the standard high-level part of Scheme's macro system 
  648. specifies syntactic rewrite rules in a pattern directed fashon 
  649. which includes error checks.
  650.  
  651. To contrast Scheme's macro system with those of older LISPs, here 
  652. is a brief historical view of the LET macro.  LET is a construct 
  653. for introducing new name bindings.  It has the form:
  654.  
  655.   (let ( (<name1> <init1>) ... )
  656.         <exp1> <exp2> ... )
  657.  
  658.  
  659. The semantics of LET is to evaluate the expressions <exp?> in an 
  660. environment extended by the names <name?> which have initial 
  661. values obtained by evaluating the expressions <init?>.  An 
  662. example is: (let ( (a 1) (b 2) ) (+ a b) ), which binds the value 1 to 
  663. a, 2 to b and then evaluates the expression (+ a b).  LET is 
  664. syntactic sugar for lambda binding:
  665.  
  666.    ( (lambda (<name1> ...) <exp1> <exp2> ...) <init1> ... )
  667.  
  668.  
  669. So (let ( (a 1) (b 2) ) (+ a b) ) rewrites to 
  670.  
  671.    ( (lambda (a b) (+ a b)) 1 2 )
  672.  
  673.  
  674.  
  675. Early LISP systems operated directly on the list structures of 
  676. the parsed source expression using low-level operations:
  677.  
  678.  
  679.   (macro LET
  680.      (lambda (form)
  681.         (cons (cons 'lambda
  682.                  (cons (map car (cadr form))
  683.                        (cddr form)))
  684.         (map cadr (cadr form)))))
  685.  
  686.  
  687. Later, arguments and "backquotes" were added, making things much 
  688. more readable, but without error checking.  The backquote (`) 
  689. indicates an "almost constant" list expression, where comma (,) 
  690. or comma-splice (,@) are used to force evaluation of a 
  691. subexpression.  The comma replaces the evaluated expression 
  692. directly, where comma-splice splices it into the list.
  693.  
  694.  
  695. So `(lambda ,(cdr (cons 'a 'b)) ,@(cdr (cons 'a 'b)))
  696.  
  697. becomes (lambda (b) b) .
  698.  
  699.  
  700.  
  701. Here is LET with argument binding and backquote:
  702.  
  703.   (define-syntax (LET def-list . expressions)
  704.      `((lambda ,(map car def-list) ,@expressions)
  705.          ,@(map cadr def-list)))
  706.  
  707.  
  708. And here is the Scheme version using pattern maching with error 
  709. checks:
  710.  
  711.   (define-syntax LET
  712.       (syntax-rules ()
  713.         ( (let ( (<var1> <init1>) ...) <exp1> <exp2> ...)       ; before
  714.           ; rewrites to
  715.           ((lambda (<var1> ...) <exp1> <exp2> ...) <init1> ...) ; after
  716.       ) )
  717.   )
  718.  
  719.  
  720.  
  721. This next example demonstrates both macro names shadowing local 
  722. variables and locals shadowing macros.  The outer binding of CAR 
  723. is to a function which returns the first element of a list.
  724.  
  725.  
  726.  
  727. ;; from "Macros That Work"
  728.  
  729.  
  730. (let-syntax ( (first  (syntax-rules () ((first ?x)  (car ?x))))
  731.               (second (syntax-rules () ((second ?x) (car (cdr ?x)))))
  732.             )
  733.  
  734.   (let ( (car "Packard") )
  735.  
  736.     (let-syntax ( (classic (syntax-rules () ((classic) car))) )
  737.  
  738.       (let ( (car "Matchbox") )
  739.  
  740.         (let-syntax ( (affordable (syntax-rules () ((affordable) car))) )
  741.  
  742.         (let ( (cars (list (classic) (affordable))) )
  743.  
  744.           (list (second cars) (first cars)) ; result
  745. ) ) ) ) ) )
  746.  
  747.  
  748. The above evaluates to:  ("Matchbox" "Packard")
  749.  
  750.  
  751.  
  752.  
  753.  
  754. PRACTICUM: extending core Scheme to standard scheme
  755.  
  756.  
  757. Scheme can remain such a small language because one can extend 
  758. the syntax of the language without making the compiler more 
  759. complex.  This allows the compiler to know a great deal about the 
  760. few (7) basic forms.  Most compiler optimizations then fall out 
  761. as general rather than special cases.
  762.  
  763. The following syntax definitions from the current Scheme standard 
  764. are directly (and simply) implemented.
  765.  
  766.  
  767. Form: (or <exp> ...)
  768.  
  769. Example: (or (= divisor 0) (/ number divisor))
  770.  
  771. Semantics:  OR evaluates the expressions from left to right.  The 
  772. value of the first true (not #f) expression is returned.  Any 
  773. remaining expressions are not evalusted.
  774.  
  775.  
  776. (define-syntax OR
  777.    (syntax-rules ()
  778.       ((or) ;=>
  779.        #f
  780.       )
  781.       ((or <test>) ;=>
  782.        <test>
  783.       )
  784.       ((or <test1> <test2> ...) ;=>
  785.        (let ( (temp <test1>) )
  786.      (if temp temp (or <test2> ...))
  787.       ) )
  788. )  )
  789.  
  790.  
  791.  
  792.  
  793. Form: (and <exp> ...)
  794.  
  795. Example: (and (input-port? p) (read p))
  796.  
  797. Semantics:  AND evaluates the expressions from left to right.  
  798. The value of the first false expression is returned.  Any 
  799. remaining expressions are not evalusted.
  800.  
  801.  
  802. (define-syntax AND
  803.    (syntax-rules ()
  804.       ((and) ;=>
  805.        #t
  806.       )
  807.       ((and <test>) ;=>
  808.        <test>
  809.       )
  810.       ((and <test1> <test2> ...) ;=>
  811.      (if <test1> (and <test2> ...) #f)
  812.       ))      
  813. )   )
  814.  
  815.  
  816.  
  817.  
  818. Forms: (let ( (<name> <value>) ...) <exp1> <exp2> ...)
  819.        (let <recur> ( (<name> <value>) ...) <exp1> <exp2> ...)
  820.  
  821. Examples:
  822.  
  823.       (define A 37)
  824.  
  825.       (let ( (a 2) (b (+ a 5)) ) (* a b)) ;=> 84
  826.  
  827.       (let loop ( (count N) (accum 0) )
  828.            (if (< n 2) 
  829.                accum 
  830.                (loop (- count 1) (* count accum))
  831.  
  832. Semantics: LET evaluates the <init>s in the enclosing environment 
  833. in some unspecified order and then extends the environment by 
  834. binding the values to the <name>s and evaluates the expressions 
  835. from left to right, returning the value of the last expression as 
  836. the value of the LET.  LET can be thought of as a "parallel 
  837. assignment".  Note that the value of B in the first example 
  838. depends on the value of A in the outer environment.
  839.  
  840. The second form is known as NAMED LET and allows recursion within 
  841. the let form.  For the example above, the call to LOOP acts as a 
  842. goto which rebinds the <name>s to fresh values and "starts over 
  843. at the top of the loop".  Note that this is a functional 
  844. construct: there are no unbound variables introduced and no 
  845. assignment is used.
  846.  
  847.  
  848. (define-syntax LET
  849.  
  850.    (syntax-rules ()
  851.  
  852.       ((let ( (<var1> <init1>) ...) <exp1> <exp2> ...)
  853.        ;=>
  854.        ((lambda (<var1> ...) <exp1> <exp2> ...) <init1> ...)
  855.       )
  856.  
  857.       ((let <name> ( (<var1> <init1>) ...) <exp1> <exp2> ...)
  858.        ;=>
  859.        ((letrec ( (<name>
  860.                    (lambda (<var1> ...) <exp1> <exp2> ...))
  861.                 )
  862.              <name>)
  863.         <init1> ...)
  864.       )
  865. )  )
  866.  
  867.  
  868.  
  869.  
  870.  
  871. Form: (LET* ( (<name> <value>) ...) <exp1> <exp2> ...)
  872.  
  873. Example: 
  874.  
  875.       (define A 37)
  876.       (let ( (a 2) (b (+ a 5)) ) (* a b)) ;=> 14
  877.  
  878. Semantics: Like un-named LET except that the <value> expressions 
  879. are evaluated sequentially and each "sees" the value of the 
  880. previous name bindings.
  881.  
  882.  
  883. (define-syntax LET*
  884.  
  885.    (syntax-rules ()
  886.  
  887.       ((let* () <exp1> <exp2> ...) ;=>
  888.        (let () <exp1> <exp2> ...)
  889.       )
  890.  
  891.       ((let* ( (var1> <init1>) (<var2> <init2>) ... )
  892.                <exp1> <exp2> ...)
  893.        ;=>
  894.        (let ( (<var1> <init1>) )
  895.           (let* ( (<var2> <init2>) ... )
  896.            <exp1> <exp2> ...))
  897.       )
  898. )  )
  899.  
  900.  
  901.  
  902.  
  903. Form: (LETREC ( (<name> <init>) ...) <exp1> <exp2> ...)
  904.  
  905. Example:
  906.  
  907.       (letrec ( (EVEN? 
  908.                   (lambda (n)
  909.                     (if (zero? n) #t (odd? (sub1 n)))))
  910.  
  911.                 (ODD?
  912.               (lambda (n)
  913.                     (if (zero? n) #f (even? (sub1 n)))))
  914.               )
  915.  
  916.          (even? 14)) ;;=> #t
  917.  
  918. Semantics: Mutually recursive form of let.  All name bindings are 
  919. visible to all <init>s.  Because the order of evaluation of the 
  920. <init>s is unspecified, it must be possible to evaluate each init 
  921. without refering to the *value* of any <name>.  Note that if the 
  922. values are all lambda expressions, this condition is always 
  923. satisfied.
  924.  
  925.  
  926.  
  927. (define-syntax LETREC
  928.  
  929.    (syntax-rules ()
  930.  
  931.       ((letrec ( (<var1> <init1>) ... )
  932.                <exp1> <exp2> ...)
  933.        ;=>
  934.        (let ( (<var1> #f) ... )
  935.          (set! <var1> <init1>) ...
  936.          <exp1> <exp2> ...)
  937.       ))
  938. )  )
  939.  
  940.  
  941.  
  942.  
  943. Forms: (cond (<test> <expr> ...) ... )
  944.        (cond (<test> <expr> ...) ... (else <expr2> ...))
  945.  
  946. Examples: (cond ((< x 0) 'negative)
  947.                 ((> x 0) 'positive)
  948.                 (else 'neither))
  949.  
  950.           (cond ((assq key alist) => cdr) 
  951.                 (else search-failure-value))
  952.  
  953. Semantics: Each <test> expression is evaluated in turn.  The 
  954. first <test> which evaluates to true causes the <expr>s to be 
  955. evaluated.  The value of the last <expr> is returned in this 
  956. case, or the value of <text> if there are no <expr>s.  If no 
  957. <test> is true, the <expr2>s of the else clause are evaluated and 
  958. the value of the last <expr2> is the value of the COND 
  959. expression.  If not <test> is true and there is no else clause, 
  960. the result is unspecified.  If a <test> is true and followed by 
  961. '=> then the <exp> following must evaluate to a procedure of one 
  962. argument and the procedure is called with the value of the <test> 
  963. expression as an argument.
  964.  
  965.  
  966.  
  967. (define-syntax COND
  968.  
  969.    (syntax-rules ( else => )  ;; 'else and '=> must match exactly
  970.  
  971.       ((cond)  ;=>
  972.     #f
  973.       )
  974.  
  975.       ((cond (else <exp1> <exp2> ...)) 
  976.        (begin <exp1> <exp2> ...)
  977.       )
  978.  
  979.       ((cond (<test> => <recipient>) <clause> ...)
  980.        ;=>
  981.        (let ( (result <test>) )
  982.           (if result
  983.               (<recipient> result)
  984.               (cond <clause> ...))
  985.       ))
  986.  
  987.       ((cond (<test>) <clause> ...)
  988.        (or <test> (cond <clause> ...))
  989.       )
  990.  
  991.       ((cond (<test> <exp1> <exp2> ...) <clause> ...)
  992.        (if <test> (begin <exp1> <exp2> ...) (cond <clause> ...))
  993.       )
  994. )  )
  995.  
  996.  
  997.  
  998. Form: (case <key> ((<datum> ...) <exp1> <exp2> ...) ...
  999.                   (else <exp3> <exp4> ...))
  1000.  
  1001. Example: (case (peak-char (current-input-port))
  1002.                ((#\h #\?) (print-help-text))
  1003.                ((#\space #\newline) (keep-looking))
  1004.                (else (read-command)))
  1005.  
  1006. Semantics: The <key> expression is evaluated and compared in turn 
  1007. to each <datum>.  If it is equivalent (eqv?), then the <exp>s of 
  1008. the first clause containing the datum are evaluated and the value 
  1009. of the last one is returned as the value of the CASE expression.  
  1010. If no match is found, then the else expression(s) are evaluated 
  1011. and the last value returned, otherwise the value of the CASE is 
  1012. unspecified.
  1013.  
  1014.  
  1015.  
  1016. (define-syntax CASE
  1017.  
  1018.    (syntax-rules ( else )
  1019.  
  1020.       ((case <key>)
  1021.     <key>
  1022.       )
  1023.  
  1024.       ((case <key> (else <exp1> <exp2> ...))
  1025.        (begin <key> <exp1> <exp2> ...)
  1026.       )
  1027.  
  1028.       ((case <key> ((<datum> ...) <exp1> <exp2> ...) <clause> ...)
  1029.        ;=>
  1030.        (let ( (key <key>) )
  1031.           (if (memv key '(<datum> ...))
  1032.               (begin <exp1> <exp2> ...)
  1033.               (case key <clause> ...))
  1034.       ))
  1035. )  )
  1036.  
  1037.  
  1038.  
  1039.  
  1040. PROBLEMS WHICH REMAIN: 
  1041.  
  1042. There are some problems of which macro authors must still beware.
  1043.  
  1044.  
  1045.  
  1046.   SIDE EFFECTS
  1047.  
  1048. Macros can be written is such a way that they duplicate code with side
  1049. effects.  For example if a function call which increments a counter is
  1050. duplicated 3 times, what looks like a single call in the source text
  1051. would end up incrementing the counter 3 times rather than once.  So
  1052. macro authors should be careful not to specify transformations which
  1053. duplicate code. 
  1054.  
  1055.  
  1056.  
  1057.   INTRODUCED NAMES
  1058.  
  1059. As the R^4RS Macro System is hygenic, there is no way to introduce new
  1060. names.   An example of wanting to introduce names is to define a
  1061. record syntax which creates definitions for record field accessors and
  1062. setters.  One might like:
  1063.   
  1064.   (define-record-type ship (speed latitude longitude))
  1065.  
  1066. to define the creator funciton MAKE-SHIP, the accessors SHIP-SPEED,
  1067. SHIP-LATITUDE, and SHIP-LONGITUDE, and the setters SET-SHIP-SPEED!,
  1068. SET-SHIP-LATITUDE!, and SET-SHIP-LONGITUDE!.
  1069.  
  1070. Currently there are several proposed low-level macro systems which are
  1071. compatable with the R^4RS high-level macro system and which allow
  1072. introduced names.
  1073.  
  1074.  
  1075.  
  1076.   MACROS LOOK LIKE FUNCTIONS BUT ARE NOT
  1077.  
  1078.  
  1079. Macros are transformations of source syntax and not functions.  This
  1080. means that they are not data structures.  They cannot be passed as
  1081. parameters, stored in data structures, or returned as results.  Since
  1082. macro uses look like function calls, there can be some confusion.
  1083.  
  1084. For example there is a function in Scheme called APPLY which takes a
  1085. procedure and a list of arguments and applies the procedure to the
  1086. arguments: 
  1087.    (apply + '(2 3 21 1))    -> 27
  1088.  
  1089. If one tries to evaluate:
  1090.    (apply or '(this that the-other))
  1091.  
  1092. One will get an error stating that OR is not defined.  This is true.
  1093. OR is not a procedure.  It only exists as a form:
  1094.   (or this that the-other)
  1095.   =>
  1096.    (let ( (<temp1> this) )
  1097.      (if <temp1>
  1098.      <temp1>
  1099.      (let ( (<temp2> that) )
  1100.        (if <temp2> <temp2> the-other))
  1101.    ) )
  1102.  
  1103. where <temp1> and <temp2> are names guarrenteed not to match any other
  1104. names in the program.
  1105.  
  1106. On the other hand, OR cannot be written as a function because all
  1107. arguments of a function are evaluated before the function is applied. 
  1108.  
  1109.  
  1110.  
  1111. IN CLOSING
  1112.  
  1113. Macros allow one to extend the syntax of a programming language.
  1114. Despite the problems which remain, Scheme's high-level macro system
  1115. allows one to write robust macros easily and precisely.
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122. =============
  1123.  
  1124. LOOKING FURTHER
  1125.  
  1126.  
  1127. W. Clinger & J. Rees: "Macros That Work", Proceedings of the 
  1128. Eighteenth Annual ACM SIGACT-SIGPLAN Symposioum on Principles of 
  1129. Programming Languages (a.k.a. POPL 18), January 1991; Also 
  1130. published as Department of Computer and Information Science 
  1131. Technical Report CIS-TR 90-17 by the University of Oregon.
  1132.  
  1133. A. Bawden & J. Rees: "Syntactic Closures", 1988 ACM Conference on 
  1134. Lisp and Functional Programming [ACM #552880].
  1135.  
  1136. E. Kholbecker, D. Friedman, M. Felleisen, & B. Duba: "Hygenic 
  1137. Macro Expansion", 1986 ACM Conference on Lisp and Functional 
  1138. Programming [ACM #552860].
  1139.  
  1140. E. Kohlbecker: Syntactic Extensions in the Programming Language 
  1141. LISP, Technical Report number 199, Indiana University CS 
  1142. Department, 1986.
  1143.  
  1144.  
  1145. =======================================================================
  1146.  
  1147. BOOKS ON SCHEME
  1148.  
  1149.  
  1150. G. Springer and D. P. Friedman,  Scheme and the Art of Programming ,
  1151. MIT Press and McGraw-Hill, 1989, ISBN 0-262-19288-8.
  1152.  
  1153.  
  1154. H. Abelson, G. J. Sussman and J. Sussman,  Structure and
  1155. Interpretation of Computer Programs, MIT Press, Cambridge, Mass.,
  1156. 1985, ISBN 0-262-01077-1.
  1157.  
  1158.  
  1159. Eisenberg,  Programming in Scheme, MIT Press, 1988, ISBN 0-262-55018-0.
  1160.  
  1161.  
  1162. Eisenberg, Hartheimer, Clinger, & Abelson,  Programming in MacScheme,
  1163. MIT Press, 1990, ISBN 0-262-55018-0
  1164.  
  1165.  
  1166. Lightship, MacScheme, MIT Press, 1990, ISBN 0-262-62077-4
  1167.  
  1168.  
  1169. R. Kent Dybvig,  The Scheme Programming Language, Prentice Hall,
  1170. 1987, ISBN 0-13-791864-X.
  1171.  
  1172.  
  1173.  
  1174. =====
  1175.  
  1176. STANDARDS:
  1177.  
  1178.  
  1179.  
  1180. IEEE Standard 1178-1990. "IEEE Standard for the Scheme Programming
  1181. Language", IEEE, New York, 1991, ISBN 1-55937-125-0 [1-800-678-IEEE:
  1182. order # SH14209].
  1183.  
  1184.  
  1185. W. Clinger and J. Rees, eds., "Revised^4 Report on the Algorithmic
  1186. Language Scheme", ACM LISP Pointers IV, 3 (July-September 1991).
  1187.  
  1188.  
  1189. J. A. Rees and W. Clinger, eds., "Revised^3 Report on the Algorithmic
  1190. Language Scheme", ACM Sigplan Notices 21, 12 (December 1986).
  1191.  
  1192.  
  1193.  
  1194.  
  1195. ======
  1196.  
  1197. IMPLEMENTATIONS: (partial list)
  1198.  
  1199.  
  1200.  
  1201. Chez Scheme    Skim        MacScheme        XScheme
  1202. PC Scheme    Scm        MIT Scheme        Fool's Lisp
  1203. Scheme->C    T        UMB Scheme         ELK Scheme
  1204. Scheme86    Gambit        Scheme48        Vincenns Scheme
  1205.  
  1206.  
  1207.  
  1208.             --- E O F ---
  1209.  
  1210.