add content from 2010
[lambda.git] / rosetta2.mdwn
index 0c1bd0b..298bda1 100644 (file)
@@ -1,28 +1,9 @@
-## More detailed differences between Scheme, OCaml, and Haskell ##
+# More detailed differences between Scheme, OCaml, and Haskell #
 
-Here is comparison of the syntax for declaring types in Haskell and OCaml:
-
-    -- Haskell
-    data Pretty a b = Lovely a | Cute b ClothingModule.ButtonType
-    newtype Pretty a b = Pretty a b Int
-    newtype Pretty a b = Pretty { unPretty a }
-    type Pretty a b = (a, b)
-
-    (* OCaml *)
-    type ('a,'b) pretty = Lovely of 'a | Cute of 'b * ClothingModule.ButtonType
-    type ('a,'b) pretty = Pretty of 'a * 'b * int
-    type ('a,'b) pretty = Pretty of 'a
-    type ('a,'b) pretty = 'a * 'b
-
-
-*Will explain later, and add more material.*
-
-Until we do, have a look at our [page on translating between OCaml Scheme and Haskell](http://lambda1.jimpryor.net/translating_between_OCaml_Scheme_and_Haskell) from the first time we offered this seminar.
-[[!toc]]
 
 The functional programming literature tends to use one of four languages: Scheme, OCaml, Standard ML (SML), or Haskell. With experience, you'll grow comfortable switching between these. At the beginning, though, it can be confusing.
 
-The easiest translations are between OCaml and SML. These languages are both derived from a common ancestor, ML. For the most part, the differences between them are only superficial. [Here's a translation manual](http://www.mpi-sws.org/~rossberg/sml-vs-ocaml.html).
+The easiest translations are between OCaml and SML. These languages are both derived from a common ancestor, ML. For the most part, the differences between them are only superficial. [Here's a translation manual](http://www.mpi-sws.org/~rossberg/sml-vs-ocaml.html). [Here's another comparison](http://adam.chlipala.net/mlcomp/).
 
 In some respects these languages are closer to Scheme than to Haskell: Scheme, OCaml and SML all default to call-by-value evaluation order, and all three have native syntax for mutation and other imperative idioms (though that's not central to their design). Haskell is different in both respects: the default evaluation order is call-by-name (strictly speaking, it's "call-by-need", which is a more efficient cousin), and the only way to have mutation or the like is through the use of monads.
 
@@ -30,7 +11,7 @@ On both sides, however, the non-default evaluation order can also be had by usin
 
 Additionally, the syntax of OCaml and SML is superficially much closer to Haskell's than to Scheme's.
 
-#Comments, Whitespace, and Brackets#
+# Comments, Whitespace, and Brackets #
 
                -- this is a single line comment in Haskell
 
@@ -56,119 +37,52 @@ Additionally, the syntax of OCaml and SML is superficially much closer to Haskel
 *      In Haskell, a block of code can be bracketed with `{` and `}`, with different expressions separated by `;`. But usually one would use line-breaks and proper indentation instead. In OCaml, separating expressions with `;` has a different meaning, having to do with how side-effects are sequenced. Instead, one can bracket a block of code with `(` and `)` or with `begin` and `end`. In Scheme, of course, every parentheses is significant.
 
 
-#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).)
+We've written some advice on how to do some OCaml-ish and Haskell-ish things in Scheme, and how to get Scheme-ish continuations in OCaml, [[on another page|/rosetta3]].
 
-       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) ...) ...)
-
-       These last three forms are also available in OCaml, but to use them you'll need to compile and install Oleg Kiselyov's "delimcc" or "caml-shift" library (these names refer to the same library), which you can find [here](http://okmij.org/ftp/continuations/implementations.html#caml-shift). You'll already need to have OCaml installed. It also helps if you already have the findlib package installed, too, [as we discuss here](http://lambda.jimpryor.net/how_to_get_the_programming_languages_running_on_your_computer/). If you're not familiar with how to compile software on your computer, this might be beyond your reach for the time being.
-
-       But assuming you do manage to compile and install Oleg's library, here's how you'd use it in an OCaml session:
+#Haskell and OCaml#
 
-               #require "delimcc";; (* loading Oleg's library this way requires the findlib package *)
-                   (* if you don't have findlib, you'll need to start ocaml like
-                    * this instead: ocaml -I /path/to/directory/containing/delimcc delimcc.cma
-                    *)
-               open Delimcc;; (* this lets you say e.g. new_prompt instead of Delimcc.new_prompt *)
-               let p = new_prompt ();;
-               let prompt thunk = push_prompt p thunk;;
-               let foo =
-                 ...
-                 prompt (fun () ->
-                   ...
-                   shift p (fun k -> ...)
-                   ...
-                   (* or *)
-                   control p (fun k -> ...)
-                   ...
-                   (* or *)
-                   abort p value
-                   ...
-                 )
-                 ...
+Here we will give some general advice about how to translate between OCaml and Haskell.
 
-       There is also a library for using *undelimited* continuations in OCaml, but it's shakier than Oleg's delimited continuation library.
+<!--
+TODO
+Here is comparison of the syntax for declaring types in Haskell and OCaml:
 
-There are some more hints about Scheme [here](/assignment8/) and [here](/week1/). We won't say any more here.
+    -- Haskell
+    data Pretty a b = Lovely a | Cute b ClothingModule.ButtonType
+    newtype Pretty a b = Pretty a b Int
+    newtype Pretty a b = Pretty { unPretty a }
+    type Pretty a b = (a, b)
 
+    (* OCaml *)
+    type ('a,'b) pretty = Lovely of 'a | Cute of 'b * ClothingModule.ButtonType
+    type ('a,'b) pretty = Pretty of 'a * 'b * int
+    type ('a,'b) pretty = Pretty of 'a
+    type ('a,'b) pretty = 'a * 'b
 
+-->
 
-#Haskell and OCaml#
+*   Our [[more entry-level page|/rosetta1]] comparing Scheme, OCaml, and Haskell (no discussion of types or records)
+*   It may sometimes be useful to try [OCaml](http://try.ocamlpro.com/) or [Haskell](http://tryhaskell.org/) in your web browser
+*   See our pages about [[learning OCaml]] and [[learning Haskell]]
+*   Another page comparing Haskell and OCaml: [Haskell for OCaml Programmers](http://blog.ezyang.com/2010/10/ocaml-for-haskellers/)
+*   Here's the other direction: [Introduction to OCaml for Haskellers](http://foswiki.cs.uu.nl/foswiki/pub/Stc/BeyondFunctionalProgrammingInHaskell:AnIntroductionToOCaml/ocaml.pdf), [another](http://blog.ezyang.com/2010/10/ocaml-for-haskellers/)
+*   Haskell Wiki on [OCaml](https://wiki.haskell.org/OCaml)
+*   [ML Dialects and Haskell](http://hyperpolyglot.org/ml); this discusses other ML-ish languages as well as OCaml and Haskell
+*   Quora discussion of the [differences between Haskell and ML languages](http://www.quora.com/What-are-the-key-differences-between-Haskell-and-Standard-ML?browse)
+*   [Another discussion](http://jxyzabc.blogspot.com/2009/03/haskell-vs-ocaml-or-ravings-of.html)
 
-We will however try to give some general advice about how to translate between OCaml and Haskell.
 
-*      Again, it may sometimes be useful to [try Haskell in your web browser](http://tryhaskell.org/)
+<!--
+TODO
 *      There are many Haskell tutorials and textbooks available. This is probably the most actively developed: [Haskell wikibook](http://en.wikibooks.org/wiki/Haskell)
 *      [Yet Another Haskell Tutorial](http://www.cs.utah.edu/~hal/docs/daume02yaht.pdf) (much of this excellent book has supposedly been integrated into the Haskell wikibook)
 *      All About Monads has supposedly also been integrated into the Haskell wikibook
 *      (A not-so-)[Gentle Introduction to Haskell](http://web.archive.org/web/http://www.haskell.org/tutorial/) (archived)
 *      [Learn You a Haskell for Great Good](http://learnyouahaskell.com/)
-*      [Another page comparing Haskell and OCaml](http://blog.ezyang.com/2010/10/ocaml-for-haskellers/)
+-->
+
 
 ##Type expressions##