Fundamentals and lambda calculus

Similar documents
Fundamentals and lambda calculus. Deian Stefan (adopted from my & Edward Yang s CSE242 slides)

Introduction to Lambda Calculus. Lecture 7 CS /08/09

CMSC 330: Organization of Programming Languages. Lambda Calculus

Introduction to Lambda Calculus. Lecture 5 CS 565 1/24/08

CMSC 330: Organization of Programming Languages

CMSC 330: Organization of Programming Languages. Lambda Calculus

CMSC 330: Organization of Programming Languages

Lambda Calculus. Lecture 4 CS /26/10

Programming Language Features. CMSC 330: Organization of Programming Languages. Turing Completeness. Turing Machine.

CMSC 330: Organization of Programming Languages

Introduction to the Lambda Calculus

1 Scope, Bound and Free Occurrences, Closed Terms

Type Systems Winter Semester 2006

Pure Lambda Calculus. Lecture 17

5. Introduction to the Lambda Calculus. Oscar Nierstrasz

Chapter 5: The Untyped Lambda Calculus

COMP 1130 Lambda Calculus. based on slides by Jeff Foster, U Maryland

Lecture 5: The Untyped λ-calculus

11/6/17. Outline. FP Foundations, Scheme. Imperative Languages. Functional Programming. Mathematical Foundations. Mathematical Foundations

INF 212 ANALYSIS OF PROG. LANGS LAMBDA CALCULUS. Instructors: Crista Lopes Copyright Instructors.

Lambda Calculus alpha-renaming, beta reduction, applicative and normal evaluation orders, Church-Rosser theorem, combinators

CIS 500 Software Foundations Fall September 25

Introductory Example

Lambda Calculus. Lambda Calculus

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages. Lambda calculus

Recursive Definitions, Fixed Points and the Combinator

CITS3211 FUNCTIONAL PROGRAMMING

Concepts of programming languages

One of a number of approaches to a mathematical challenge at the time (1930): Constructibility

The Lambda Calculus. 27 September. Fall Software Foundations CIS 500. The lambda-calculus. Announcements

The Untyped Lambda Calculus

CS 4110 Programming Languages & Logics. Lecture 17 Programming in the λ-calculus

9/23/2014. Why study? Lambda calculus. Church Rosser theorem Completeness of Lambda Calculus: Turing Complete

CSE 505: Concepts of Programming Languages

Last class. CS Principles of Programming Languages. Introduction. Outline

lambda calculus History 11/28/13 Jianguo Lu A formal system designed to inves:gate func:on defini:on, func:on applica:on, and recursion.

Formal Semantics. Aspects to formalize. Lambda calculus. Approach

Lambda Calculus. Adrian Groza. Department of Computer Science Technical University of Cluj-Napoca

Activity. CSCI 334: Principles of Programming Languages. Lecture 4: Fundamentals II. What is computable? What is computable?

Computer Science 203 Programming Languages Fall Lecture 10. Bindings, Procedures, Functions, Functional Programming, and the Lambda Calculus

CMSC 330: Organization of Programming Languages

Advanced Topics in Programming Languages Lecture 3 - Models of Computation

Foundations. Yu Zhang. Acknowledgement: modified from Stanford CS242

dynamically typed dynamically scoped

λ calculus Function application Untyped λ-calculus - Basic Idea Terms, Variables, Syntax β reduction Advanced Formal Methods

Functions as data. Massimo Merro. 9 November Massimo Merro The Lambda language 1 / 21

Constraint-based Analysis. Harry Xu CS 253/INF 212 Spring 2013

Lambda Calculus. Variables and Functions. cs3723 1

Lambda Calculus and Extensions as Foundation of Functional Programming

The Untyped Lambda Calculus

CMSC330. Objects, Functional Programming, and lambda calculus

VU Semantik von Programmiersprachen

Lambda Calculus-2. Church Rosser Property

CSCI.4430/6969 Programming Languages Lecture Notes

Lambda Calculus. Type Systems, Lectures 3. Jevgeni Kabanov Tartu,

Elixir, functional programming and the Lambda calculus.

From the λ-calculus to Functional Programming Drew McDermott Posted

Denotational Semantics; Lambda Calculus Basics Section and Practice Problems Week 4: Tue Feb 13 Fri Feb 16, 2018

Introduction to the λ-calculus

Untyped Lambda Calculus

Formal Systems and their Applications

Pure (Untyped) λ-calculus. Andrey Kruglyak, 2010

The Untyped Lambda Calculus

CS 242. Fundamentals. Reading: See last slide

Untyped Lambda Calculus

Functional Programming and λ Calculus. Amey Karkare Dept of CSE, IIT Kanpur

CMPUT 325 : Lambda Calculus Basics. Lambda Calculus. Dr. B. Price and Dr. R. Greiner. 13th October 2004

More Lambda Calculus and Intro to Type Systems

Lexicografie computationala Feb., 2012

CS 6110 S14 Lecture 1 Introduction 24 January 2014

CS152: Programming Languages. Lecture 7 Lambda Calculus. Dan Grossman Spring 2011

COMP80 Lambda Calculus Programming Languages Slides Courtesy of Prof. Sam Guyer Tufts University Computer Science History Big ideas Examples:

Functional Programming

Chapter 5: The Untyped Lambda Calculus

The Untyped Lambda Calculus

Lambda Calculus and Type Inference

Part I. Historical Origins

Whereweare. CS-XXX: Graduate Programming Languages. Lecture 7 Lambda Calculus. Adding data structures. Data + Code. What about functions

Lecture Notes on Data Representation

