-#Scheme and OCaml#
-
-* You can [try Scheme in your web browser](http://tryscheme.sourceforge.net/). This is useful if you don't have Racket or another Scheme implementation installed---but don't expect it to have all the bells and whistles of a mature implementation!
-
-* **Type Variants and Pattern Matching** If you want to reproduce this kind of OCaml code:
-
- # type lambda_expression = Var of char | Lam of char * lambda_expression | App of lambda_expression * lambda_expression;;
-
- # let rec free_vars (expr : lambda_expression) : char list =
- match expr with
- | Var label -> [label]
- | Lam (label, body) -> remove label (free_vars body)
- | App (left, right) -> merge (free_vars left) (free_vars right);;
-
- # free_vars (Lam ('x', (App (Var 'x', Var 'y'))));;
- - : char list = ['y']
-
- in Scheme, you have two choices. First, the quick hack:
-
- ; we use the symbols 'var and 'lam as tags, and assume
- ; that an expression will always be a pair of one of these forms:
- ; (cons 'var symbol)
- ; (cons (cons 'lam symbol) expression)
- ; (cons expression expression)
-
- (define (free-vars expr)
- (cond
- [(eq? (car expr) 'var) (list (cdr expr))]
- [(and? (pair? (car expr)) (eq? (car (car expr)) 'lam))
- (remove (cdr (car expr)) (free-vars (cdr expr)))]
- [else (merge (free-vars (car expr)) (free-vars (cdr expr)))]))
-
- Second, you can create real datatypes and pattern-match on them. There are several tools for doing this. I'll describe the `define-datatype` and `cases` forms developed for the book *Essentials of Programming Languages* (EoPL) by Friedman and Wand.
-
- (Alternatives include [the `struct` form in Racket](http://docs.racket-lang.org/guide/define-struct.html). Also `define-record-type` from srfi-9 and srfi-57; see also [the r6rs libs](http://docs.racket-lang.org/r6rs-lib-std/r6rs-lib-Z-H-7.html).)
-
- Here is how the tools from EoPL work. You must begin your file either with `#lang eopl` or with the first two lines below:
-
- #lang racket
- (require eopl/eopl)
-
- (define-datatype lambda-expression lambda-expression?
- (var (label symbol?))
- (lam (label symbol?) (body lambda-expression?))
- (app (left lambda-expression?) (right lambda-expression?)))
-
- (define (free-vars expr)
- (cases lambda-expression expr
- (var (label) (list label))
- (lam (label body) (remove label (free-vars body)))
- (app (left right) (remove-duplicates (append (free-vars left) (free-vars right))))))
-
- (free-vars (lam 'x (app (var 'x) (var 'y))))
- ; evaluates to '(y)
-
-* Scheme has excellent support for working with implicit or "first-class" **continuations**, using either `call/cc` or any of various delimited continuation operators. See [the Racket docs](http://docs.racket-lang.org/reference/cont.html?q=shift&q=do#%28part._.Classical_.Control_.Operators%29).
-
- In Scheme you can use these forms by default (they're equivalent):
-
- (call/cc (lambda (k) ...))
- (let/cc k ...)
-
- If your program declares `(require racket/control)`, you can also use:
-
- (begin ... (reset ... (shift k ...) ...) ...)
-
- (begin ... (prompt ... (control k ...) ...) ...)
-
- (begin ... (prompt ... (abort value) ...) ...)