Merge branch 'master' into working
authorJim <jim.pryor@nyu.edu>
Wed, 4 Feb 2015 21:17:40 +0000 (16:17 -0500)
committerJim <jim.pryor@nyu.edu>
Wed, 4 Feb 2015 21:17:40 +0000 (16:17 -0500)
* master: (32 commits)
  update for rename of rosetta.mdwn to rosetta1.mdwn
  update for rename of rosetta.mdwn to rosetta1.mdwn
  update for rename of rosetta.mdwn to rosetta1.mdwn
  update for rename of rosetta.mdwn to rosetta1.mdwn
  update for rename of rosetta.mdwn to rosetta1.mdwn
  rename rosetta.mdwn to rosetta1.mdwn
  huh, last edits are not displaying
  tweak markup
  post latest content
  add Prelude
  fix typo, thanks Kyle
  stronger note
  note what's in progress
  note what's in progress
  add comments, paste content from rosetta2
  rename more_rosetta.mdwn to rosetta2.mdwn
  cut content
  create page
  replace content
  update for rename of rosetta2.mdwn to rosetta.mdwn
  ...

index.mdwn
learning_haskell.mdwn
learning_ocaml.mdwn
learning_scheme.mdwn
readings.mdwn
rosetta.mdwn [deleted file]
rosetta1.mdwn [new file with mode: 0644]
rosetta2.mdwn [new file with mode: 0644]
topics/week1_advanced_notes.mdwn

index 6e0f1dd..fd7673d 100644 (file)
@@ -80,9 +80,9 @@ what you think you need in order to solve the problem.
 [[Advanced notes|topics/week1 advanced notes]]
 
 (**Intermezzo**)
-> The [[differences between our made-up language and Scheme, OCaml, and Haskell|rosetta]];
-Help on [[learning Scheme]], [[OCaml|learning OCaml]], and [[Haskell|learning Haskell]];
-[[What do words like "interpreter" and "compiler" mean?|ecosystem]]
+> Help on [[learning Scheme]], [[OCaml|learning OCaml]], and [[Haskell|learning Haskell]];
+The [[differences between our made-up language and Scheme, OCaml, and Haskell|rosetta1]] (in progress);
+[[What do words like "interpreter" and "compiler" mean?|ecosystem]] (in progress)
 
 <!--
 [[Lambda Evaluator]]: Usable in your browser. It can help you check whether your answer to some of the homework questions works correctly. There is also now a [library](/lambda_library) of lambda-calculus arithmetical and list operations, some relatively advanced.
