translating tweaks
[lambda.git] / translating_between_OCaml_Scheme_and_Haskell.mdwn
index 8914902..e76bab4 100644 (file)
@@ -42,14 +42,17 @@ Additionally, the syntax of OCaml and SML is superficially much closer to Haskel
 
 *      **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;;
+               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 =
+               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
@@ -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.
 
-       (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:
 
@@ -85,8 +88,10 @@ Additionally, the syntax of OCaml and SML is superficially much closer to Haskel
                    (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 <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):
 
@@ -145,8 +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, 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 "abstract 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 data type]]). So we have:
 
                data Either a b = Left a | Right b;
                data FooType a b = Foo_constructor1 a b | Foo_constructor2 a b;