CSC173 Lambda Calculus Lambda Calculus Evaluation (10 min) Evaluate this expression (β-reduce with normal-order evaluation):

A Quick Overview. CAS 701 Class Presentation 18 November Department of Computing & Software McMaster University. Church s Lambda Calculus

Introduction to the Lambda Calculus. Chris Lomont

Implementing functional languages with abstract machines

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

Recursion. Lecture 6: More Lambda Calculus Programming. Fixed Points. Recursion

Fall 2013 Midterm Exam 10/22/13. This is a closed-book, closed-notes exam. Problem Points Score. Various definitions are provided in the exam.

Homework. Lecture 7: Parsers & Lambda Calculus. Rewrite Grammar. Problems

CS-XXX: Graduate Programming Languages. Lecture 9 Simply Typed Lambda Calculus. Dan Grossman 2012

Resources: The slides of this lecture were derived from [Järvi], with permission of the original author, by copy & x = 1 let x = 1 in...

The Lambda Calculus. notes by Don Blaheta. October 12, A little bondage is always a good thing. sk

More Lambda Calculus and Intro to Type Systems

Overview. A normal-order language. Strictness. Recursion. Infinite data structures. Direct denotational semantics. Transition semantics

Programming Languages (CSCI 4430/6430) History, Syntax, Semantics, Essentials, Paradigms

Programming Languages

CS522 - Programming Language Semantics

Functional Programming

Review. CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Let bindings (CBV) Adding Stuff. Booleans and Conditionals

CITS3211 FUNCTIONAL PROGRAMMING. 14. Graph reduction

Basic Foundations of Isabelle/HOL

> module Lambda where > import Data.List -- I need some standard list functions

Transcription:

Fundamentals and lambda calculus

