Reference Dynamically Typed Programming Languages Practical Foundations for Programming Languages, 2/e, “Part VI: Dynamic Types” , by Part 1: The Untyped λ -Calculus Robert Harper, Cambridge University Press, 2016, pages 183–210. https://www.cs.cmu.edu/%7Erwh/pfpl/2nded.pdf Note: Harper doesn’t much care for “dynamically typed languages” and his criticisms are dead Jim Royer on, but these languages do have some advantages. Lambda calculus definition , from Wikipedia. CIS 352 https://en.wikipedia.org/wiki/Lambda_calculus_definition April 16, 2019 Royer Dynamically Typed Programming Languages 1 / 22 Royer Dynamically Typed Programming Languages 2 / 22 Important!!! dynamically typed �≡ dynamically scoped Dynamically typed roughly means The λ -Calculus we may not find out the type of a value until runtime. Dynamically scoped roughly means we may not find out a variable’s binding until runtime. Dynamically Typed Programming Languages include: Lisp, Scheme, Racket, Python, Clojure, Erlang, JavaScript, Julia, Lua, Perl, R, Ruby, Smalltalk, ... (See https://en.wikipedia.org/wiki/Dynamic_programming_language#Examples .) The “premier example” is the (untyped) λ -calculus. Royer Dynamically Typed Programming Languages 3 / 22 Royer Dynamically Typed Programming Languages 4 / 22
The λ -Calculus: Beginnings The λ -Calculus: Beginnings Alonzo Church originally developed the λ -calculus Alonzo Church originally developed the λ -calculus as part of a grand formalism for the foundations of as part of a grand formalism for the foundations of mathematics. mathematics. But ... But . . . Stephen Kleene and Barkely Rosser showed that system was inconsistent. So . . . Royer Dynamically Typed Programming Languages 5 / 22 Royer Dynamically Typed Programming Languages 5 / 22 The λ -Calculus: Beginnings The λ -Calculus: Beginnings Alonzo Church originally developed the λ -calculus Alonzo Church originally developed the λ -calculus as part of a grand formalism for the foundations of as part of a grand formalism for the foundations of mathematics. mathematics. But ... But . . . Stephen Kleene and Barkely Rosser showed that Stephen Kleene and Barkely Rosser showed that system was inconsistent. system was inconsistent. So ... So . . . The formalism was cut back to the part that was The formalism was cut back to the part that was about defining functions, λ -calculus. about defining functions, λ -calculus. Amazingly ... Amazingly . . . The λ -calculus turns out to be Turing-complete . Why “amazingly”? Royer Dynamically Typed Programming Languages 5 / 22 Royer Dynamically Typed Programming Languages 5 / 22
The λ -Calculus: Beginnings Definitions, 1 Alonzo Church originally developed the λ -calculus Concrete Syntax ∗ as part of a grand formalism for the foundations of mathematics. E :: = X (variable occurrence) But ... | ( E E ) (function application) Stephen Kleene and Barkely Rosser showed that | λ X . E (function abstraction) system was inconsistent. So ... X :: = identifiers The formalism was cut back to the part that was ∗ Note: about defining functions, λ -calculus. Amazingly ... We sometimes add extra parens around lambda-expressions. E.g., we can write (( λ x . ( y x )) z ) for ( λ x . ( y x ) z ) . The λ -calculus turns out to be Turing-complete . Why “amazingly”? Also, by convention application associates to the left. E.g., we can write w x y z for ((( w x ) y ) z ) as in Haskell. Because on the surface there is not very much to the Harper uses a LISPy concrete syntax for λ x . e . E.g.: λ ( x ) e λ -calculus. Royer Dynamically Typed Programming Languages 5 / 22 Royer Dynamically Typed Programming Languages 6 / 22 Free and bound variables Computations Definition E :: = X | ( E E ) | λ X . E An expression of the form: (( λ x . e 0 ) e 1 ) is called a β -redex . (( λ x . e 0 ) e 1 ) β -reduces to e 0 [ e 1 / x ] . Abstract Syntax (in Haskell) e β -reduces to e ′ when e ′ is the result of replacing some subexpression of e of the form type Name = String (( λ x . e 0 ) e 1 ) with e 0 [ e 1 / x ] . data Exp = Id Name | App Exp Exp | Lam Name Exp e is in β -normal form when it contains no β -redexes. App Examples (( λ x . ( plus x z )) y ) → β ( plus y z ) (( λ w . ( plus w z )) ( times x y )) → β ( plus ( times x y ) z ) I B F F (( λ x . ( x z )) x ) Lam x Id x (( λ x . ( λ z . ( plus x z ))) y ) → β ( λ z . ( plus y z )) (( λ x . ( λ y . ( plus x y ))) y ) �→ β ( λ y . ( plus y y )) variable capture!! App (( λ x . ( λ y . ( plus x y ))) y ) → β ( λ z . ( plus y z )) I = binding occurrence ( x ( λ y . y )) �→ β anything as it is in normal form B = bound occurence F = free occurence Id x Id z Ω = def (( λ x . ( x x )) ( λ x . ( x x ))) → β (( λ x . ( x x )) ( λ x . ( x x ))) = Ω Royer Dynamically Typed Programming Languages 7 / 22 Royer Dynamically Typed Programming Languages 8 / 22
β -reduction’s less glamorous siblings Normal Order Evaluation (think preorder) The Normal Order Evaluation Strategy Always do the leftmost possible beta-reduction. Repeat until (if ever) you reach a normal form. [Draw the parse tree!] α -conversion (Bound vars don’t mater for meaning) λ x . e ≡ α λ y . ( e [ y / x ]) where x � = y . Normal Order Evaluation Strategy is equivalent to: (I.e., Renaming bound vars doesn’t change meaning.) function nor ( M ) if M = (( λ x . N ) P ) then nor ( N [ P / x ]) then nor ( ( N ′ P ) ) else if M = ( N P ) & N → n . o . N ′ η -conversion (Extensionality) else if M = ( N P ) & P → n . o . P ′ then nor ( ( N P ′ ) ) (( λ x . e ) x ) ≡ η e when x / ∈ freeVars ( e ) . & N → n . o . N ′ then nor ( λ x . N ′ ) else if M = λ x . N ( ‡ ) (I.e., λ -terms producing the same result on all args are equivalent.) else (* M is in β -n.f. *) return M Theorem If e has a normal form, normal order evaluation will eventually reach it. (‡) Drop this line to get to call-by-name . Royer Dynamically Typed Programming Languages 9 / 22 Royer Dynamically Typed Programming Languages 10 / 22 Applicative Order Evaluation (think postorder) Aside: Are there other evaluation strategies? The Applicative Order Evaluation Strategy Always do the innermost (to the left) possible beta-reduction. Repeat until (if ever) you run out of beta-redexes. [Draw the parse tree!] Normal Order Evaluation Strategy is equivalent to: More than you want to know. For starts, see: function nor ( M ) then nor ( ( N ′ P ) ) M = ( N P ) & N → n . o . N ′ if https://en.wikipedia.org/wiki/Evaluation_strategy else if M = ( N P ) & P → n . o . P ′ then nor ( ( N P ′ ) ) else if M = (( λ x . N ) P ) then nor ( N [ P / x ]) & N → n . o . N ′ then nor ( λ x . N ′ ) else if M = λ x . N ( ‡ ) else (* M is in β -n.f. *) return M Fact If e has a normal form, applicative order evaluation may not find it. (‡) Drop this line to get to call-by-value . Royer Dynamically Typed Programming Languages 11 / 22 Royer Dynamically Typed Programming Languages 12 / 22
The λ -calculus as a RISC assembly language, 1 The λ -calculus as a RISC assembly language, 2 Church Numerals Church Booleans Church Pairs c 0 = def λ s . λ z . z true = def λ t . λ f . t c 1 = def λ s . λ z . ( s z ) pair = def λ f . λ s . λ b . (( b f ) s ) “Object oriented integers” false = def λ t . λ f . f c 2 = def λ s . λ z . ( s ( s z )) fst = def λ p . ( p true ) specify what successor ( s ) is test = def λ b . λ m . λ n . (( l m ) n ) c 3 = def λ s . λ z . ( s ( s ( s z ))) snd = def λ p . ( p false ) specify what zero ( z ) is and = def λ b . λ c . (( b c ) false ) . . . c n = apply s n -times to z Examples Examples successor = def λ n . λ s . λ z . ( s ( n s z )) fst ( pair u v ) → ∗ predecessor is difficult β u test true u v → ∗ β u ( pred c 0 → β c 0 & plus = def λ m . λ n . λ s . λ z . m s ( n s z ) snd ( pair u v ) → ∗ β u pred c n + 1 → β c n ) test false u v → ∗ β v times = def λ m . λ n . ( m ( plus n ) c 0 ) and true true → ∗ β true . . . and false true → ∗ β false . Y = def λ f . ( λ x . f ( x x ))( λ x . f ( x x )) . . Royer Dynamically Typed Programming Languages 13 / 22 Royer Dynamically Typed Programming Languages 14 / 22 From Barendregt’s Impact of the Lambda calculus From Barendregt’s Impact of the Lambda calculus Kleene did find a way to lambda de- Kleene did find a way to lambda de- fine the predecessor function in the un- fine the predecessor function in the un- typed lambda calculus, by using an typed lambda calculus, by using an appropriate data type (pairs of inte- appropriate data type (pairs of inte- gers) as auxiliary device. In [69], he gers) as auxiliary device. In [69], he described how he found the solution described how he found the solution while being anesthetized by laughing while being anesthetized by laughing gas (N 2 O) for the removal of four wis- gas (N 2 O) for the removal of four wis- dom teeth. dom teeth. http://www-users.mat.umk.pl/~adwid/materialy/doc/church.pdf http://www-users.mat.umk.pl/~adwid/materialy/doc/church.pdf So yes, drugs were involved in all of this. Royer Dynamically Typed Programming Languages 15 / 22 Royer Dynamically Typed Programming Languages 15 / 22
Recommend
More recommend