From: Chris Date: Thu, 12 Feb 2015 15:50:55 +0000 (-0500) Subject: added discussion of computation X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=commitdiff_plain;h=31cebc8050836005ee17dd1d20ae81b2ab9afa3c;hp=ee6a2e3f2edbc040298165943d874423d866bbc6 added discussion of computation --- diff --git a/_applications.mdwn b/_applications.mdwn index 37d06d21..339a6622 100644 --- a/_applications.mdwn +++ b/_applications.mdwn @@ -9,7 +9,7 @@ We mentioned a number of linguistic and philosophical applications of the tools 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. @@ -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. -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 --------------- diff --git a/_rosetta1.mdwn b/_rosetta1.mdwn index 2e6049ca..e02b1c18 100644 --- a/_rosetta1.mdwn +++ b/_rosetta1.mdwn @@ -36,7 +36,7 @@ The following site may be useful; it lets you run a Scheme interpreter inside yo ((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]] @@ -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))) ...) ...) - + 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))) - + 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; - + but it's not the same! 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: diff --git a/_rosetta2.mdwn b/_rosetta2.mdwn index 48ac2775..d4236095 100644 --- a/_rosetta2.mdwn +++ b/_rosetta2.mdwn @@ -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);; - + 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 :: 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 diff --git a/_what_is_functional.mdwn b/_what_is_functional.mdwn index d6b9354e..ff9be6ae 100644 --- a/_what_is_functional.mdwn +++ b/_what_is_functional.mdwn @@ -89,7 +89,7 @@ Scheme (imperative part)
OCaml (imperative part) untyped lambda calculus
-combinatorial logic +combinatory logic --------------------------------------------------- Turing complete --------------------------------------------------- @@ -191,7 +191,7 @@ Scheme (imperative part)
OCaml (imperative part) untyped lambda calculus
-combinatorial logic +combinatory logic --------------------------------------------------- Turing complete --------------------------------------------------- @@ -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")) - + (begin (print "water") (print "under")) And so too these: diff --git a/code/lambda.js b/code/lambda.js index 83ae7c4a..955254bf 100644 --- a/code/lambda.js +++ b/code/lambda.js @@ -487,10 +487,10 @@ function sub(tree, v, arg) { 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. - tree.cdr.car.cdr, + tree.cdr.car.cdr, 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); - return (new cons (null, + return (new cons (null, 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));} - else + else 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) { @@ -547,7 +547,7 @@ function isLet(tree) { 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) { @@ -557,14 +557,14 @@ function isConvertable(tree) { 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); - if ((tree.car.cdr != "lambda") + if ((tree.car.cdr != "lambda") && (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) - if ((tree.car).car == null) + if ((tree.car).car == null) 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); - return ("(" + treeToStringRaw(tree.car) + "." + + return ("(" + treeToStringRaw(tree.car) + "." + treeToStringRaw(tree.cdr) + ")") } @@ -624,7 +624,7 @@ function formatTree(tree) { 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))); diff --git a/code/lambda_evaluator.mdwn b/code/lambda_evaluator.mdwn index 4e59b7fe..22319519 100644 --- a/code/lambda_evaluator.mdwn +++ b/code/lambda_evaluator.mdwn @@ -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 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)`. @@ -109,12 +109,12 @@ Under the hood --------------- 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. -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). diff --git a/code/monad_library.mdwn b/code/monad_library.mdwn index 1761e61c..a9418b80 100644 --- a/code/monad_library.mdwn +++ b/code/monad_library.mdwn @@ -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`. - + * 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: diff --git a/code/parse.js b/code/parse.js index 5cdeb40e..ddc6199e 100644 --- a/code/parse.js +++ b/code/parse.js @@ -306,7 +306,7 @@ var make_parse = function () { tokens = source.tokens(); token_nr = 0; advance(); - + // let n = c in b // (\n. b) c @@ -336,7 +336,7 @@ var make_parse = function () { target = t; advance("in"); } - + target.second = expression(false); advance("(end)"); diff --git a/content.mdwn b/content.mdwn index d725c61c..aaab7a51 100644 --- a/content.mdwn +++ b/content.mdwn @@ -57,7 +57,7 @@ Week 3: * More on Lists Introduces list comprehensions, discusses how to get the `tail` of lists in the Lambda Calculus -* [[Combinatorial Logic|topics/week3 combinatory logic]] +* [[Combinatory Logic|topics/week3 combinatory logic]] * Reduction Strategies and Normal Forms * Homework for week 3 diff --git a/exercises/_assignment2_answers.mdwn b/exercises/_assignment2_answers.mdwn index bb3b724f..dac7f123 100644 --- a/exercises/_assignment2_answers.mdwn +++ b/exercises/_assignment2_answers.mdwn @@ -53,11 +53,11 @@ In Racket, these functions can be defined like this: 15. Define a `neg` operator that negates `true` and `false`. - Expected behavior: + Expected behavior: (((neg true) 10) 20) - evaluates to `20`, and + evaluates to `20`, and (((neg false) 10) 20) diff --git a/exercises/assignment2.mdwn b/exercises/assignment2.mdwn index dff7cc23..9eaa205e 100644 --- a/exercises/assignment2.mdwn +++ b/exercises/assignment2.mdwn @@ -51,11 +51,11 @@ In Racket, these functions can be defined like this: 15. Define a `neg` operator that negates `true` and `false`. - Expected behavior: + Expected behavior: (((neg true) 10) 20) - evaluates to `20`, and + evaluates to `20`, and (((neg false) 10) 20) diff --git a/exercises/assignment3.mdwn b/exercises/assignment3.mdwn index 21997eeb..95450217 100644 --- a/exercises/assignment3.mdwn +++ b/exercises/assignment3.mdwn @@ -24,7 +24,7 @@ 8. Recall our proposed encoding for the numbers, called "Church's encoding". As we explained last week, it's similar to our proposed encoding of lists in terms of their folds. In last week's homework, you defined `succ` for numbers so encoded. Can you now define `pred` in the Lambca Calculus? Let `pred 0` result in whatever `err` is bound to. This is challenging. For some time theorists weren't sure it could be done. (Here is [some interesting commentary](http://okmij.org/ftp/Computation/lambda-calc.html#predecessor).) However, in this week's notes we examined one strategy for defining `tail` for our chosen encodings of lists, and given the similarities we explained between lists and numbers, perhaps that will give you some guidance in defining `pred` for numbers. -9. Define `leq` for numbers (that is, ≤) in the Lambda Calculus. Here is the expected behavior, +9. Define `leq` for numbers (that is, ≤) in the Lambda Calculus. Here is the expected behavior, where `one` abbreviates `succ zero`, and `two` abbreviates `succ (succ zero)`. leq zero zero ~~> true @@ -40,7 +40,7 @@ where `one` abbreviates `succ zero`, and `two` abbreviates `succ (succ zero)`. You'll need to make use of the predecessor function, but it's not essential to understanding this problem that you have successfully implemented it yet. You can treat it as a black box. -## Combinatorial Logic +## Combinatory Logic Reduce the following forms, if possible: @@ -53,7 +53,7 @@ Reduce the following forms, if possible: -16. Give Combinatorial Logic combinators (that is, expressed in terms of `S`, `K`, and `I`) that behave like our boolean functions. You'll need combinators for `true`, `false`, `neg`, `and`, `or`, and `xor`. +16. Give Combinatory Logic combinators (that is, expressed in terms of `S`, `K`, and `I`) that behave like our boolean functions. You'll need combinators for `true`, `false`, `neg`, `and`, `or`, and `xor`. Using the mapping specified in this week's notes, translate the following lambda terms into combinatory logic: @@ -75,8 +75,8 @@ Evaluation strategies in Combinatory Logic Calculus. Call it Skomega. 24. Are there evaluation strategies in CL corresponding to leftmost -reduction and rightmost reduction in the lambda calculus? -What counts as a redex in CL? +reduction and rightmost reduction in the lambda calculus? +What counts as a redex in CL? 25. Consider the CL term K I Skomega. Does leftmost (alternatively, rightmost) evaluation give results similar to the behavior of K I diff --git a/index.mdwn b/index.mdwn index 5bddb85b..9fd9d69d 100644 --- a/index.mdwn +++ b/index.mdwn @@ -103,7 +103,7 @@ The [[differences between our made-up language and Scheme, OCaml, and Haskell|ro (**Week 3**) Thursday 12 February 2015 > Topics: More on Lists (in progress); -Combinatorial Logic (in progress); +Combinatory Logic (in progress); Reduction Strategies and Normal Forms (in progress); Homework (in progress) diff --git a/learning_haskell.mdwn b/learning_haskell.mdwn index 54dd276c..28acee69 100644 --- a/learning_haskell.mdwn +++ b/learning_haskell.mdwn @@ -52,13 +52,13 @@ ## 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) | -[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)) diff --git a/learning_scheme.mdwn b/learning_scheme.mdwn index 2ded2d37..2f92b5ed 100644 --- a/learning_scheme.mdwn +++ b/learning_scheme.mdwn @@ -164,7 +164,7 @@ Scheme is a very small language which is based on Lisp, the oldest of functional 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. -->