chomp whitespace
authorJim <jim.pryor@nyu.edu>
Thu, 12 Feb 2015 15:14:20 +0000 (10:14 -0500)
committerJim <jim.pryor@nyu.edu>
Thu, 12 Feb 2015 15:14:20 +0000 (10:14 -0500)
_applications.mdwn
_rosetta1.mdwn
_rosetta2.mdwn
_what_is_functional.mdwn
code/lambda.js
code/lambda_evaluator.mdwn
code/monad_library.mdwn
code/parse.js
learning_haskell.mdwn
learning_scheme.mdwn
rosetta1.mdwn

index 37d06d2..339a662 100644 (file)
@@ -9,7 +9,7 @@ We mentioned a number of linguistic and philosophical applications of the tools
 From linguistics
 ----------------
 
 From linguistics
 ----------------
 
-*       Generalized quantifiers are a special case of operating on continuations.  [[!wikipedia Richard_Montague]] analyzed all NPs, including, e.g., proper names, as sets of properties. 
+*       Generalized quantifiers are a special case of operating on continuations.  [[!wikipedia Richard_Montague]] analyzed all NPs, including, e.g., proper names, as sets of properties.
  This gives names and quantificational NPs the same semantic type, which explain why we can coordinate them (*John and everyone*, *Mary or some graduate student*).  So instead of thinking of a name as refering to an individual, which then serves as the argument to a verb phrase, in the Generalized Quantifier conception, the name denotes a higher-order function that takes the verb phrase (its continuation) as an argument.  Montague only continuized
 one syntactic category (NPs), but a more systematic approach would continuize uniformly throughout the grammar.
 See [a paper by me (CB)](http://dx.doi.org/10.1023/A:1022183511876) for detailed discussion.
  This gives names and quantificational NPs the same semantic type, which explain why we can coordinate them (*John and everyone*, *Mary or some graduate student*).  So instead of thinking of a name as refering to an individual, which then serves as the argument to a verb phrase, in the Generalized Quantifier conception, the name denotes a higher-order function that takes the verb phrase (its continuation) as an argument.  Montague only continuized
 one syntactic category (NPs), but a more systematic approach would continuize uniformly throughout the grammar.
 See [a paper by me (CB)](http://dx.doi.org/10.1023/A:1022183511876) for detailed discussion.
@@ -21,7 +21,7 @@ See [a paper by me (CB)](http://dx.doi.org/10.1023/A:1022183511876) for detailed
 *       Anaphora, as in *Everyone's mother loves him* (which says that for every person x, x's mother loves x).  [A paper by CB and Chung-chieh Shan](http://dx.doi.org/10.1007/s10988-005-6580-7) discusses an implementation in terms of delimited continuations.  See also a different implementation in work of [Philippe de Groote](http://ecommons.library.cornell.edu/bitstream/1813/7577/4/salt16_degroote_1_16.pdf).
 
 *      As suggested in class, it is possible to think of the side effects of expressives such as *damn* in *John read the damn book* in terms of control operators such as call/cc in Scheme.
 *       Anaphora, as in *Everyone's mother loves him* (which says that for every person x, x's mother loves x).  [A paper by CB and Chung-chieh Shan](http://dx.doi.org/10.1007/s10988-005-6580-7) discusses an implementation in terms of delimited continuations.  See also a different implementation in work of [Philippe de Groote](http://ecommons.library.cornell.edu/bitstream/1813/7577/4/salt16_degroote_1_16.pdf).
 
 *      As suggested in class, it is possible to think of the side effects of expressives such as *damn* in *John read the damn book* in terms of control operators such as call/cc in Scheme.
-At the end of the seminar we gave a demonstration of modeling [[damn]] using continuations...see the [summary](/damn) for more explanation and elaboration.  In the meantime, you can read a new paper about this idea [here](http://tinyurl.com/cbarker/barker-bernardi-shan-interaction.pdf)---comments welcome. 
+At the end of the seminar we gave a demonstration of modeling [[damn]] using continuations...see the [summary](/damn) for more explanation and elaboration.  In the meantime, you can read a new paper about this idea [here](http://tinyurl.com/cbarker/barker-bernardi-shan-interaction.pdf)---comments welcome.
 
 From philosophy
 ---------------
 
 From philosophy
 ---------------
index 2e6049c..e02b1c1 100644 (file)
@@ -36,7 +36,7 @@ The following site may be useful; it lets you run a Scheme interpreter inside yo
 
                ((foo 2) 3)
 
 
                ((foo 2) 3)
 
-       These functions are "curried". `foo 2` returns a `2`-fooer, which waits for an argument like `3` and then foos `2` to it. `( + ) 2` returns a `2`-adder, which waits for an argument like `3` and then adds `2` to it. For further reading: 
+       These functions are "curried". `foo 2` returns a `2`-fooer, which waits for an argument like `3` and then foos `2` to it. `( + ) 2` returns a `2`-adder, which waits for an argument like `3` and then adds `2` to it. For further reading:
 
 *      [[!wikipedia Currying]]
 
 
 *      [[!wikipedia Currying]]
 
@@ -71,7 +71,7 @@ The following site may be useful; it lets you run a Scheme interpreter inside yo
        But supposing you had constructed appropriate values for `+` and `3` and `2`, you'd place them in the ellided positions in:
 
                (((\three (\two ((... three) two))) ...) ...)
        But supposing you had constructed appropriate values for `+` and `3` and `2`, you'd place them in the ellided positions in:
 
                (((\three (\two ((... three) two))) ...) ...)
-       
+
        In an ordinary imperatival language like C:
 
                int three = 3;
        In an ordinary imperatival language like C:
 
                int three = 3;
@@ -179,7 +179,7 @@ The following site may be useful; it lets you run a Scheme interpreter inside yo
                (let* [(three (+ 1 2))]
                          (let* [(two 2)]
                                   (+ three two)))
                (let* [(three (+ 1 2))]
                          (let* [(two 2)]
                                   (+ three two)))
-       
+
        It was also asked whether the `(+ 1 2)` computation would be performed before or after it was bound to the variable `three`. That's a terrific question. Let's say this: both strategies could be reasonable designs for a language. We are going to discuss this carefully in coming weeks. In fact Scheme and OCaml make the same design choice. But you should think of the underlying form of the `let`-statement as not settling this by itself.
 
        Repeating our starting point for reference:
        It was also asked whether the `(+ 1 2)` computation would be performed before or after it was bound to the variable `three`. That's a terrific question. Let's say this: both strategies could be reasonable designs for a language. We are going to discuss this carefully in coming weeks. In fact Scheme and OCaml make the same design choice. But you should think of the underlying form of the `let`-statement as not settling this by itself.
 
        Repeating our starting point for reference:
@@ -335,7 +335,7 @@ The following site may be useful; it lets you run a Scheme interpreter inside yo
 
                int x = 3;
                x = 2;
 
                int x = 3;
                x = 2;
-       
+
        <em>but it's not the same!</em> In the latter case we have mutation, in the former case we don't. You will learn to recognize the difference as we proceed.
 
        The OCaml expression just means:
        <em>but it's not the same!</em> In the latter case we have mutation, in the former case we don't. You will learn to recognize the difference as we proceed.
 
        The OCaml expression just means:
index 48ac277..d423609 100644 (file)
@@ -463,7 +463,7 @@ The syntax for declaring and using these is a little bit different in the two la
 
                type color = Color of (int * int * int);;
                let c = Color (0, 127, 255);;
 
                type color = Color of (int * int * int);;
                let c = Color (0, 127, 255);;
-       
+
        and then extract the field you want using pattern-matching:
 
                let Color (r, _, _) = c;;
        and then extract the field you want using pattern-matching:
 
                let Color (r, _, _) = c;;
@@ -717,13 +717,13 @@ Haskell has more built-in support for monads, but one can define the monads one
                main = do
                  let s = "hello world"
                  putStrLn s
                main = do
                  let s = "hello world"
                  putStrLn s
-       
+
                main :: IO String
                main = do
                  let s = "hello world"
                  putStrLn s
                  return s
                main :: IO String
                main = do
                  let s = "hello world"
                  putStrLn s
                  return s
-       
+
                main :: IO String
                main = let s = "hello world"
                       in putStrLn s >> return s
                main :: IO String
                main = let s = "hello world"
                       in putStrLn s >> return s
index d6b9354..c17da57 100644 (file)
@@ -245,7 +245,7 @@ Or this:
 In the presence of imperatival elements, sequencing order is very relevant. For example, these will behave differently:
 
        (begin (print "under") (print "water"))
 In the presence of imperatival elements, sequencing order is very relevant. For example, these will behave differently:
 
        (begin (print "under") (print "water"))
-       
+
        (begin (print "water") (print "under"))
 
 And so too these:
        (begin (print "water") (print "under"))
 
 And so too these:
index 83ae7c4..955254b 100644 (file)
@@ -487,10 +487,10 @@ function sub(tree, v, arg) {
   if (tree.car == null) return (tree);
 
   // perform alpha reduction to prevent variable collision
   if (tree.car == null) return (tree);
 
   // perform alpha reduction to prevent variable collision
-  if (isBindingForm(tree)) 
-       return (new cons (tree.car, 
+  if (isBindingForm(tree))
+       return (new cons (tree.car,
                                          sub(sub(tree.cdr,         // inner sub = alpha reduc.
                                          sub(sub(tree.cdr,         // inner sub = alpha reduc.
-                                                         tree.cdr.car.cdr, 
+                                                         tree.cdr.car.cdr,
                                                          fresh(tree.cdr.car.cdr)),
                                                  v,
                                                  arg)));
                                                          fresh(tree.cdr.car.cdr)),
                                                  v,
                                                  arg)));
@@ -504,7 +504,7 @@ var i = 0;
 function fresh(string) {
   i = i+1;
   if (typeof(string) != "string") return (string);
 function fresh(string) {
   i = i+1;
   if (typeof(string) != "string") return (string);
-  return (new cons (null,  
+  return (new cons (null,
                                        string.substring(0,1) + (i).toString()));
 }
 
                                        string.substring(0,1) + (i).toString()));
 }
 
@@ -533,11 +533,11 @@ function mapReduce(tree) {
 function convert(tree) {
        if (isLet(tree)) {
          return (sub(tree.cdr.car, tree.car.cdr.car.cdr, tree.car.cdr.cdr.car));}
 function convert(tree) {
        if (isLet(tree)) {
          return (sub(tree.cdr.car, tree.car.cdr.car.cdr, tree.car.cdr.cdr.car));}
-       else 
+       else
          if (isConvertable(tree)) {
                return (sub(tree.car.cdr.cdr.car, tree.car.cdr.car.cdr, tree.cdr.car));}
          else return(tree);
          if (isConvertable(tree)) {
                return (sub(tree.car.cdr.cdr.car, tree.car.cdr.car.cdr, tree.cdr.car));}
          else return(tree);
-} 
+}
 
 // Is of form ((let var arg) body)?
 function isLet(tree) {
 
 // Is of form ((let var arg) body)?
 function isLet(tree) {
@@ -547,7 +547,7 @@ function isLet(tree) {
   if (tree.cdr == null) return (false);
   if (tree.cdr.car == null) return (false);
   return(true);
   if (tree.cdr == null) return (false);
   if (tree.cdr.car == null) return (false);
   return(true);
-}  
+}
 
 // Is of form ((lambda var body) arg)?
 function isConvertable(tree) {
 
 // Is of form ((lambda var body) arg)?
 function isConvertable(tree) {
@@ -557,14 +557,14 @@ function isConvertable(tree) {
   if (tree.cdr == null) return (false);
   if (tree.cdr.car == null) return (false);
   return(true);
   if (tree.cdr == null) return (false);
   if (tree.cdr.car == null) return (false);
   return(true);
-}  
+}
 
 // Is of form (lambda var body)?
 function isBindingForm(tree) {
   if (tree == null) return (false);
   if (tree.car == null) return (false);
   if (tree.car.car != null) return (false);
 
 // Is of form (lambda var body)?
 function isBindingForm(tree) {
   if (tree == null) return (false);
   if (tree.car == null) return (false);
   if (tree.car.car != null) return (false);
-  if ((tree.car.cdr != "lambda") 
+  if ((tree.car.cdr != "lambda")
          && (tree.car.cdr != "let")
          && (tree.car.cdr != "exists")
          && (tree.car.cdr != "forall")
          && (tree.car.cdr != "let")
          && (tree.car.cdr != "exists")
          && (tree.car.cdr != "forall")
@@ -583,7 +583,7 @@ function isBindingForm(tree) {
 function treeToString(tree) {
   if (tree == null) return ("")
   if (tree.car == null) return (tree.cdr)
 function treeToString(tree) {
   if (tree == null) return ("")
   if (tree.car == null) return (tree.cdr)
-  if ((tree.car).car == null) 
+  if ((tree.car).car == null)
        return (treeToString(tree.car) + " " + treeToString(tree.cdr))
   return ("(" + treeToString(tree.car) + ")" + treeToString(tree.cdr))
 }
        return (treeToString(tree.car) + " " + treeToString(tree.cdr))
   return ("(" + treeToString(tree.car) + ")" + treeToString(tree.cdr))
 }
@@ -592,7 +592,7 @@ function treeToString(tree) {
 function treeToStringRaw(tree) {
   if (tree == null) return ("@")
   if (typeof(tree) == "string") return (tree);
 function treeToStringRaw(tree) {
   if (tree == null) return ("@")
   if (typeof(tree) == "string") return (tree);
-  return ("(" + treeToStringRaw(tree.car) + "." + 
+  return ("(" + treeToStringRaw(tree.car) + "." +
                                treeToStringRaw(tree.cdr) + ")")
 }
 
                                treeToStringRaw(tree.cdr) + ")")
 }
 
@@ -624,7 +624,7 @@ function formatTree(tree) {
   return (output)
 }
 
   return (output)
 }
 
-function mytry(form) { 
+function mytry(form) {
   i = 0;
   form.result.value = formatTree((stringToTree(form.input.value)));
   // form.result.value = formatTree(fixedPoint(stringToTree(form.input.value)));
   i = 0;
   form.result.value = formatTree((stringToTree(form.input.value)));
   // form.result.value = formatTree(fixedPoint(stringToTree(form.input.value)));
index 4e59b7f..2231951 100644 (file)
@@ -1,7 +1,7 @@
 This lambda evaluator will allow you to write lambda terms and evaluate (that is, normalize) them, and inspect the results.
 This lambda evaluator will allow you to write lambda terms and evaluate (that is, normalize) them, and inspect the results.
-(This won't work in Racket, because Racket doesn't even try to represent the internal structure of a function in a human-readable way.)  
+(This won't work in Racket, because Racket doesn't even try to represent the internal structure of a function in a human-readable way.)
 
 
-*Lambda terms*: lambda terms are written with a backslash, thus: `((\x (\y x)) z)`.  
+*Lambda terms*: lambda terms are written with a backslash, thus: `((\x (\y x)) z)`.
 
 If you click "Normalize", the system will try to produce a normal-form lambda expression that your original term reduces to (~~>). So `((\x (\y x)) z)` reduces to `(\y z)`.
 
 
 If you click "Normalize", the system will try to produce a normal-form lambda expression that your original term reduces to (~~>). So `((\x (\y x)) z)` reduces to `(\y z)`.
 
@@ -109,12 +109,12 @@ Under the hood
 ---------------
 
 The interpreter is written in JavaScript and runs inside your browser.
 ---------------
 
 The interpreter is written in JavaScript and runs inside your browser.
-So if you decide to reduce a term that does not terminate (such as `((\x (x x)) (\x (x x)))`), it will be your 
+So if you decide to reduce a term that does not terminate (such as `((\x (x x)) (\x (x x)))`), it will be your
 browser that stops responding, not the wiki server.
 
 The main code is [here](http://lambda.jimpryor.net/code/lambda.js). Suggestions for improvements welcome.
 
 browser that stops responding, not the wiki server.
 
 The main code is [here](http://lambda.jimpryor.net/code/lambda.js). Suggestions for improvements welcome.
 
-The code is based on: 
+The code is based on:
 
 *      Chris Barker's JavaScript lambda calculator
 *      [Oleg Kiselyov's Haskell lambda calculator](http://okmij.org/ftp/Computation/lambda-calc.html#lambda-calculator-haskell).
 
 *      Chris Barker's JavaScript lambda calculator
 *      [Oleg Kiselyov's Haskell lambda calculator](http://okmij.org/ftp/Computation/lambda-calc.html#lambda-calculator-haskell).
index 1761e61..a9418b8 100644 (file)
@@ -132,7 +132,7 @@ Some comments on the design of this library.
                type ('r,'b) m = ('b -> 'r) -> 'r
 
        and there both `'r` and `'b` need to be free type variables. Since we want to allow you to layer Continuation monads with the others, it vastly simplified the library to make all of the monadic types take two type parameters, even though the second will only be used by a Continuation monad you may have stacked in the monadic bundle you're using. You can pretty much ignore this; think of the `S.(unit 1)` as though it just had the type `int S.m`.
                type ('r,'b) m = ('b -> 'r) -> 'r
 
        and there both `'r` and `'b` need to be free type variables. Since we want to allow you to layer Continuation monads with the others, it vastly simplified the library to make all of the monadic types take two type parameters, even though the second will only be used by a Continuation monad you may have stacked in the monadic bundle you're using. You can pretty much ignore this; think of the `S.(unit 1)` as though it just had the type `int S.m`.
-       
+
 
 *      The implementation of most monadic types is **hidden**. Above, when we wanted to supply an `initial_store` to a value `u` of type `('a,'b) S.m`, we did this:
 
 
 *      The implementation of most monadic types is **hidden**. Above, when we wanted to supply an `initial_store` to a value `u` of type `('a,'b) S.m`, we did this:
 
index 5cdeb40..ddc6199 100644 (file)
@@ -306,7 +306,7 @@ var make_parse = function () {
         tokens = source.tokens();
         token_nr = 0;
         advance();
         tokens = source.tokens();
         token_nr = 0;
         advance();
-        
+
         // let n = c in b
         // (\n. b) c
 
         // let n = c in b
         // (\n. b) c
 
@@ -336,7 +336,7 @@ var make_parse = function () {
             target = t;
             advance("in");
         }
             target = t;
             advance("in");
         }
-    
+
         target.second = expression(false);
 
         advance("(end)");
         target.second = expression(false);
 
         advance("(end)");
index 54dd276..28acee6 100644 (file)
 ## Advanced Docs, listed here for reference ##
 
 *   GHC User's Guide from
 ## Advanced Docs, listed here for reference ##
 
 *   GHC User's Guide from
-[Haskell Platform](https://www.haskell.org/platform/doc/2014.2.0.0/ghc/users_guide) | 
+[Haskell Platform](https://www.haskell.org/platform/doc/2014.2.0.0/ghc/users_guide) |
 [latest](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide), including
 [Using GHCi](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html) and
 [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) |
 [latest](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide), including
 [Using GHCi](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html) and
 [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)
 -->
 ([Prelude](https://www.haskell.org/onlinereport/haskell2010/haskellch9.html)) <!--
 [GHC latest bootstrap libraries](https://downloads.haskell.org/~ghc/latest/docs/html/libraries)
 -->
index 2ded2d3..2f92b5e 100644 (file)
@@ -164,7 +164,7 @@ Scheme is a very small language which is based on Lisp, the oldest of functional
     continuations
     macros
 
     continuations
     macros
 
-An excellent place to start is the book: Structure and Interpretation of Computer Programs (considered by some the "bible" of functional programming, which may give a false implication as to its breadth, despite it being a very good book). There are also countless other great books and websites which have been published to answer questions on how to learn Lisp, why to learn Lisp, etc., so searching the web will most certainly be worth your time. 
+An excellent place to start is the book: Structure and Interpretation of Computer Programs (considered by some the "bible" of functional programming, which may give a false implication as to its breadth, despite it being a very good book). There are also countless other great books and websites which have been published to answer questions on how to learn Lisp, why to learn Lisp, etc., so searching the web will most certainly be worth your time.
 -->
 
 <!--
 -->
 
 <!--
index 1c42a13..70866b1 100644 (file)
@@ -215,7 +215,7 @@ Fourth, in Kapulet, `( - 10)` expresses &lambda; `x. x - 10` (consistently with
     ( - 2)         # ( - 2) 10 == 8
     (0 - )
     ( - ) (5, 3)
     ( - 2)         # ( - 2) 10 == 8
     (0 - )
     ( - ) (5, 3)
-    
+
 
 and here are their translations into natural Haskell:
 
 
 and here are their translations into natural Haskell:
 
@@ -779,7 +779,7 @@ Notice that this form ends with `end`, not with `in result`. The above is roughl
       pat1  match expr1;
       ...
     in ... # rest of program or library
       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
 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