diff --git a/out/Stlc.md b/out/Stlc.md index ecc03cca..5d615dea 100644 --- a/out/Stlc.md +++ b/out/Stlc.md @@ -4,762 +4,834 @@ layout : page permalink : /Stlc --- -This chapter defines the simply-typed lambda calculus. +The _lambda-calculus_, first published by the logician Alonzo Church in +1932, is a core calculus with only three syntactic constructs: +variables, abstraction, and application. It embodies the concept of +_functional abstraction_, which shows up in almsot every programming +language in some form (as functions, procedures, or methods). +The _simply-typed lambda calculus_ (or STLC) is a variant of the +lambda calculus published by Church in 1940. It has just the three +constructs above for function types, plus whatever else is required +for base types. Church had a minimal base type with no operations; +we will be slightly more pragmatic and choose booleans as our base type. + +This chapter formalises the STLC (syntax, small-step semantics, and typing rules), +and the next chapter reviews its main properties (progress and preservation). +The new technical challenges arise from the mechanisms of +_variable binding_ and _substitution_. + +We've already seen how to formalize a language with +variables ([Imp]({{ "Imp" | relative_url }})). +There, however, the variables were all global. +In the STLC, we need to handle the variables that name the +parameters to functions, and these are _bound_ variables. +Moreover, instead of just looking up variables in a global store, +we'll need to reduce function applications by _substituting_ +arguments for parameters in function bodies. + +We choose booleans as our base type for simplicity. At the end of the +chapter we'll see how to add numbers as a base type, and in later +chapters we'll enrich STLC with useful constructs like pairs, sums, +lists, records, subtyping, and mutable state. ## Imports
 
-open import Maps using (Id; id; _≟_; PartialMap; module PartialMap)
 open PartialMap using () renaming (_,_↦_ to _,_∶_)
 open import Data.Nat using ()
 open import Data.Maybe using (Maybe; just; nothing)
 open import Relation.Nullary using (Dec; yes; no)
 open import Relation.Binary.PropositionalEquality using (_≡_; _≢_; refl)
 
 
- ## Syntax -Syntax of types and terms. +We have just two types. + * Functions, `A ⇒ B` + * Booleans, `𝔹` +We require some form of base type, because otherwise the set of types +would be empty. Church used a trivial base type `o` with no operations. +For us, it is more convenient to use booleans. Later we will consider +numbers as a base type. + +Here is the syntax of types in BNF. + + A, B, C ::= A ⇒ B | 𝔹 + +And here it is formalised in Agda.
 
-infixr 20 _⇒_
 
 data Type : Set where
   _⇒_ : Type  Type  Type
   𝔹 : Type
 
-
+
+Terms have six constructs. Three are for the core lambda calculus:
+  * Variables, `\` x`
+  * Abstractions, `λ[ x ∶ A ] N`
+  * Applications, `L · M`
+and three are for the base type, booleans:
+  * True, `true`
+  * False, `false`
+  * Conditions, `if L then M else N`
+Abstraction is also called lambda abstraction, and is the construct
+from which the calculus takes its name. 
+
+With the exception of variables, each construct either constructs
+a value of a given type (abstractions yield functions, true and
+false yield booleans) or deconstructs it (applications use functions,
+conditionals use booleans). We will see this again when we come
+to the rules for assigning types to terms, where constructors
+correspond to introduction rules and deconstructors to eliminators.
+
+Here is the syntax of terms in BNF.
+
+
+
+
+
+
+infixl 20 _·_
 infix  15 λ[_∶_]_
 infix  15 if_then_else_
 
 data Term : Set where
   ` : Id  Term
   λ[_∶_]_ : Id  Type  Term  Term
   _·_ : Term  Term  Term
   true : Term
   false : Term
   if_then_else_ : Term  Term  Term  Term
 
 
+Each type introduces its own constructs, which come in pairs, +one to introduce (or construct) values of the type, and one to eliminate +(or deconstruct) them. + +CONTINUE FROM HERE + + + Example terms.
 
-f x : Id
 f  =  id 0
 x  =  id 1
 
 not two : Term 
 not =  λ[ x  𝔹 ] (if ` x then false else true)
 two =  λ[ f  𝔹  𝔹 ] λ[ x  𝔹 ] ` f · (` f · ` x)
 
@@ -769,130 +841,130 @@ Example terms.
 
 
 
-data Value : Term  Set where
   value-λ     :  {x A N}  Value (λ[ x  A ] N)
   value-true  : Value true
   value-false : Value false
 
@@ -902,645 +974,645 @@ Example terms.
 
 
 
-_[_:=_] : Term  Id  Term  Term
 (` x′) [ x := V ] with x  x′
 ... | yes _ = V
 ... | no  _ = ` x′
 (λ[ x′  A′ ] N′) [ x := V ] with x  x′
 ... | yes _ = λ[ x′  A′ ] N′
 ... | no  _ = λ[ x′  A′ ] (N′ [ x := V ])
 (L′ · M′) [ x := V ] =  (L′ [ x := V ]) · (M′ [ x := V ])
 (true) [ x := V ] = true
 (false) [ x := V ] = false
 (if L′ then M′ else N′) [ x := V ] = if (L′ [ x := V ]) then (M′ [ x := V ]) else (N′ [ x := V ])
 
@@ -1550,569 +1622,569 @@ Example terms.
 
 
 
-infix 10 _⟹_ 
 
 data _⟹_ : Term  Term  Set where
   βλ· :  {x A N V}  Value V 
     (λ[ x  A ] N) · V  N [ x := V ]
   ξ·₁ :  {L L′ M} 
     L  L′ 
     L · M  L′ · M
   ξ·₂ :  {V M M′} 
     Value V 
     M  M′ 
     V · M  V · M′
   βif-true :  {M N} 
     if true then M else N  M
   βif-false :  {M N} 
     if false then M else N  N
   ξif :  {L L′ M N} 
     L  L′     
     if L then M else N  if L′ then M else N
 
@@ -2123,665 +2195,665 @@ Example terms.
 
 
 
-infix 10 _⟹*_ 
 infixr 2 _⟹⟨_⟩_
 infix  3 _∎
 
 data _⟹*_ : Term  Term  Set where
   _∎ :  M  M ⟹* M
   _⟹⟨_⟩_ :  L {M N}  L  M  M ⟹* N  L ⟹* N  
 
 reduction₁ : not · true ⟹* false
 reduction₁ =
     not · true
   ⟹⟨ βλ· value-true 
     if true then false else true
   ⟹⟨ βif-true 
     false
   
 
 reduction₂ : two · not · true ⟹* true
 reduction₂ =
     two · not · true
   ⟹⟨ ξ·₁ (βλ· value-λ) 
     (λ[ x  𝔹 ] not · (not · ` x)) · true
   ⟹⟨ βλ· value-true 
     not · (not · true)
   ⟹⟨ ξ·₂ value-λ (βλ· value-true) 
     not · (if true then false else true)
   ⟹⟨ ξ·₂ value-λ βif-true  
     not · false
   ⟹⟨ βλ· value-false 
     if false then false else true
   ⟹⟨ βif-false 
     true
   
 
