add more links to index
[lambda.git] / family_tree_of_functional_programming_languages.mdwn
index 124ebb5..cc2b424 100644 (file)
@@ -1,4 +1,5 @@
-There's no need for you to know this for our seminar. But in case you're interested...
+There's a lot more trivia and links here than anyone needs to know for this seminar. It's
+there for anyone who may be interested.
 
 Others (and ourselves) will often talk about "functional programming
 languages." But it would be more appropriate to talk of functional *paradigms*
@@ -12,9 +13,9 @@ typed and those that are statically typed.
 
 The **dynamically typed** languages give types more of a background role in the
 program. They include the Lisp family (which in turn includes all the variants
-of [[!wikipedia Scheme]], and also [[!wikipedia Common Lisp]], and [[!wikipedia
-Clojure]]). They also include [[!wikipedia Erlang]] and [[!wikipedia Joy]] and
-[[!wikipedia Pure]], and others.
+of [[!wikipedia Scheme (programming language) desc="Scheme"]], and also [[!wikipedia Common Lisp]], and [[!wikipedia
+Clojure]]). They also include [[!wikipedia Erlang (programming language) desc="Erlang"]] and [[!wikipedia Joy (programming language) desc="Joy"]] and
+[[!wikipedia Pure (programming language) desc="Pure"]], and others.
 
 Although these languages are hospitable to functional programming, some of them
 also permit you to write *imperatival* code (that is, code with *side-effects*)
@@ -52,7 +53,7 @@ eliminated. They can't sneak up to bite you unawares while the program is
 running.
 
 Formerly, static typing required the programmer to add lots of annotations in
-her source code explicitly specifying what they type of each function argument
+her source code explicitly specifying what the type of each function argument
 is, what the type of the function's return value was, and so on. This is
 tedious, and partly for this reason dynamically typed languages have become
 popular and are thought of as easier to work with. However, nowadays statically
@@ -74,7 +75,7 @@ like follows:
 
 This just says explicitly that foo takes an argument x of type int, an argument
 y of type float, and returns a pair of type int\*float (that is, a pair whose
-first member is if type int and whose second member is of type float).
+first member is of type int and whose second member is of type float).
 
 Type inference allows programmers to enjoy the benefits of strict compile-time
 type-checking, which as we said, helps eliminate a large class of errors at a
@@ -87,37 +88,42 @@ gets everything sorted out.)
 
 Though as we said dynamically-typed languages have become popular, programmers
 who get used to modern statically-typed languages find them productive.
-Sometimes they become zealots for working this way instead; at any case, they
+Sometimes they become zealots for working this way instead; in any case, they
 say that the popular dim opinion of static typing is based on out-of-date
 experiences of older languages like C and Java.
 
 Most functional programming languages these days are statically typed.
 
-We can further divide these languages based on whether they use *lazy* or
-*strict/eager* evaluation. We'll discuss the difference between these during
+We can further divide these languages based on whether they use lazy or
+strict/eager evaluation. We'll discuss the difference between these during
 the seminar.
 
-Most programming languages, functional or not, use strict/eager evaluation. For
+Most programming languages, functional or not, use **strict/eager evaluation**. For
 instance, languages of the ML family are all statically-typed functional
-languages with strict/eager evaluation. These include [[!wikipedia SML]] and
-[[!wikipedia Caml]] and [[!wikipedia Nemerle]]. Other statically-typed
-functional languages with strict/eager semantics are [[!wikipedia Scala]] and
-[[!wikipedia Coq]]. Like Scheme, many of these languages permit *imperatival*
-as well as functional coding; but they are regarded as functional programming
-languages because they are so hospitable to functional programming, and give it
-a central place in their design.
-
-A few languages such as [[!wikipedia Miranda]] and [[!wikipedia Haskell]] are
-statically-typed languages that instead mostly use lazy evaluation. However,
+languages with strict/eager evaluation. These include [[!wikipedia Standard ML desc="SML"]] and
+[[!wikipedia Caml]] and [[!wikipedia Nemerle]]. SML in turn has several variants
+or implementations: [[!wikipedia MLton]], [[!wikipedia Standard ML of New Jersey desc="SML/NJ"]], [[!wikipedia Moscow ML]],
+and [[!wikipedia Mythryl]]. Microsoft's [[!wikipedia F Sharp (programming language) desc="F#"]]
+is derived from Caml.
+
+Other statically-typed functional languages with strict/eager evaluation are
+[[!wikipedia Scala (programming language) desc="Scala"]] and [[!wikipedia
+Coq]]. Like Scheme, many of these languages permit *imperatival* as well as
+functional coding; but they are regarded as functional programming languages
+because they are so hospitable to functional programming, and give it a central
+place in their design.
+
+A few languages such as [[!wikipedia Miranda (programming language) desc="Miranda"]] and [[!wikipedia Haskell (programming language) desc="Haskell"]] are
+statically-typed languages that instead mostly use **lazy evaluation**. However,
 it'd be more strictly accurate to say Haskell is lazy *by default*. You can
 also make Haskell evaluate some expressions strictly/eagerly; you just have to
-be ask for that explicitly. (I don't know about Miranda.) Languages like OCaml
+ask for that explicitly. (I don't know about Miranda.) Languages like OCaml
 are the reverse: they're strict/eager by default, but you can get lazy
 evaluation where it's needed, you just have to ask for it explicitly.
 
 Unlike OCaml, Haskell is much more extreme about being non-imperatival. Though
 it's possible to write imperative code in Haskell, too; one just has to
-encapsulate it in a ST or IO *monad*. We'll be discussing in the seminar how
+encapsulate it in an "ST" or "IO" *monad*. We'll be discussing in the seminar how
 monads can be used to create purely functional representations of imperatival
 algorithms. (You can do the same in languages like Scheme and OCaml, too.
 What's different is that in Haskell monads are the *only* way to deal with
@@ -126,4 +132,9 @@ imperatival code.)
 We'll talk much more about monads, lazy vs strict evaluation, and functional vs
 imperatival code as we proceed.
 
+We won't much discuss static vs dynamic typing; this has to do with lower-level
+implementation details than we'll be concerned with. However, you'll encounter
+the difference in practice as you work with Scheme and OCaml, respectively; and
+you'll see it referred to as you read around. So it's good for you to
+have placed it in your mental map.