+ # 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
in Scheme, you have two choices. First, the quick hack:
; we use the symbols 'var and 'lam as tags, and assume
@@ -67,7+70,7 @@ Additionally, the syntax of OCaml and SML is superficially much closer to Haskel
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.
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, see <http://docs.racket-lang.org/guide/define-struct.html>. Also `define-record-type` from srfi-9 and srfi-57; see also <http://docs.racket-lang.org/r6rs-lib-std/r6rs-lib-Z-H-7.html>.)
+ (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:
Here is how the tools from EoPL work. You must begin your file either with `#lang eopl` or with the first two lines below:
@@ -85,8+88,10 @@ Additionally, the syntax of OCaml and SML is superficially much closer to Haskel
-* Scheme has excellent support for working with implicit or "first-class" **continuations**, using either `call/cc` or any of various delimited continuation operators. See <http://docs.racket-lang.org/reference/cont.html?q=shift&q=do#%28part._.Classical_.Control_.Operators%29>.
+* 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):
In Scheme you can use these forms by default (they're equivalent):
@@ -145,7+150,7 @@ We will however try to give some general advice about how to translate between O
* In Haskell, you say a value has a certain type with: `value :: type`. You express the operation of prepending a new `int` to a list of `int`s with `1 : other_numbers`. In OCaml it's the reverse: you say `value : type` and `1 :: other_numbers`.
* In Haskell, you say a value has a certain type with: `value :: type`. You express the operation of prepending a new `int` to a list of `int`s with `1 : other_numbers`. In OCaml it's the reverse: you say `value : type` and `1 :: other_numbers`.
-* In Haskell, type names and constructors both begin with capital letters, and type variables always appear after their constructors, in Curried form. And the primary term for declaring a new type is `data` (short for [[!wikipedia algebraic datatype]]). So we have:
+* In Haskell, type names and constructors both begin with capital letters, and type variables always appear after their constructors, in Curried form. And the primary term for declaring a new type is `data` (short for [[!wikipedia algebraic datatype]]). So we have:
data Either a b = Left a | Right b;
data FooType a b = Foo_constructor1 a b | Foo_constructor2 a b;
data Either a b = Left a | Right b;
data FooType a b = Foo_constructor1 a b | Foo_constructor2 a b;