@@ -2795,683 +2867,683 @@ Much of the above, though not all, can be filled in using C-c C-r and C-c C-s.
 
 
 
-Context : Set
 Context = PartialMap Type
 
 infix 10 _⊢_∶_
 
 data _⊢_∶_ : Context  Term  Type  Set where
   Ax :  {Γ x A} 
     Γ x  just A 
     Γ  ` x  A
   ⇒-I :  {Γ x N A B} 
     Γ , x  A  N  B 
     Γ  λ[ x  A ] N  A  B
   ⇒-E :  {Γ L M A B} 
     Γ  L  A  B 
     Γ  M  A 
     Γ  L · M  B
   𝔹-I₁ :  {Γ} 
     Γ  true  𝔹
   𝔹-I₂ :  {Γ} 
     Γ  false  𝔹
   𝔹-E :  {Γ L M N A} 
     Γ  L  𝔹 
     Γ  M  A 
     Γ  N  A 
     Γ  if L then M else N  A
 
@@ -3481,205 +3553,205 @@ Much of the above, though not all, can be filled in using C-c C-r and C-c C-s.
 
 
 
-typing₁ :   not  𝔹  𝔹
 typing₁ = ⇒-I (𝔹-E (Ax refl) 𝔹-I₂ 𝔹-I₁)
 
 typing₂ :   two  (𝔹  𝔹)  𝔹  𝔹
 typing₂ = ⇒-I (⇒-I (⇒-E (Ax refl) (⇒-E (Ax refl) (Ax refl))))
 
diff --git a/src/Stlc.lagda b/src/Stlc.lagda
index 10ea0dcf..9abc392d 100644
--- a/src/Stlc.lagda
+++ b/src/Stlc.lagda
@@ -30,7 +30,7 @@ we'll need to reduce function applications by _substituting_
 arguments for parameters in function bodies.
 
 We choose booleans as our base type for simplicity.  At the end of the
-chapter we'll see how to add naturals as a base type, and in later
+chapter we'll see how to add numbers as a base type, and in later
 chapters we'll enrich STLC with useful constructs like pairs, sums,
 lists, records, subtyping, and mutable state.
 
@@ -47,7 +47,19 @@ open import Relation.Binary.PropositionalEquality using (_≡_; _≢_; refl)
 
 ## Syntax
 
-We have just two types, function types and booleans.
+We have just two types.
+  * Functions, `A ⇒ B`
+  * Booleans, `𝔹`
+We require some form of base type, because otherwise the set of types
+would be empty. Church used a trivial base type `o` with no operations.
+For us, it is more convenient to use booleans. Later we will consider
+numbers as a base type.
+
+Here is the syntax of types in BNF.
+
+    A, B, C ::= A ⇒ B | 𝔹
+
+And here it is formalised in Agda.
 
 \begin{code}
 infixr 20 _⇒_
@@ -57,11 +69,28 @@ data Type : Set where
   𝔹 : Type
 \end{code}
 
-Each type introduces its own constructs, which come in pairs,
-one to introduce (or construct) values of the type, and one to eliminate
-(or deconstruct) them.
+Terms have six constructs. Three are for the core lambda calculus:
+  * Variables, `\` x`
+  * Abstractions, `λ[ x ∶ A ] N`
+  * Applications, `L · M`
+and three are for the base type, booleans:
+  * True, `true`
+  * False, `false`
+  * Conditions, `if L then M else N`
+Abstraction is also called lambda abstraction, and is the construct
+from which the calculus takes its name. 
+
+With the exception of variables, each construct either constructs
+a value of a given type (abstractions yield functions, true and
+false yield booleans) or deconstructs it (applications use functions,
+conditionals use booleans). We will see this again when we come
+to the rules for assigning types to terms, where constructors
+correspond to introduction rules and deconstructors to eliminators.
+
+Here is the syntax of terms in BNF.
+
+
 
-CONTINUE FROM HERE
 
 \begin{code}
 infixl 20 _·_
@@ -77,6 +106,14 @@ data Term : Set where
   if_then_else_ : Term → Term → Term → Term
 \end{code}
 
+Each type introduces its own constructs, which come in pairs,
+one to introduce (or construct) values of the type, and one to eliminate
+(or deconstruct) them.
+
+CONTINUE FROM HERE
+
+
+
 Example terms.
 \begin{code}
 f x : Id