index 4e728ae..54dd276 100644 (file)
@@ -1,6 +1,6 @@
 *   [Try Haskell in your browser](http://tryhaskell.org) (slow, bare-bones) <!-- similar websites listed at https://wiki.haskell.org/Learning_Haskell#Trying_Haskell_online -->
 *   This site's guide to [[Installing Haskell|/installing#haskell]]
-*   This site's [[explanation of the differences between Scheme, OCaml, and Haskell|rosetta]]
+*   This site's [[explanation of the differences between Scheme, OCaml, and Haskell|rosetta1]]
 
 
 <!-- -->
@@ -58,7 +58,8 @@
 [Extensions](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghc-language-features.html)
 *   Libraries from
 [Haskell Platform](https://www.haskell.org/platform/doc/2014.2.0.0/platform/doc) |
-[Haskell 2010](https://www.haskell.org/onlinereport/haskell2010/haskellpa2.html) <!--
+[Haskell 2010](https://www.haskell.org/onlinereport/haskell2010/haskellpa2.html) 
+([Prelude](https://www.haskell.org/onlinereport/haskell2010/haskellch9.html)) <!--
 [GHC latest bootstrap libraries](https://downloads.haskell.org/~ghc/latest/docs/html/libraries)
 -->
 *   GHC [releases](https://www.haskell.org/ghc) and
index 666a756..0bd1b69 100644 (file)
@@ -1,6 +1,6 @@
 *   [Try OCaml in your browser](http://try.ocamlpro.com/) (slow, bare-bones)
 *   This site's guide to [[Installing OCaml|/installing#ocaml]]
-*   This site's [[explanation of the differences between Scheme, OCaml, and Haskell|rosetta]]
+*   This site's [[explanation of the differences between Scheme, OCaml, and Haskell|rosetta1]]
 
 
 <!-- -->
index f10f1cf..2ded2d3 100644 (file)
@@ -1,6 +1,6 @@
 *   [Try Scheme in your browser](http://tryscheme.sourceforge.net/) (slow, bare-bones)
 *   This site's guide to [[Installing Scheme|/installing#scheme]]
-*   This site's [[explanation of the differences between Scheme, OCaml, and Haskell|rosetta]]
+*   This site's [[explanation of the differences between Scheme, OCaml, and Haskell|rosetta1]]
 
 <!-- -->
 *   Wikipedia on
index 175208c..b30c3dd 100644 (file)
@@ -5,7 +5,7 @@
 *   Help on [[Learning Haskell]]
 
 <!-- -->
-*   This site's [[explanation of the differences|rosetta]] between these languages
+*   This site's [[explanation of the differences|rosetta1]] between these languages
 
 
 ## Other Offsite Reading ##
diff --git a/rosetta.mdwn b/rosetta.mdwn
deleted file mode 100644 (file)
index dad4fc0..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-## Can you summarize the differences between Scheme, OCaml, and Haskell? ##
-
-Yes, I will (start to) do so shortly.
-
-
-## Offsite Readings comparing Scheme, OCaml, and Haskell ##
-
-*   [Haskell for OCaml Programmers](http://science.raphael.poss.name/haskell-for-ocaml-programmers.pdf)
-*   [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)
-*   [Differences between Haskell and SML?](http://www.quora.com/What-are-the-key-differences-between-Haskell-and-Standard-ML?browse)
-*   [Comparing SML to OCaml](http://www.mpi-sws.org/~rossberg/sml-vs-ocaml.html)
-
-
-
-## Why did you name this page "Rosetta"? ##
-
-The [Rosetta Stone](https://en.wikipedia.org/wiki/Rosetta_Stone) is a famous slab discovered during Napoleon's invasion of Egypt, that had the same decree written in ancient Greek (which modern scholars understood) and two ancient Egyptian scripts (which they didn't). The slab enabled us to recover understanding of those Egyptian scripts; and has since come to be a symbol for the simultaneous expression of a single idea in multiple languages. A number of websites do this for various programming languages:
-
-<table><th>
-<td>Scheme
-<td>OCaml
-<td>Haskell
-<tr>
-<td rowspan=10>&nbsp;
-<td><a href="http://rosettacode.org/wiki/Category:Scheme">Rosetta Code</a>
-<td><a href="http://rosettacode.org/wiki/Category:OCaml">Rosetta Code</a>
-<td><a href="http://rosettacode.org/wiki/Category:Haskell">Rosetta Code</a>
-<tr>
-<td><a href="http://pleac.sourceforge.net/pleac_guile/index.html">PLEAC</a>
-<td><a href="http://pleac.sourceforge.net/pleac_ocaml/index.html">PLEAC</a>
-<td><a href="http://pleac.sourceforge.net/pleac_haskell/index.html">PLEAC</a>
-<tr>
-<td>n/a
-<td colspan=2 align=center><hr><a href="http://langref.org/ocaml+haskell/solved">langref.org</a>
-<tr>
-<td><a href="http://www.codecodex.com/wiki/Category:Scheme">code codex</a>
-<td><a href="http://www.codecodex.com/wiki/Category:Objective_Caml">code codex</a>
-<td><a href="http://www.codecodex.com/wiki/Category:Haskell">code codex</a>
-<tr>
-<td><a href="http://community.schemewiki.org/?ninety-nine-scheme-problems">99 problems</a>
-<td><a href="http://ocaml.org/learn/tutorials/99problems.html">99 problems</a>
-<td><a href="https://wiki.haskell.org/H-99:_Ninety-Nine_Haskell_Problems">99 problems</a>
-</table>
-
-See also the [Project Euler](https://projecteuler.net/) programming challenges.
diff --git a/rosetta1.mdwn b/rosetta1.mdwn
new file mode 100644 (file)
index 0000000..5e9c052
--- /dev/null
@@ -0,0 +1,412 @@
+[[!toc levels=2]]
+
+** *This page is still being written!* **
+
+
+## Can you summarize the differences between your made-up language and Scheme, OCaml, and Haskell? ##
+
+The made-up language we wet our toes in in week 1 is called Kapulet. (I'll tell you the story behind its name sometime.) The purpose of starting with this language is that it represents something of a center of gravity between Scheme, OCaml, and Haskell, and also lacks many of their idiosyncratic warts. One downside is that it's not yet implemented in a form that you can run on your computers. So for now, if you want to try out your code on a real mechanical evaluator, you'll need to use one of the other languages.
+
+Also, if you want to read code written outside this class, or have others read your code, for these reasons too you'll need to make the shift over to one of the established languages.
+
+We hope, though, that learning Kapulet first puts you in a position to make that shift more effortlessly, and also to more quickly see the places where there's underlying unity to Scheme, OCaml, and Haskell, despite their diverse syntaxes. (And idiosyncratic warts.)
+
+### Comments
+
+    ...  # this is a comment in Kapulet, that goes until the end of the line
+
+    ...  ; this is a comment in Scheme, that goes until the end of the line
+
+    ...  -- this is a comment in Haskell, that goes until the end of the line
+
+Note that for Haskell's comments, the `--` must be immediately followed by something like a space or a letter. `-->` does not begin a comment; it's a legal operator symbol.
+
+OCaml doesn't have comments of that sort. It only has "block" comments like this:
+
+    (* ... *)
+
+which may last for several lines. These comments *nest*, so that:
+
+    (* ... (* inner *) ... *)
+
+is a single comment.
+
+Haskell also has block comments, though it `{- writes them differently -}`.
+Haskell's block comments also nest.
+
+Racket and Scheme also have block comments, though they `#| write them differently |#`.
+These block comments also nest. Another form of block comments is `#;( ... )`. Those may contain nested parentheses, and extend until the next *matching* `)`. So prefixing `#;` to a complex parenthesized expression is a way to turn the whole thing into a comment. (These two comment styles aren't part of the official Scheme standard, but they are widely implemented.)
+
+
+
+### Variable names
+
+% Haskell's division into letter-based vs operators. Each can be "flagged" to temporarily behave as though it belonged to the other syntactic category (see below).
+
+
+
+### Infix operators and parentheses
+
+
+Kapulet, OCaml, and Haskell all understand some expressions like `+` to be infix operators. So you would write:
+
+    1 + 2
+
+not:
+
+    + 1 2
+
+Although all three of these languages permits you to enclose an infix operator in parentheses to make a *section*, which no longer has infix syntax. In Kapulet, `( + )` is the same as &lambda; `(x, y). x + y`, whereas in OCaml and Haskell it's a *curried* function, which we can write (in Kapulet syntax) as &lambda; `x y. x + y`.
+
+Kapulet and OCaml have some operators spelled with letters also taking infix syntax, such as `comp` in Kapulet or `mod` in OCaml. In Haskell, this is never the case: variables that are made of letters are only treated as function terms being applied to arguments *when they're at the start* of a list of expressions; and variables that are made of punctuation symbols, and not enclosed in parentheses, will only be treated as infix operators. However, Haskell permits you to temporarily "flag" a letter-made function term to behave like an infix operator, by enclosing it in `` ` `` marks. Thus in Haskell you can write:
+
+    3 `mod` 2
+
+But without the `` ` ``, you'd have to write: `mod 3 2`.
+
+Scheme has no infix operators. It ruthlessly demands that all functions to be applied to arguments come at the start of a list of expressions, regardless of whether those functions are spelled using letters, punctuation symbols, or a mix of the two. Thus in Scheme one always writes:
+
+    (+ 3 2)
+
+and the like. Moreover, in Scheme parentheses are never optional and never redundant. In contexts like this, the parentheses are necessary to express that the function is being applied; `+ 3 2` on its own is not a complete Scheme expression. And if the `+` were surrounded by its own parentheses, as in:
+
+    ((+) 3 2)
+
+what that would mean is that `+` is first being applied to *zero* arguments, which is different from not applying it all. (In Kapulet, OCaml, and Haskell, one would write that `f` is being applied to "zero arguments" like this: `f ()`.) Scheme helpfully defines the result of applying `+` to zero arguments to be `0`. So `((+) 3 2)` would evaluate to whatever `(0 3 2)` does, and that's an error, because `0` is not a function.
+
+Note that `(0 3 2)`, although it *is*, qua expression, a list of numbers, does not evaluate to a list. To get an expression that *evaluates to* that list, you'd have to use `(list 0 3 2)` or `'(0 3 2)`. (Notice the initial `'`.)
+
+In Scheme, you can also write `(+ 3 2 10)`, and so on. You only have to write `(+ (+ 3 2) 10)` if you really want to.
+
+% Parentheses have other roles in Scheme, too.
+
+In Scheme, the default style for defining functions is as taking several arguments simultaneously, that is the *uncurried* style. In OCaml and Haskell, the default style is to define them *curried*. Curried functions can easily be partially applied:
+
+    (* OCaml *)
+    let add  = fun x y -> x + y in
+    let add2 = add 2 in
+        add2 3
+    ;;
+
+will result in `5`.
+
+In Scheme, the default would be to define `add` like this:
+
+    (define add (lambda (x y) (+ x y)))
+
+Then you cannot say `(add 2)`, because `add` will be expecting two arguments, but you only supplied one. You can however define curried functions in Scheme, it's just more laborious:
+
+    (define curried_add (lambda (x) (lambda (y) (+ x y))))
+    (define add2 (curried_add 2))
+    (add2 3)
+
+will result in `5`. This is the best one can do in official Scheme, but there are various syntax extensions and macros out there to make it possible to write this sort of thing more succinctly.
+
+OCaml and Haskell also permit defining functions in uncurried form:
+
+    (* OCaml *)
+    let add  = fun (x, y) -> x + y in
+    let add2 = fun add 2 in ...
+
+Here the last displayed line will fail, because `add` expects as its argument a tuple of two numbers.
+
+Kapulet essentially works like OCaml and Haskell; though for pedagogical reasons I started out by introducing uncurried definitions, rather than the *curried* definitions those other languages predominantly use.
+
+As we mentioned, in Kapulet, OCaml, and Haskell, there is a shorthand that enables you to write things like:
+
+    # Kapulet
+    let
+      ten_minus match lambda x. 10 - x;
+      and_ys    match lambda x. x & ys
+    in (ten_minus, and_ys)
+
+like this:
+
+    # Kapulet
+    let
+      ten_minus match (10 - );
+      and_ys    match ( & ys)
+    in (ten_minus, and_ys)
+
+There are just minor differences between these languages. First, OCaml doesn't have the `( + 10)` or `(10 + )` forms, but only the `( + )`. Second, as a special case, OCaml doesn't permit you to do this with its list-consing operator `::`. You have to write `fun x xs -> x :: xs`, not `( :: )`. Whereas in Kapulet `( & )`, `(x & )`, and `( & xs)` are all sections using its sequence-consing operator `&`; and in Haskell, `( : )`, `(x : )`, and `( : xs)` are the same.
+
+Thirdly, in Kapulet, `( - 10)` also expresses &lambda; `x. x - 10` (consistently with `(10 - )`), but Haskell (and OCaml) treat this form differently, and interpret it as meaning the integer `- 10`. Here's how to express some things in Kapulet:
+
+    # Kapulet
+    (0 - 2)
+    ( - 2)         # ( - 2) 10 == 8
+    (0 - )
+    ( - ) (5, 3)
+    
+
+and here are their translations into Haskell:
+
+    -- Haskell
+    ( -2 )
+    (subtract 2)  -- subtract 2 10 == 8
+    negate        -- (0 - ) also works
+    ( - ) 5 3
+
+OCaml expresses `(0 - )` or `negate` as `~-`. You can write `3 * (0 - 2)` in OCaml as either `3 * ( -2 )` or as `3 * ~-2`.
+
+I know all these languages fairly well, and I still find this last issue difficult to keep track of. You may be starting to understand why I spoke of "warts."
+
+
+### Equality and Booleans
+
+The relation that's written `==` in Kapulet is also written that way in Haskell. That symbol means something else in OCaml, having to do with mutable reference cells; to get the same notion in OCaml one writes just a single `=`. The negation of this notion is written `!=` in Kapulet, `/=` in Haskell, and `<>` in OCaml. (Again, `!=` means something else in OCaml.)
+
+The relations that are written `and`, `or`, and `not` are written in Haskell and OCaml as `&&`, `||`, and `not`. (Haskell uses `and` and `or` to express functions that form the conjunction or disjunction of every `Bool` value in a List of such. OCaml permits `or` as an old synonym for `||`, but discourages using that spelling. OCaml also permits `&` as an old, discouraged synonym for `&&`.)
+
+Scheme %%
+
+The values that are written `'true` and `'false` in Kapulet are written in Haskell as `True` and `False`, and in OCaml as just `true` and `false`. They're written `#t` and `#f` in Scheme, but in Scheme in many contexts any value that isn't `#f` will behave as though it were `#t`, even values you might think are more "false-ish", like `0` and the empty list. Thus `(if 0 'yes 'no)` will evaluate to `'yes`.
+
+Scheme recognizes the values `'true` and `'false`, but it treats `'false` as distinct from `#f`, and thus as a "true-ish" value, like all of its other values that aren't `#f`.
+
+
+
+### Sequences, Lists, and Tuples
+
+In Kapulet, we have a notion I called a "sequence" which has an empty form `[]` and a cons-ing operator `&`, so that:
+
+    1 & 2 & 3 & []
+
+can also be written:
+
+    [1, 2, 3]
+
+Haskell is very similar, except that it calls these Lists, and its cons-ing operator is written `:`. OCaml also calls them `list`s, and its cons-operator is written `::`. (OCaml *also* uses `:`, but it uses it to deal with types, and Haskell in turn also uses `::`, but that's what *it* uses to deal with types. Grr.)
+
+Kapulet writes the operator that concatenates or appends sequences as `&&`. Thus:
+
+    # Kapulet
+    [1, 2] && [3, 4, 5]
+
+evaluates to `[1, 2, 3, 4, 5]`. Haskell writes this operator as `++`. In Haskell, a `String` is just a List of `Char`, so `++` is also the operator we use to append strings:
+
+    -- Haskell
+    "over" ++ "due"
+
+evaluates to `"overdue"`. In OCaml, `string`s aren't implemented as `list`s, so their append operators are different: `^` for `string`s and `@` for `list`s:
+
+    (* OCaml *)
+    [1; 2] @ [3; 4; 5] ;;
+    "over" ^ "due" ;;
+
+evaluate to `[1; 2; 3; 4; 5]` and `"overdue"`. Note that OCaml separates its `list` items with semicolons not commas. If you write `[1, 2, 3]` in OCaml, it will think that's a one-element list whose first element is a triple, that is, what you'd write in Haskell as `[(1, 2, 3)]`.
+
+Here are some list functions in Kapulet:
+
+    length
+    (&&)
+    # the following were defined in homework
+    empty?
+    tail
+    drop
+    take
+    split
+    filter
+    partition
+    map
+    map2
+    # the following were defined in extra credit
+    unmap2
+    takewhile
+    dropwhile
+    reverse
+    # new functions
+    concat       # converts [[10, 20], [30], [], [40, 50]]
+                 # to [10, 20, 30, 40, 50] (only merging a single layer of []s)
+    (mem)        # infix syntax, 2 mem [1, 2, 3] == 'true
+    nth          # nth [10, 20, 30] 1 == 20, because the first element
+                 # is at position 0; fails if index is out of bounds
+    all? p xs    # all? odd? [1, 3, 5] == 'true
+    any? p xs    # any? even? [1, 3, 5] == 'false
+
+
+
+Here are the corresponding functions in Haskell:
+
+    length
+    (++)
+    null
+    tail     -- compare head, which fails on []
+    drop     {- but these are curried functions, so you write `drop n xs`
+                not `drop (n, xs)` as in Kapulet -}
+    take
+    splitAt
+    filter
+    Data.List.partition
+    map
+    zipWith  {- zip handles the special case where f is the function that forms ordered pairs
+                both zipWith and zip stop with the shortest list -}
+    unzip    -- doesn't take an f argument, assumes (\(x, y) -> (x, y))
+    takeWhile
+    dropWhile
+    reverse
+    concat
+    elem     -- not infix syntax, but often written as: 2 `elem` [1, 2, 3]
+    (!!)     -- infix syntax: [10, 20, 30] !! 1 == 20; fails if index is out of bounds
+    all p xs
+    any p xs
+
+
+
+Here they are in OCaml:
+
+    length
+    (@)          (* or List.append *)
+    (* no function corresponding to empty? *)
+    List.tl      (* compare List.hd, which fails on [] *)
+    (* no function corresponding to drop or take *)
+    (* no function corresponding to split; OCaml uses List.split to mean something else *)
+    List.filter  (* also List.find_all *)
+    List.partition
+    List.map
+    List.map2    (* compare List.combine, like Haskell's zip
+                    both map2 and combine fail if the lists are different lengths *)
+    List.split   (* like Haskell's unzip, doesn't take an f argument *)
+    (* no function corresponding to takewhile or dropwhile *)
+    List.rev
+    List.concat  (* also List.flatten, which still only merges a single layer of []s *)
+    List.mem     (* not infix syntax *)
+    List.nth     (* List.nth [10; 20; 30] 1 = 20; fails if index is out of bounds *)
+    List.for_all p xs
+    List.exists p xs
+
+
+How does all this look in Scheme? Well, Scheme has a notion they call a (proper) `list`, and also a notion they call a `vector`. There are also what Scheme calls "improper" `list`s, with `(cons 1 'nonlist)` or `'(1 . nonlist)`, where `'nonlist` is any non-list (here it's a `symbol`) being a special case. Let's ignore the improper `list`s. Scheme's (proper) `list`s and `vector`s each has a claim to correspond to Kapulet's sequences, Haskell's Lists, and OCaml's `list`s. Each is also somewhat different. The dominant differences are:
+
+1.  these structures in Scheme can contain heterogenously-typed elements, including further `list`s and `vector`s in some positions but not in others
+2.  in the official Scheme standard, `list`s and `vector`s are both *mutable* containers, that is, one and the same persisting `list` structure can have different
+elements at different stages in a program's evaluation
+
+Many Scheme implementations also provide immutable versions of `list`s and `vector`s, more closely approximating the sequences/lists in Kapulet, Haskell, and OCaml. With some configurations, Racket even makes the immutable versions the defaults. But none of these are yet part of the official Scheme standard. Also, difference 1 is present in all Scheme implementations. This makes Scheme's `list`s and `vector`s in some ways more akin to *tuples* in the other languages (to "proper" tuples in Kapulet).
+
+There are also some differences in how `list`s are specified in Scheme versus the other languages. In Scheme, one writes the empty list like this:
+
+    (list)
+
+and lists with more elements like this:
+
+    (list 10)
+    (list 10 x)
+    (list 10 x 'alpha)
+    (list 10 x 'alpha (list 'beta 'gamma) 'delta 20)
+
+In the preceding, the `x` is a variable and is evaluated to be whatever value it's bound to in the context where the displayed expressions are being evaluated. If one has a list specification that contains no variables, no matter how deeply embedded, then a certain shorthand becomes available, using a `'` prefix, like this:
+
+    '()                          ; same as (list)
+    '(10)                        ; same as (list 10)
+    '(10 alpha)                  ; same as (list 10 'alpha)
+    '(10 alpha (beta gamma) 20)  ; same as (list 10 'alpha (list 'beta 'gamma) 20)
+
+Scheme can also write <code>'<em>something</em></code> as <code>(quote <em>something</em>)</code>. (The `quote` is not a function being applied to some argument; this is a special syntax that only superficially *looks* like a function application.)
+
+
+Here are the `list` functions in Scheme corresponding to the functions listed in the other languages:
+
+    cons              ; corresponds to Kapulet's ( & ), Haskell's ( : ), OCaml's `::`
+    length
+    append            ; corresponds to Kapulet's ( && ), Haskell's ( ++ ), OCaml's ( @ )
+                      ; can be applied to one or more arguments
+    null?             ; corresponds to Kapulet's empty?, Haskell's null
+    car               ; corresponds to Haskell's head
+    cdr               ; corresponds to Kapulet's and Haskell's tail
+    (list-tail xs k)  ; corresponds to Kapulet's drop (k, xs); fails if out-of-bounds
+    ; no official function corresponding to take or split or filter or partition
+    map               ; corresponds to Kapulet's map and map2
+                      ; can take one or more list arguments
+    ; no official function corresponding to unmap2 or takewhile or dropwhile
+    reverse
+    ; no official function corresponding to concat
+    member            ; corresponds to Kapulet's (mem) and Haskell's elem
+    (list-ref xs k)   ; corresponds to Kapulet's `nth xs k`
+    ; no official function corresponding to all or any
+
+All of the functions listed as missing from the official Scheme standard can be found in various add-on libraries, or you could define them yourself if you had to.
+
+
+
+
+
+<!--
+
+symbol=?
+
+characters: #\c  #\xff  #\space  #\newline
+
+
+
+### Other functions
+
+Same in all: `succ`, `pred`, `fst`, `snd`.
+
+Same in Kapulet and Haskell (modulo the differences between multivalues and tuples), aren't predefined in OCaml: `id`, `const`, `flip`, `curry`, `uncurry`.
+
+Kapulet's `(comp)` is Haskell's `( . )`; isn't predefined in OCaml.
+
+Kapulet and Haskell both have `( $ )`; OCaml expresses as `( @@ )`. (OCaml also has `|>` to express the converse operation: `f x`, `f @@ x` and `x |> f` all mean the same.)
+
+Kapulet's `odd?` and `even?` are Haskell's `odd`, `even`; aren't predefined in OCaml.
+
+Kapulet's `swap` (defined in homework) is Haskell's `Data.Tuple.swap`.
+
+Kapulet's `dup` isn't predefined in Haskell but can be easily expressed as `\x -> (x, x)`.
+
+-->
+
+
+
+### More to come ...
+
+(This page is being worked on...)
+
+FIXME
+
+
+## Offsite Readings comparing Scheme, OCaml, and Haskell ##
+
+
+*   [Haskell for OCaml Programmers](http://science.raphael.poss.name/haskell-for-ocaml-programmers.pdf)
+*   [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)
+*   [Differences between Haskell and SML?](http://www.quora.com/What-are-the-key-differences-between-Haskell-and-Standard-ML?browse)
+*   [Comparing SML to OCaml](http://www.mpi-sws.org/~rossberg/sml-vs-ocaml.html)
+
+
+
+
+## Why did you name these pages "Rosetta"? ##
+
+The [Rosetta Stone](https://en.wikipedia.org/wiki/Rosetta_Stone) is a famous slab discovered during Napoleon's invasion of Egypt, that had the same decree written in ancient Greek (which modern scholars understood) and two ancient Egyptian scripts (which they didn't). The slab enabled us to recover understanding of those Egyptian scripts; and has since come to be a symbol for the simultaneous expression of a single idea in multiple languages. A number of websites do this for various programming languages:
+
+<table><th>
+<td>Scheme
+<td>OCaml
+<td>Haskell
+<tr>
+<td rowspan=10>&nbsp;
+<td><a href="http://rosettacode.org/wiki/Category:Scheme">Rosetta Code</a>
+<td><a href="http://rosettacode.org/wiki/Category:OCaml">Rosetta Code</a>
+<td><a href="http://rosettacode.org/wiki/Category:Haskell">Rosetta Code</a>
+<tr>
+<td><a href="http://pleac.sourceforge.net/pleac_guile/index.html">PLEAC</a>
+<td><a href="http://pleac.sourceforge.net/pleac_ocaml/index.html">PLEAC</a>
+<td><a href="http://pleac.sourceforge.net/pleac_haskell/index.html">PLEAC</a>
+<tr>
+<td>n/a
+<td colspan=2 align=center><hr><a href="http://langref.org/ocaml+haskell/solved">langref.org</a>
+<tr>
+<td><a href="http://www.codecodex.com/wiki/Category:Scheme">code codex</a>
+<td><a href="http://www.codecodex.com/wiki/Category:Objective_Caml">code codex</a>
+<td><a href="http://www.codecodex.com/wiki/Category:Haskell">code codex</a>
+<tr>
+<td><a href="http://community.schemewiki.org/?ninety-nine-scheme-problems">99 problems</a>
+<td><a href="http://ocaml.org/learn/tutorials/99problems.html">99 problems</a>
+<td><a href="https://wiki.haskell.org/H-99:_Ninety-Nine_Haskell_Problems">99 problems</a>
+</table>
+
+See also the [Project Euler](https://projecteuler.net/) programming challenges.
diff --git a/rosetta2.mdwn b/rosetta2.mdwn
new file mode 100644 (file)
index 0000000..c37f222
--- /dev/null
@@ -0,0 +1,5 @@
+## More detailed differences between Scheme, OCaml, and Haskell ##
+
+*Will add this later, as we learn more concepts.*
+
+
index c5e589f..8b6289a 100644 (file)
@@ -102,7 +102,7 @@ If we get to the `y & ys` line in the pattern list, and the pattern-match succee
 Sometimes it's useful to bind variables against overlapping parts of a structure. For instance, suppose I'm writing a pattern that is to be matched against multivalues like `([10, 20], 'true)`. And suppose I want to end up with `ys` bound to `[10, 20]`, `x` bound to `10`, and `xs` bound to `[20]`. Using the techniques introduced so far, I have two options. First, I could bind `ys` against `[10, 20]`, and then initiate a second pattern-match to break that up into `10` and `[20]`. Like this:
 
     case ([10, 20], 'true) of
-      [ys, _] then case ys of
+      (ys, _) then case ys of
                      x & xs then ...;
                      ...
                    end;
@@ -112,7 +112,7 @@ Sometimes it's useful to bind variables against overlapping parts of a structure
 Alternatively, I could directly bind `x` against `10` and `xs` against `[20]`. But then I would have to re-cons them together again to get `ys`. Like this:
 
     case ([10, 20], 'true) of
-      [x & xs, _] then let
+      (x & xs, _) then let
                          ys match x & xs
                        in ...;
       ...
@@ -121,7 +121,7 @@ Alternatively, I could directly bind `x` against `10` and `xs` against `[20]`. B
 Both of these strategies work. But they are a bit inefficient. I said you didn't really need to worry about efficiency in this seminar. But these are also a bit cumbersome to write. There's a special syntax that enables us to bind all three of `ys`, `x`, and `xs` in the desired way, despite the fact that they will be matching against overlapping, rather than discrete, parts of the value `[10, 20]`. The special syntax looks like this:
 
     case ([10, 20], 'true) of
-      [(x & xs) as ys, _] then ...
+      ((x & xs) as ys, _) then ...
       ...
     end