Again: JavaScript functions JavaScript functions are first-class Syntax is a bit ugly/terse when you want to use functions as values; recall block scoping: (function () { //... do something }) (); New version has cleaner syntax called arrow functions Semantics not always the same (this has different meaning), but for this class should always be safe to use

In this lecture

In this lecture

In this lecture

In this lecture λ

What is the lambda calculus? Simplest reasonable programming language Only has one feature: functions

Why study it? Captures the idea of first-class functions Good system for studying the concept of variable binding that appears in almost all languages Historically important Competing model of computation introduced by Church as an alternative to Turing machines: substitution (you ll see this today) = symbolic comp Influenced Lisp (thus JS), ML, Haskell, C++, etc.

Why else? Base for studying many programming languages You can use lambda calculus and extended it in different ways to study languages and features E.g., we can study the difference between strict languages like JavaScript and lazy ones like Haskell λ + evaluation strategy E.g., we can study different kinds of type systems Simply-typed λ calculus, polymorphic, etc.

Why else? Most PL papers describe language models that build on lambda calculus Understanding λ will help you interpret what you are reading in PL research papers Understanding λ will help you get started with other formal/theoretical foundations: Operational semantics Denotational semantics

Before we get started, some terminology Syntax (grammar) The symbols used to write a program E.g., (x + y) is a grammatical expression Semantics The actions that occur when a program is executed PL implementation: Syntax -> Semantics

Before we get started, some terminology Syntax (grammar) The symbols used to write a program E.g., (x + y) is a grammatical expression Semantics The actions that occur when a program is executed PL implementation: Syntax -> Semantics

Before we get started, some terminology Syntax (grammar) The symbols used to write a program E.g., (x + y) is a grammatical expression Semantics The actions that occur when a program is executed PL implementation: Syntax -> Semantics

Week 2 Syntax of λ calculus Semantics of λ calculus Informal substitution Free and bound variables Formal substitution Evaluation order

Lambda calculus Language syntax (grammar): Expressions: e ::= x λx.e e 1 e 2 Variables: x Functions or λ abstractions: λx.e This is the same as x => e in JavaScript! Function application: e 1 e 2 This is the same as e 1 (e2) in JavaScript!

Example terms λx.(2+x) Same as: x => (2 + x) (λx.(2 + x)) 5 Same as: (x => (2 + x)) (5) (λf.(f 3)) (λx.(x + 1)) Same as: (f => (f (3))) (x => (x+1))

Example terms λx.(2+x) LIES! What is this 2 and +? (Sugar.) Same as: x => (2 + x) (λx.(2 + x)) 5 Same as: (x => (2 + x)) (5) (λf.(f 3)) (λx.(x + 1)) Same as: (f => (f (3))) (x => (x+1))

Example terms λx.(2+x) Same as: x => (2 + x) (λx.(2 + x)) 5 Same as: (x => (2 + x)) (5) (λf.(f 3)) (λx.(x + 1)) Same as: (f => (f (3))) (x => (x+1))

Example terms λx.(2+x) Same as: x => (2 + x) (λx.(2 + x)) 5 Same as: (x => (2 + x)) (5) (λf.(f 3)) (λx.(x + 1)) Same as: (f => (f (3))) (x => (x+1))

Example terms λx.(2+x) Same as: x => (2 + x) (λx.(2 + x)) 5 Same as: (x => (2 + x)) (5) (λf.(f 3)) (λx.(x + 1)) Same as: (f => (f (3))) (x => (x+1))

JavaScript to λ calculus Let s look at function composition: (f f)(x) In JavaScript: f => (x => f (f (x))) ((f => (x => f (f (x)))) (x => x+1)) (4) In λ: λf.(λx. f (f x)) ((λf.(λx. f (f x)) (λx.x+1)) 4

JavaScript to λ calculus Let s look at function composition: (f f)(x) In JavaScript: f => (x => f (f (x))) ((f => (x => f (f (x)))) (x => x+1)) (4) In λ: λf.(λx. f (f x)) ((λf.(λx. f (f x)) (λx.x+1)) 4

JavaScript to λ calculus Let s look at function composition: (f f)(x) In JavaScript: f => (x => f (f (x))) ((f => (x => f (f (x)))) (x => x+1)) (4) In λ: λf.(λx. f (f x)) ((λf.(λx. f (f x)) (λx.x+1)) 4

Understanding λ calculus syntax λ-calculus syntax: e ::= x λx.e e 1 e 2 Is λ(x+y). 3 a valid term? (A: yes, B: no) Is λx. 3 a valid term? (A: yes, B: no) Is λx. (x x) a valid term? (A: yes, B: no) Is λx. x (x y) a valid term? (A: yes, B: no)

Understanding λ calculus syntax λ-calculus syntax: e ::= x λx.e e 1 e 2 Is λ(x+y). 3 a valid term? (A: yes, B: no) Is λx. 3 a valid term? (A: yes, B: no) Is λx. (x x) a valid term? (A: yes, B: no) Is λx. x (x y) a valid term? (A: yes, B: no)

Understanding λ calculus syntax λ-calculus syntax: e ::= x λx.e e 1 e 2 Is λ(x+y). 3 a valid term? (A: yes, B: no) Is λx. 3 a valid term? (A: yes, B: no) Is λx. (x x) a valid term? (A: yes, B: no) Is λx. x (x y) a valid term? (A: yes, B: no)

Understanding λ calculus syntax λ-calculus syntax: e ::= x λx.e e 1 e 2 Is λ(x+y). 3 a valid term? (A: yes, B: no) Is λx. 3 a valid term? (A: yes, B: no) Is λx. (x x) a valid term? (A: yes, B: no) Is λx. x (x y) a valid term? (A: yes, B: no)

Understanding λ calculus syntax λ-calculus syntax: e ::= x λx.e e 1 e 2 Is λ(x+y). 3 a valid term? (A: yes, B: no) Is λx. 3 a valid term? (A: yes, B: no) Is λx. (x x) a valid term? (A: yes, B: no) Is λx. x (x y) a valid term? (A: yes, B: no)

More compact syntax Function application is left associative e1 e 2 e 3 (e 1 e 2 ) e 3 Lambdas binds all the way to right: only stop when you find unmatched closing paren ) λx.λy.λz.e λx.(λy.(λz.e)) Why? Lambda abstraction has lowest precedence!

Understanding compact syntax Write the parens: λx.x x A: λx.(x x) B: (λx.x) x

Understanding compact syntax Write the parens: λx.x x A: λx.(x x) B: (λx.x) x

Understanding compact syntax Write the parens: λy.λx.x x = A: λy.(λx.x) x B: λy.(λx.(x x)) C: (λy.(λx.x)) x

Understanding compact syntax Write the parens: λy.λx.x x = A: λy.(λx.x) x B: λy.(λx.(x x)) C: (λy.(λx.x)) x

Understanding compact syntax Is (λy.λx.x) x = λy.λx.x x? A: yes B: no

Understanding compact syntax Is (λy.λx.x) x = λy.λx.x x? A: yes B: no

Parsing rules Applications are left associative Precedence: application > lambda abstraction

Add parentheses λy.λx.x x λz.y λw.w λy.λx.(x x) λz.y λw.w λy.λx.((x x) λz.y) λw.w λy.λx.(((x x) λz.y) λw.w) λy.λx.(((x x) λz.y) (λw.w)) A: λy.λx.(((x x) (λz.y)) (λw.w)) B: λy.λx.(((x x) (λz.y) (λw.w)))

Add parentheses λy.λx.x x λz.y λw.w λy.λx.(x x) λz.y λw.w λy.λx.((x x) λz.y) λw.w λy.λx.(((x x) λz.y) λw.w) λy.λx.(((x x) λz.y) (λw.w)) A: λy.λx.(((x x) (λz.y)) (λw.w)) B: λy.λx.(((x x) (λz.y) (λw.w)))

Add parentheses λy.λx.x x λz.y λw.w λy.λx.(x x) λz.y λw.w λy.λx.((x x) λz.y) λw.w λy.λx.(((x x) λz.y) λw.w) λy.λx.(((x x) λz.y) (λw.w)) A: λy.λx.(((x x) (λz.y)) (λw.w)) First unmatched closing paren B: λy.λx.(((x x) (λz.y) (λw.w)))

Even more compact syntax Can always variables left of the period λx.λy.λz.e λxyz.e This makes the term look like a 3 argument function Can implement multiple-argument function using single-argument functions: called currying (bonus) We won t use this syntax, but you may see in the wild

Week 2 Syntax of λ calculus Semantics of λ calculus Informal substitution Free and bound variables Formal substitution Evaluation order

Semantics of λ calculus Reduce a term to another as much as we can If we can t reduce it any further, the term is said to be in normal form How? Rewrite terms! What does that mean?! Substitution!

Example terms Example: (λx.(2 + x)) 5 (2 + 5) 7 In JavaScript: (x => (2 + x)) (5) (2 + 5) 7 Example: (λf.(f 3)) (λx.(x + 1)) ((λx.(x + 1)) 3) (3 + 1) 4 In JavaScript: (f => (f (3))) (x => (x+1)) ((x => (x+1)) (3) (3+1) 4

Example terms Example: (λx.(2 + x)) 5 (2 + 5) 7 In JavaScript: (x => (2 + x)) (5) (2 + 5) 7 Example: (λf.(f 3)) (λx.(x + 1)) ((λx.(x + 1)) 3) (3 + 1) 4 In JavaScript: (f => (f (3))) (x => (x+1)) ((x => (x+1)) (3) (3+1) 4

Example terms Example: (λx.(2 + x)) 5 (2 + 5) 7 In JavaScript: (x => (2 + x)) (5) (2 + 5) 7 Example: (λf.(f 3)) (λx.(x + 1)) ((λx.(x + 1)) 3) (3 + 1) 4 In JavaScript: (f => (f (3))) (x => (x+1)) ((x => (x+1)) (3) (3+1) 4

Example terms Example: (λx.(2 + x)) 5 (2 + 5) 7 In JavaScript: (x => (2 + x)) (5) (2 + 5) 7 Example: (λf.(f 3)) (λx.(x + 1)) ((λx.(x + 1)) 3) (3 + 1) 4 In JavaScript: (f => (f (3))) (x => (x+1)) ((x => (x+1)) (3) (3+1) 4

Example terms Example: (λx.(2 + x)) 5 (2 + 5) 7 In JavaScript: (x => (2 + x)) (5) (2 + 5) 7 Example: (λf.(f 3)) (λx.(x + 1)) ((λx.(x + 1)) 3) (3 + 1) 4 In JavaScript: (f => (f (3))) (x => (x+1)) ((x => (x+1)) (3) (3+1) 4

Example terms Example: (λx.(2 + x)) 5 (2 + 5) 7 In JavaScript: (x => (2 + x)) (5) (2 + 5) 7 Example: (λf.(f 3)) (λx.(x + 1)) ((λx.(x + 1)) 3) (3 + 1) 4 In JavaScript: (f => (f (3))) (x => (x+1)) ((x => (x+1)) (3) (3+1) 4

Example terms Example: (λx.(2 + x)) 5 (2 + 5) 7 In JavaScript: (x => (2 + x)) (5) (2 + 5) 7 Example: (λf.(f 3)) (λx.(x + 1)) ((λx.(x + 1)) 3) (3 + 1) 4 In JavaScript: (f => (f (3))) (x => (x+1)) ((x => (x+1)) (3) (3+1) 4

Example terms Example: (λx.(2 + x)) 5 (2 + 5) 7 In JavaScript: (x => (2 + x)) (5) (2 + 5) 7 Example: (λf.(f 3)) (λx.(x + 1)) ((λx.(x + 1)) 3) (3 + 1) 4 In JavaScript: (f => (f (3))) (x => (x+1)) ((x => (x+1)) (3) (3+1) 4

Example terms Example: (λx.(2 + x)) 5 (2 + 5) 7 In JavaScript: (x => (2 + x)) (5) (2 + 5) 7 Example: (λf.(f 3)) (λx.(x + 1)) ((λx.(x + 1)) 3) (3 + 1) 4 In JavaScript: (f => (f (3))) (x => (x+1)) ((x => (x+1)) (3) (3+1) 4

Easy! Pattern for function application: substitute the term you are applying the function to for the argument variable

Substitution (not right) Def: Substitution: e 1 [x := e 2 ] Replace every occurrence of x in e1 with e 2 General reduction rule for λ calculus: (λx.e 1 ) e 2 e 1 [x := e 2 ] Function application rewritten to e 1 (the function body) with every x in e 1 substituted with e 2 (argument)

Substitution (not right) Def: Substitution: e 1 [x := e 2 ] Replace every occurrence of x in e1 with e 2 General reduction rule for λ calculus: (λx.e 1 ) e 2 e 1 [x := e 2 ] Function application rewritten to e 1 (the function body) with every x in e 1 substituted with e 2 (argument)

Simple examples Reduce (λx.(2 + x)) 5 (2 + 5) 7 Reduce: (λx.λy.λz.y+3) 4 5 6 = (((λx.λy.λz.y+3) 4) 5) 6 ((λy.λz.y+3) 5) 6 (λz.5+3) 6 (5+3) 8

Simple examples Reduce (λx.(2 + x)) 5 (2 + 5) 7 Reduce: (λx.λy.λz.y+3) 4 5 6 = (((λx.λy.λz.y+3) 4) 5) 6 ((λy.λz.y+3) 5) 6 (λz.5+3) 6 (5+3) 8

Simple examples Reduce (λx.(2 + x)) 5 (2 + 5) 7 Reduce: (λx.λy.λz.y+3) 4 5 6 = (((λx.λy.λz.y+3) 4) 5) 6 ((λy.λz.y+3) 5) 6 (λz.5+3) 6 (5+3) 8

Simple examples (cont) Reduce (λx.(λy.2) 3) 5 (λx. 2) 5 2 Reduce: ((λx.(λy.2)) 3) 5 ((λy.2) 5) 2 Is (λx.(λy.2) 3) 5 = ((λx.(λy.2)) 3) 5? A: yes, B: no

Simple examples (cont) Reduce (λx.(λy.2) 3) 5 (λx. 2) 5 2 Reduce: ((λx.(λy.2)) 3) 5 ((λy.2) 5) 2 Is (λx.(λy.2) 3) 5 = ((λx.(λy.2)) 3) 5? A: yes, B: no

Simple examples (cont) Reduce (λx.(λy.2) 3) 5 (λx. 2) 5 2 Reduce: ((λx.(λy.2)) 3) 5 ((λy.2) 5) 2 Is (λx.(λy.2) 3) 5 = ((λx.(λy.2)) 3) 5? A: yes, B: no

Simple examples (cont) Reduce (λx.(λy.2) 3) 5 (λx. 2) 5 2 Reduce: ((λx.(λy.2)) 3) 5 ((λy.2) 5) 2 Is (λx.(λy.2) 3) 5 = ((λx.(λy.2)) 3) 5? A: yes, B: no

A more complicated example

A more complicated example Reduce the following: (λx. (λa. x + a) 7) 4

A more complicated example Reduce the following: (λx. (λa. x + a) 7) 4 (λa. 4 + a) 7

A more complicated example Reduce the following: (λx. (λa. x + a) 7) 4 (λa. 4 + a) 7 4 + 7

A more complicated example Reduce the following: (λx. (λa. x + a) 7) 4 (λa. 4 + a) 7 4 + 7 11

Let s make this even more fun!

Let s make this even more fun! Instead of 4, let s apply function to (a + 5) (λx. (λa. x + a) 7) (a + 5)

Let s make this even more fun! Instead of 4, let s apply function to (a + 5) (λx. (λa. x + a) 7) (a + 5) (λa. (a + 5) + a) 7

Let s make this even more fun! Instead of 4, let s apply function to (a + 5) (λx. (λa. x + a) 7) (a + 5) (λa. (a + 5) + a) 7 (7 + 5) + 7

Let s make this even more fun! Instead of 4, let s apply function to (a + 5) (λx. (λa. x + a) 7) (a + 5) (λa. (a + 5) + a) 7 (7 + 5) + 7 19

Let s make this even more fun! Instead of 4, let s apply function to (a + 5) (λx. (λa. x + a) 7) (a + 5) (λa. (a + 5) + a) 7 (7 + 5) + 7 19 A: yes, B: no Is this right?

Let s make this even more fun! Instead of 4, let s apply function to (a + 5) (λx. (λa. x + a) 7) (a + 5) (λa. (a + 5) + a) 7 (7 + 5) + 7 19 A: yes, B: no Is this right?

Substitution is surprisingly complex Recall our reduction rule for application: (λx.e 1 ) e 2 e 1 [x := e 2 ] This function application reduces to e 1 (the function body) where every x in e 1 is substituted with e 2 (value we re applying func to) Where did we go wrong? When we substituted: (λx. (λa. x + a) 7) (a + 5) (λa. (a + 5) + a) 7 the a is captured!

Example to do at home

Example to do at home Reduce the following ((λf.(λx. f (f x))) (λx.x+1)) 4

Example to do at home Reduce the following ((λf.(λx. f (f x))) (λx.x+1)) 4 (λx. (λx.x+1) ((λx.x+1) x)) 4

Example to do at home Reduce the following ((λf.(λx. f (f x))) (λx.x+1)) 4 (λx. (λx.x+1) ((λx.x+1) x)) 4 (λx.x+1) ((λx.x+1) 4)

Example to do at home Reduce the following ((λf.(λx. f (f x))) (λx.x+1)) 4 (λx. (λx.x+1) ((λx.x+1) x)) 4 (λx.x+1) ((λx.x+1) 4) (λx.x+1) (4+1)

Example to do at home Reduce the following ((λf.(λx. f (f x))) (λx.x+1)) 4 (λx. (λx.x+1) ((λx.x+1) x)) 4 (λx.x+1) ((λx.x+1) 4) (λx.x+1) (4+1) 4+1+1

Example to do at home Reduce the following ((λf.(λx. f (f x))) (λx.x+1)) 4 (λx. (λx.x+1) ((λx.x+1) x)) 4 (λx.x+1) ((λx.x+1) 4) (λx.x+1) (4+1) 4+1+1 6

Example to do at home

Example to do at home Reduce the following (λf.(λx. f (f x))) (λy.y+x)

Example to do at home Reduce the following (λf.(λx. f (f x))) (λy.y+x) λx. (λy.y+x) ((λy.y+x) x)

Example to do at home Reduce the following (λf.(λx. f (f x))) (λy.y+x) λx. (λy.y+x) ((λy.y+x) x) λx. (λy.y+x) (x+x)

Example to do at home Reduce the following (λf.(λx. f (f x))) (λy.y+x) λx. (λy.y+x) ((λy.y+x) x) λx. (λy.y+x) (x+x) λx. (x+x+x)

Example to do at home Reduce the following (λf.(λx. f (f x))) (λy.y+x) λx. (λy.y+x) ((λy.y+x) x) λx. (λy.y+x) (x+x) λx. (x+x+x)???? that s not a function that adds x to argument two times

Another way to see the problem Syntactic sugar: let x = e 1 in e 2 (λx.e 2 ) e 1 Let syntax makes this easy to see: let x = a + 5 in let x = a + 5 in let a = 7 in let a = 7 in x + a (a + 5) + a Very obviously wrong! But, guess what: your C macro preprocessor does this!

Another way to see the problem Syntactic sugar: let x = e 1 in e 2 (λx.e 2 ) e 1 Let syntax makes this easy to see: let x = a + 5 in let x = a + 5 in let a = 7 in let a = 7 in x + a (a + 5) + a Very obviously wrong! But, guess what: your C macro preprocessor does this!

Fixing the problem How can we fix this? 1.Rename variables! let x = a+5 in let x = a+5 in let x = a+5 in let a = 7 in let a123 = 7 in let a123 = 7 in x + a x + a123 (a+5) + a123 2.Do the dumb substitution!

Fixing the problem How can we fix this? 1.Rename variables! let x = a+5 in let x = a+5 in let x = a+5 in let a = 7 in let a123 = 7 in let a123 = 7 in x + a x + a123 (a+5) + a123 2.Do the dumb substitution!

Fixing the problem How can we fix this? 1.Rename variables! let x = a+5 in let x = a+5 in let x = a+5 in let a = 7 in let a123 = 7 in let a123 = 7 in x + a x + a123 (a+5) + a123 2.Do the dumb substitution!

Why is this the way to go? Def: variable x is bound in λx.(x+y) Can we always rename bound variables? A: yes, B:no Yes! Bound variables are just placeholders Above: x is not special, we could have used z We say they are equivalent: λx.(x+y) =α λz.(z+y) Renaming amounts to converting bound variable names to avoid capture: e.g., λx.(x+y) to λz.(z+y)

Can we rename everything? Can we rename y in λx.(x+y)? (A: yes, B: no) No! We don t know what y may be, so we must keep it as is! Intuition: Can change the name of your function argument variables but not of variables from the outer scope E.g., x. P(x, y) or i {1,,10} x i + y

Can we rename everything? Can we rename y in λx.(x+y)? (A: yes, B: no) No! We don t know what y may be, so we must keep it as is! Intuition: Can change the name of your function argument variables but not of variables from the outer scope E.g., x. P(x, y) or i {1,,10} x i + y

Can we rename everything? Can we rename y in λx.(x+y)? (A: yes, B: no) No! We don t know what y may be, so we must keep it as is! Intuition: Can change the name of your function argument variables but not of variables from the outer scope E.g., x. P(x, y) or i {1,,10} x i + y

Week 2 Syntax of λ calculus Semantics of λ calculus Informal substitution Free and bound variables Formal substitution Evaluation order

Let s think about this more formally

Def: free variables If a variable is not bound by a λ, we say that it is free e.g., y is free in λx.(x+y) is x free? No! A: yes, We B: say no x is bound in λx.(x+y) We can compute the free variables of any term: FV(x) = {x} FV(λx.e) = FV(e) \ {x} think: build out! FV(e 1 e 2 ) = FV(e 1 ) FV(e 2 )

Def: free variables If a variable is not bound by a λ, we say that it is free e.g., y is free in λx.(x+y) is x free? No! A: yes, We B: say no x is bound in λx.(x+y) We can compute the free variables of any term: FV(x) = {x} FV(λx.e) = FV(e) \ {x} think: build out! FV(e 1 e 2 ) = FV(e 1 ) FV(e 2 )

Def: free variables If a variable is not bound by a λ, we say that it is free e.g., y is free in λx.(x+y) is x free? No! A: yes, We B: say no x is bound in λx.(x+y) We can compute the free variables of any term: FV(x) = {x} FV(λx.e) = FV(e) \ {x} think: build out! FV(e 1 e 2 ) = FV(e 1 ) FV(e 2 )

Def: free variables If a variable is not bound by a λ, we say that it is free e.g., y is free in λx.(x+y) is x free? No! We say x is bound in λx.(x+y) We can compute the free variables of any term: FV(x) = {x} FV(λx.e) = FV(e) \ {x} think: build out! FV(e 1 e 2 ) = FV(e 1 ) FV(e 2 )

Def: Capture-avoiding substitution Capture-avoiding substitution: x[x:=e] = e y[x:=e] = y if y x (e1 e 2 )[x := e] = (e 1 [x := e]) (e 2 [ x:= e]) (λx.e 1 )[x := e] = λx.e 1 (λy.e1 )[x := e 2 ] = λy.e 1 [x := e 2 ] if y x and y FV(e 2 ) Why the if? If y is free in e2 this would capture it!

Def: Capture-avoiding substitution Capture-avoiding substitution: x[x:=e] = e y[x:=e] = y if y x (e1 e 2 )[x := e] = (e 1 [x := e]) (e 2 [ x:= e]) (λx.e 1 )[x := e] = λx.e 1 (λy.e1 )[x := e 2 ] = λy.e 1 [x := e 2 ] if y x and y FV(e 2 ) Why the if? If y is free in e2 this would capture it!

Def: Capture-avoiding substitution Capture-avoiding substitution: x[x:=e] = e y[x:=e] = y if y x (e1 e 2 )[x := e] = (e 1 [x := e]) (e 2 [ x:= e]) (λx.e 1 )[x := e] = λx.e 1 (λy.e1 )[x := e 2 ] = λy.e 1 [x := e 2 ] if y x and y FV(e 2 ) Why the if? If y is free in e2 this would capture it!

Def: Capture-avoiding substitution Capture-avoiding substitution: x[x:=e] = e y[x:=e] = y if y x (e1 e 2 )[x := e] = (e 1 [x := e]) (e 2 [ x:= e]) (λx.e 1 )[x := e] = λx.e 1 (λy.e1 )[x := e 2 ] = λy.e 1 [x := e 2 ] if y x and y FV(e 2 ) Why the if? If y is free in e2 this would capture it!

Def: Capture-avoiding substitution Capture-avoiding substitution: x[x:=e] = e y[x:=e] = y if y x (e1 e 2 )[x := e] = (e 1 [x := e]) (e 2 [ x:= e]) (λx.e 1 )[x := e] = λx.e 1 (λy.e1 )[x := e 2 ] = λy.e 1 [x := e 2 ] if y x and y FV(e 2 ) Why the if? If y is free in e2 this would capture it!

Def: Capture-avoiding substitution Capture-avoiding substitution: x[x:=e] = e y[x:=e] = y if y x (e1 e 2 )[x := e] = (e 1 [x := e]) (e 2 [ x:= e]) (λx.e 1 )[x := e] = λx.e 1 (λy.e1 )[x := e 2 ] = λy.e 1 [x := e 2 ] if y x and y FV(e 2 ) Why the if? If y is free in e2 this would capture it!

Def: Capture-avoiding substitution Capture-avoiding substitution: x[x:=e] = e y[x:=e] = y if y x (e1 e 2 )[x := e] = (e 1 [x := e]) (e 2 [ x:= e]) (λx.e 1 )[x := e] = λx.e 1 (λy.e1 )[x := e 2 ] = λy.e 1 [x := e 2 ] if y x and y FV(e 2 ) Why the if? If y is free in e2 this would capture it!

Def: Capture-avoiding substitution Capture-avoiding substitution: x[x:=e] = e y[x:=e] = y if y x (e1 e 2 )[x := e] = (e 1 [x := e]) (e 2 [ x:= e]) (λx.e 1 )[x := e] = λx.e 1 (λy.e1 )[x := e 2 ] = λy.e 1 [x := e 2 ] if y x and y FV(e 2 ) Why the if? If y is free in e2 this would capture it!

Lambda calculus: equational theory α-renaming or α-conversion λx.e = λy.e[x:=y] where y FV(e) β-reduction (λx.e1 ) e 2 = e 1 [x:=e 2 ] η-conversion λx.(e x) = e where x FV(e) We define our relation using these equations!

Back to our example

Back to our example What we should have done: (λx. (λa. x + a) 7) (a + 5)

Back to our example What we should have done: (λx. (λa. x + a) 7) (a + 5) =α (λx. (λb. x + b) 7) (a + 5)

Back to our example What we should have done: (λx. (λa. x + a) 7) (a + 5) =α (λx. (λb. x + b) 7) (a + 5) =β (λb. (a + 5) + b) 7

Back to our example What we should have done: (λx. (λa. x + a) 7) (a + 5) =α (λx. (λb. x + b) 7) (a + 5) =β (λb. (a + 5) + b) 7 =β (a + 5) + 7

Back to our example What we should have done: (λx. (λa. x + a) 7) (a + 5) =α (λx. (λb. x + b) 7) (a + 5) =β (λb. (a + 5) + b) 7 =β (a + 5) + 7 =β a + 12

The to do at home example

The to do at home example What you should have done: (λf.(λx. f (f x)) (λy.y+x)

The to do at home example What you should have done: (λf.(λx. f (f x)) (λy.y+x) =α (λf.(λz. f (f z)) (λy.y+x)

The to do at home example What you should have done: (λf.(λx. f (f x)) (λy.y+x) =α (λf.(λz. f (f z)) (λy.y+x) =β λz. (λy.y+x) ((λy.y+x) z)

The to do at home example What you should have done: (λf.(λx. f (f x)) (λy.y+x) =α (λf.(λz. f (f z)) (λy.y+x) =β λz. (λy.y+x) ((λy.y+x) z) =β λz. (λy.y+x) (z+x)

The to do at home example What you should have done: (λf.(λx. f (f x)) (λy.y+x) =α (λf.(λz. f (f z)) (λy.y+x) =β λz. (λy.y+x) ((λy.y+x) z) =β λz. (λy.y+x) (z+x) =β λz. z+x+x

Week 2 Syntax of λ calculus Semantics of λ calculus Informal substitution Free and bound variables Formal substitution Evaluation order

Evaluation order What should we reduce first in (λx.x) ((λy.y) z)? A: The inner term: (λy.y) z B: The outer term: (λx.x) ((λy.y) z) Does it matter? No! They both reduce to z!

Evaluation order What should we reduce first in (λx.x) ((λy.y) z)? A: The inner term: (λy.y) z B: The outer term: (λx.x) ((λy.y) z) Does it matter? No! They both reduce to z!

Church-Rosser Theorem: If you reduce to a normal form, it doesn t matter what order you do the reductions. This is known as confluence. Does this mean that reduction order doesn t matter for any program? A: yes B: no

Church-Rosser Theorem: If you reduce to a normal form, it doesn t matter what order you do the reductions. This is known as confluence. Does this mean that reduction order doesn t matter for any program? A: yes B: no

Does evaluation order really not matter?

Does evaluation order really not matter? Consider a curious term called Ω Ω (λx.x x) (λx.x x)

Does evaluation order really not matter? Consider a curious term called Ω Ω (λx.x x) (λx.x x) =β (x x)[ x:= (λx.x x)]

Does evaluation order really not matter? Consider a curious term called Ω Ω (λx.x x) (λx.x x) =β (x x)[ x:= (λx.x x)] =β (λx.x x) (λx.x x)

Does evaluation order really not matter? Consider a curious term called Ω Ω (λx.x x) (λx.x x) =β (x x)[ x:= (λx.x x)] =β (λx.x x) (λx.x x) = Ω Deja vu!

Ω Ω Ω Ω Ω Ω (Ω has no normal form)

Does evaluation order really not matter? Consider a function that ignores its argument: (λx.y) What happens when we call it on Ω? (λx.y) Ω

Does evaluation order really not matter? Consider a function that ignores its argument: (λx.y) What happens when we call it on Ω? y (λx.y) Ω

Does evaluation order really not matter? Consider a function that ignores its argument: (λx.y) What happens when we call it on Ω? (λx.y) Ω y (λx.y) Ω

Does evaluation order really not matter? Consider a function that ignores its argument: (λx.y) What happens when we call it on Ω? (λx.y) Ω y (λx.y) Ω y

Does evaluation order really not matter? Consider a function that ignores its argument: (λx.y) What happens when we call it on Ω? (λx.y) Ω y (λx.y) Ω y (λx.y) Ω

Does evaluation order really not matter? Consider a function that ignores its argument: (λx.y) What happens when we call it on Ω? y y y y (λx.y) Ω (λx.y) Ω (λx.y) Ω (λx.y) Ω

Does evaluation order really not matter? Nope! Evaluation order does matter!

Call-by-value Reduce function, then reduce args, then apply e 1 e 2 (λx.e 1 ) e 2 (λx.e 1 ) n e 1 [x:=n] JavaScript s evaluation strategy is call-by-value (ish) What does this program do? (x => 33) ((x => x(x)) (x => x(x))) RangeError: Maximum call stack size exceeded

Call-by-value Reduce function, then reduce args, then apply e 1 e 2 (λx.e 1 ) e 2 (λx.e 1 ) n e 1 [x:=n] JavaScript s evaluation strategy is call-by-value (ish) What does this program do? (x => 33) ((x => x(x)) (x => x(x))) RangeError: Maximum call stack size exceeded

Call-by-value Reduce function, then reduce args, then apply e 1 e 2 (λx.e 1 ) e 2 (λx.e 1 ) n e 1 [x:=n] JavaScript s evaluation strategy is call-by-value (ish) What does this program do? (x => 33) ((x => x(x)) (x => x(x))) RangeError: Maximum call stack size exceeded

Call-by-value Reduce function, then reduce args, then apply e 1 e 2 (λx.e 1 ) e 2 (λx.e 1 ) n e 1 [x:=n] JavaScript s evaluation strategy is call-by-value (ish) What does this program do? (x => 33) ((x => x(x)) (x => x(x))) RangeError: Maximum call stack size exceeded

Call-by-value Reduce function, then reduce args, then apply e 1 e 2 (λx.e 1 ) e 2 (λx.e 1 ) n e 1 [x:=n] JavaScript s evaluation strategy is call-by-value (ish) What does this program do? (x => 33) ((x => x(x)) (x => x(x))) RangeError: Maximum call stack size exceeded

Call-by-name Reduce function then apply e 1 e 2 (λx.e 1 ) e 2 e 1 [x:=e 2 ] Haskell s evaluation strategy is call-by-name It only does what is absolutely necessary! Actually it s call-by-need = call-by-name + sharing

Call-by-name Reduce function then apply e 1 e 2 (λx.e 1 ) e 2 e 1 [x:=e 2 ] Haskell s evaluation strategy is call-by-name It only does what is absolutely necessary! Actually it s call-by-need = call-by-name + sharing

Call-by-name Reduce function then apply e 1 e 2 (λx.e 1 ) e 2 e 1 [x:=e 2 ] Haskell s evaluation strategy is call-by-name It only does what is absolutely necessary! Actually it s call-by-need = call-by-name + sharing

Call-by-name Reduce function then apply e 1 e 2 (λx.e 1 ) e 2 e 1 [x:=e 2 ] Haskell s evaluation strategy is call-by-name It only does what is absolutely necessary! Actually it s call-by-need = call-by-name + sharing

Summary A term may have many redexes (subterms can reduce) Evaluation strategy says which redex to evaluate Evaluation not guaranteed to find normal form Call-by-value: evaluate function & args before β reduce Call-by-name: evaluate function, then β-reduce

Today Syntax of λ calculus Semantics of λ calculus Free and bound variables Substitution Evaluation order

Takeaway λ-calculus is a forma system Simplest reasonable programming language -Ramsey Binders show up everywhere! Know your capture-avoiding substitution!

Bonus!

Recursive functions in λ-calculus Suppose you want to implement factorial in λ-calculus λn. if n 1 then 1 else n * (fac (n-1)) Is this right? A: yes, B: no Why not? fac is not a thing!

Recursive functions in λ-calculus Suppose you want to implement factorial in λ-calculus λn. if n 1 then 1 else n * (fac (n-1)) Is this right? A: yes, B: no Why not? fac is not a thing!

Recursive functions in λ-calculus Suppose you want to implement factorial in λ-calculus λn. if n 1 then 1 else n * (fac (n-1)) Is this right? A: yes, B: no Why not? fac is not a thing!

The Y combinator X

combinator Like Ω, there is a special term Y in lambda calculus Y λf. (λx. f (x x)) (λx. f (x x)) Why is this interesting? It reduces as follows Y f =β f (Y f) =β f (f (Y f)) =β f ( f (Y f) )

combinator Like Ω, there is a special term Y in lambda calculus Y λf. (λx. f (x x)) (λx. f (x x)) Why is this interesting? It reduces as follows Y f =β f (Y f) =β f (f (Y f)) Def: Fixed-point of a function f is a value x such that f x = x =β f ( f (Y f) )

How can we use this? Let s go back to factorial example. f λfac.λn. if n 1 then 1 else n * (fac (n-1)) factorial Y f =β f (Y f) = f factorial = (λfac.λn. if n 1 then 1 else n * (fac (n-1))) factorial =β λn. if n 1 then 1 else n * (factorial (n-1))

How can we use this? Apply as usual: factorial 2 =β (f (Y f)) 2 =β (λn. if n 1 then 1 else n * (factorial (n-1))) 2 =β if 2 1 then 1 else 2 * (factorial (2-1)) =β if 2 1 then 1 else 2 * (factorial 1) =β 2 * (factorial 1)

How can we use this? Apply as usual: =β 2 * (factorial 1) =β 2 * ((f factorial) 1) =β 2 * ((λn. if n 1 then 1 else n * (factorial (n-1))) 1) =β 2 * (if 1 1 then 1 else 1 * (factorial (1-1))) =β 2 * (if 1 1 then 1 else 1 * (factorial 0)) =β 2 * 1 =β 2