`'`*something*

as `(quote `*something*)

. (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 the list has length < k
; no official function predefined for 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 predefined for unmap2 or takewhile or dropwhile
reverse
; no official function prefefined for join/concat
memv, member ; correspond to Kapulet's (mem) and Haskell's elem
; memv compares elements using eqv?, member using equal?
(list-ref xs k) ; corresponds to Kapulet's `nth xs k`
; fails if the index k is out of bounds
; no official function predefined for 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.
### Tuples
The course notes [[already mentioned|topics/week1_kapulet_intro#lightweight]] that Kapulet has a "lightweight" notion of tuples, called multivalues and written `(10, x)`, as well as a heavier notion written `Pair (10, x)`. The latter is what corresponds to the tuples in Haskell and OCaml. They don't have any explicit notation for Kapulet's "lightweight" tuples (though they exist behind the scenes in OCaml and explain some of its otherwise puzzling behavior). There are good reasons for introducing this additional complexity in Kapulet, but this is not the place to explain them.
All of these languages have notions of zero-length tuples, as well as pairs, triples, and the like. (In Kapulet's case, there are both the 0-length multivalue `()` and heavier counterparts.)
Probably the closest approximation to tuples in Scheme is its notion of `vector`s, though in the case of pairs, Scheme's `pair`s---which it identifies with short, possibly "improper" `list`s---are arguably also contenders. The fact that these Scheme structures permit elements of heterogenous type is not a problem, because that is also true for tuples in the other languages. However, Scheme's `vector`s and `pair`s are officially mutable, but tuples in the other languages are not. (As mentioned above, many Scheme implementations do also provide immutable versions of these structures.)
What corresponds to the zero-length tuples in Kapulet, OCaml, and Haskell? Perhaps the zero-length `vector`. Or perhaps a different Scheme value, called *void*. Different Scheme implementations display this value in different ways. For example, Racket and Chicken may display it as `#*and*

`... in ...`:
(* OCaml *)
letrec
even = fun x -> if x = 0 then true else odd x
and
odd = fun x -> if x = 0 then false else even x
in ...
Haskell has both of the syntactic forms that Kapulet does, though like OCaml, it uses `=` rather than `match`. And it wraps all the binding clauses with `{ ... }` (see [[earlier remarks|rosetta1#haskell-whitespace]] about Haskell and whitespace/indentation):
-- Haskell
let {
pat1 = expr1;
pat2 = expr2;
pat3 = expr3
} in result
Also, in Haskell `let` always means `letrec`. There is no term in Haskell that means what simple `let` does in Kapulet and OCaml.
Haskell also has another form, roughly synonymous with its `let ... in ...`. It looks like this:
-- Haskell
result where {
pat1 = expr1;
pat2 = expr2;
pat3 = expr3
}
Here all the new bindings introduced for the variables in the `pat`s are in effect for the evaluation of the `expr`s (this works like `letrec` too), and also for the evaluation of `result`.
There are a few places where you can use `let ... in ...` but not `... where ...`, and a few places where the inverse is true.
Scheme has *four (or five)* syntactic forms here, including `let`, `let*`, `letrec`, and `letrec*`. The difference between the last two [is subtle](http://stackoverflow.com/questions/13078165) and only arises in the presence of continuations; you can just use `letrec` for ordinary purposes. I won't try to explain the difference between `let` and `let*` here, except to say this:
1. When there's only a single pattern-binding clause, as in `(let ((var expression)) result)`, `let` and `let*` work the same.
2. When there are multiple pattern-binding clauses, as in `(let ((var1 expression1) (var2 expression2)) result)`, then they work somewhat differently and `let*` is probably the one that works like you're expecting.
The `let*` form is the one that corresponds to `let` in Kapulet. I recommend you get in the habit of just always using `let*` (or `letrec`) in Scheme, instead of `let`.
When you're at the "toplevel" of your program, or of a library/module/compilation-unit (the terminology differs), there is also another syntactic form possible. In Kapulet, you'd write:
# Kapulet
let
pat1 match expr1;
...
end
... # rest of program or library
Notice that this form ends with `end`, not with `in result`. The above is roughly equivalent to:
# Kapulet
let
pat1 match expr1;
...
in ... # rest of program or library
That is, the bindings initiated by the clauses of the `let` construction remain in effect until the end of the program or library. They can of course be "hidden" by subsequent bindings to new variables spelled the same way. The program:
# Kapulet
let
x match 0
end
let
x match 1
end
x
evaluates to `1`, just like:
# Kapulet
let
x match 0
in let
x match 1
in x
does. There's a similar form for `letrec`.
OCaml can do the same:
let
x = 0 ;;
let
x = 1 ;;
x
The double-semicolons are hints to OCaml's "toplevel interpreter" that a syntactic unit has finished. In some contexts they're not needed, but it does no harm to include them if you're not sure.
Haskell's "toplevel interpreter" (ghci) permits a syntactic form that looks superficially quite like these:
let x = 2
x
but under the covers something quite different is happening. (Specifically, you're working "inside the IO Monad", except that in this special context, expressions like `x` that don't evaluate to monadic values are permitted and evaluated. We don't expect that you will understand yet what any of this means.) If you're writing *in a file* that you want Haskell to interpret or compile, on the other hand, you have to do something a bit different (which you can't easily also do at the toplevel in ghci). [[Recall|topics/week1_kapulet_advanced#funct-declarations]] the shortcut by which we permitted:
# Kapulet
let
f match lambda pat1. body1;
g match lambda pat2 pat3. body2
in ...
to be written more concisely as:
# Kapulet
let
f pat1 = body1;
g pat2 pat3 = body2
in ...
OCaml and Haskell permit that same shorthand. And Haskell additionally permits the bare binding clauses of such expressions (that is, without the surrounding `let` and `in`) to occur at the toplevel of files. In other words, a Haskell file can look like this:
-- Haskell file.hs
f pat1 = body1
g pat2 pat3 = body2
...
Note there are no semicolons here. These are called "toplevel declarations" of the functions `f` and `g`. A single function name can have multiple declarations (within a single scoping context), using different patterns:
-- Haskell file.hs
f [] = 0
f (x:xs) = 1 + f xs
defines `f` as a function that returns the length of a single List argument. (You can also do that *inside* Haskell's `let` constructions, too.) This is what corresponds *in Haskell files* to `let ... end` in Kapulet.
Haskell also permits multiple declarations of this sort inside its `let` and `where` constructs, too. Moreover, these declarations can also have [[pattern guards|rosetta1#haskell-guards]], as in:
-- Haskell file.fs
f [] = 0
f (x:xs) | odd x = 1 + f xs
| otherwise = f xs
Scheme has a version of `letrec ... end`, which it writes as `define`. Thus in Scheme this:
; Scheme
(define var1 expr1)
... ; rest of program
evaluates the same as this:
; Scheme
(letrec ((var1 expr1))
... ; rest of program
)
This is what we can call Scheme's [[fifth|rosetta1#five-lets]] form of the `let` family.
Some versions of Scheme permit you also to include `define` inside some (but not all) complex expressions. Thus you can write:
(lambda (x)
(define var1 expr1)
...)
instead of:
(lambda (x)
(letrec ((var1 expr1))
...))
There is no analogue to this in the other languages.
### Further Installments ...
We will expand these comparisons (on separate web pages) as we introduce additional ideas in the course, such as types and monads and continuations.
## 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)
* [Haskell vs Scheme](http://www.reddit.com/r/programming/comments/nq1k/haskell_and_scheme_which_one_and_why/)
## 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:
Scheme | OCaml | Haskell | |

Rosetta Code | Rosetta Code | Rosetta Code | |

PLEAC | PLEAC | PLEAC | |

n/a | langref.org | ||

code codex | code codex | code codex | |

99 problems | 99 problems | 99 problems |