<<

CS 251 Fall 20192019 CS 251 Fall 20192019 Principles of of Programming Programming Languages Languages Principles of of Programming Programming Languages Languages λ Ben Wood λ Ben Wood CS 251 Part 1: Defining Racket: How to Program Expressions and Bindings via the meta-language of PL definitions

https://cs.wellesley.edu/~cs251/f19/Expressions, Bindings, Meta-language 0 https://cs.wellesley.edu/~cs251/f19/Expressions, Bindings, Meta-language 1

Topics / Goals From AI to language-oriented programming

LISP: List Processing language, 1950s-60s, MIT AI Lab. 1. Basic language forms and evaluation model. Advice Taker: represent logic as data, not just as a program. and programs as data: 2. Foundations of defining syntax and semantics. • Symbolic computation (not just number crunching) – Informal descriptions (English) • Programs that manipulate logic (and run it too) Scheme: child of Lisp, 1970s, MIT AI Lab. – Formal descriptions (meta-language): Still motivated by AI applications, became more "functional" than Lisp. • Grammars for syntax. Important design changes/additions/cleanup: • simpler naming and function treatment • Judgments, inference rules, and derivations • lexical scope for big-step operational semantics. • first-class continuations • tail-call optimization, … 3. Learn Racket. (an opinionated subset) Racket: child of Scheme, 1990s-2010s, PLT group. – Not always idiomatic or the full story. Setup for transition to Standard ML. Revisions to Scheme for: • Rapid implementation of new languages. • Education. Became Racket in 2010.

Expressions, Bindings, Meta-language 2 Expressions, Bindings, Meta-language 3 Defining Racket PL design/implementation: layers

To define each new language feature: – Define its syntax. How is it written? – Define its dynamic semantics as evaluation rules. kernel How is it evaluated? primitive values, Features data types 1. Expressions syntactic sugar • A few today, more to come. 2. Bindings standard libraries 3. That's all! • A couple more advanced features later. user libraries Expressions, Bindings, Meta-language 4 Expressions, Bindings, Meta-language 5

Values Addition expression

Expressions that cannot be evaluated further. Syntax: (+ e1 e2) – Parentheses required: no extras, no omissions. Syntax: – e1 and e2 stand in for any expressions. Numbers: 251 240 301 – Note prefix notation. Note recursive Booleans: #t #f structure! … Examples: (+ 251 240) (+ (+ 251 240) 301) Evaluation: (+ #t 251) Values evaluate to themselves.

Expressions, Bindings, Meta-language 6 Expressions, Bindings, Meta-language 7 Addition expression Not quite! Addition expression

Syntax: (+ e1 e2) Syntax: (+ e1 e2) Note recursive Evaluation: structure! Evaluation: Dynamic type checking 1. Evaluate e1 to a value v1. 1. Evaluate e1 to a value v1. 2. Evaluate e2 to a value v2. 2. Evaluate e2 to a value v2. 3. Return the arithmetic sum of v1 + v2. 3. If v1 and v2 are numbers then return the arithmetic sum of v1 + v2. Otherwise there is a type error.

Expressions, Bindings, Meta-language 8 Expressions, Bindings, Meta-language 9

The language of languages ! A grammar formalizes syntax. Because it pays to be precise. non-terminal Syntax: symbols – Formal grammar notation e ::= v Non-terminal e – Conventions for writing syntax patterns | ( + e e ) has 2 productions, separated by "|". Grammar meta-syntax. terminal symbols

"An expression e is one of: – Any value v – Any addition expression (+ e e) of any two expressions"

Expressions, Bindings, Meta-language 10 Expressions, Bindings, Meta-language 11 Racket syntax so far Notation conventions

Expressions Outside the grammar: e ::= v • Use of a non-terminal symbol, such as e, in syntax | ( + e e ) examples and evaluation rules means any expression matching one of the productions of e in the grammar.

Literal Values • Two uses of e in the same context are aliases; they mean v ::= #f | #t | n the same expression. Number values • Subscripts (or suffixes) distinguish separate instances of a n ::= 0 | 1 | 2 | … single non-terminal, e.g., e1, e2, …, en or e1, e2, …, en.

Expressions, Bindings, Meta-language 12 Expressions, Bindings, Meta-language 13

The language of languages ! Judgments and rules formalize semantics. Because it pays to be precise. Syntax: Judgment e ↓ v means "expression e evaluates to value v." – Formal grammar notation – Conventions for writing syntax patterns It is implemented by inference rules for different cases: Semantics: value rule: v ↓ v [value] – Judgments: addition rule: • formal assertions, like functions if e1 ↓ n1 – Inference rules: and e2 ↓ n2 e1 ↓ n1 and n is the arithmetic sum e2 ↓ n2 • implications between judgments, like cases of functions of n1 and n2 n = n1 + n2 – Derivations: then (+ e1 e2) ↓ n [add] (+ e1 e2) ↓ n • deductions based on rules, like applying functions …

Expressions, Bindings, Meta-language 14 Expressions, Bindings, Meta-language 15 If all premises hold Inference rules then the conclusion holds. Evaluation derivations Axiom (no premises) Inference rule notation and meaning Bar is optional for axioms. An evaluation derivation is a "proof" that an expression Conclusion [value] v ↓ v evaluates to a value using the evaluation rules. Rule name (+ 3 (+ 5 4)) ↓ 12 by the addition rule because:

Number values, not just any values. – 3 ↓ 3 by the value rule, where 3 is a number Models dynamic type checking. – and (+ 5 4) ↓ 9 by the addition rule , where 9 is a number, because: e1 ↓ n1 "v is the arithmetic sum Premises of the numbers n1 and n2." • 5 ↓ 5 by the value rule, where 5 is a number e2 ↓ n2 (not Racket syntax) n = n1 + n2 • and 4 ↓ 4 by the value rule, where 4 is a number Conclusion [add] (+ e1 e2) ↓ n • and 9 is the sum of 5 and 4 Rule name – and 12 is the sum of 3 and 9 .

Expressions, Bindings, Meta-language 16 Expressions, Bindings, Meta-language 17

Evaluation derivations Errors are modeled by “stuck” derivations. Rules defining the evaluation judgment How to evaluate How to evaluate Adding vertical bars e ↓ v [value] helps clarify nesting. v ↓ v (+ #t (+ 5 4))? (+ (+ 1 2) (+ 5 #f))?

↓ e1 ↓ n1 #t n 1 ↓ 1 [value] 3 ↓ 3 [value] e2 ↓ n2 5 ↓ 5 [value] 2 ↓ 2 [value] n = n1 + n2 3 = 1 + 2 5 ↓ 5 [value] [add] 4 ↓ 4 [value] [add] (+ e1 e2) ↓ n 9 = 5 + 4 (+ 1 2) ↓ 3 4 ↓ 4 [value] [add] (+ 5 4) ↓ 9 5 ↓ 5 [value] 9 = 5 + 4 #f ↓ n [add] (+ 5 4) ↓ 9 [add] [add] Stuck. Can’t apply the [add] rule 12 = 3 + 9 [add] because there is no rule that Stuck. Can’t apply the [add] rule (+ 3 (+ 5 4)) ↓ 12 allows #t to evaluate to a number. because there is no rule that allows #t to evaluate to a number.

Expressions, Bindings, Meta-language 18 Expressions, Bindings, Meta-language 19 Other number expressions Conditional if expressions

Similar syntax and evaluation for: Syntax: (if e1 e2 e3) + - * / quotient < > <= >= = Some small differences. Evaluation: Build syntax and evaluation rules for: 1. Evaluate e1 to a value v1. and quotient > 2. If v1 is not the value #f then evaluate e2 and return the result otherwise evaluate e3 and return the result

Expressions, Bindings, Meta-language 20 Expressions, Bindings, Meta-language 21

Evaluation rules for if expressions. if expressions

if expressions are expressions. e1 ↓ v1 e3 is not evaluated! Racket has no "statements!" e2 ↓ v2 v1 is not #f [if nonfalse] (if (< 9 (- 251 240)) (if e1 e2 e3) ↓ v2 (+ 4 (* 3 2)) (+ 4 (* 3 3)))

(+ 4 (* 3 (if (< 9 (- 251 240)) 2 3))) e1 ↓ #f e2 is not evaluated! e3 ↓ v3 (if (if (< 1 2) (> 4 3) (> 5 6)) [if false] (if e1 e2 e3) ↓ v3 (+ 7 8) (* 9 10) Notice: at most one of these rules can have its premises satisfied! Expressions, Bindings, Meta-language 22 Expressions, Bindings, Meta-language 23 if expression evaluation Language design choice: if semantics v1 not required to be a Boolean value Will either of these expressions result in an e1 ↓ v1 error (stuck derivation) when evaluated? e2 ↓ v2 v1 is not #f [if nonfalse] (if e1 e2 e3) ↓ v2 (if (> 251 240) 251 (/ 251 0))

Alternative design (if #f (+ #t 251) 251) e1 ↓ #t e2 ↓ v2 [if true] (if e1 e2 e3) ↓ v2

Expressions, Bindings, Meta-language 24 Expressions, Bindings, Meta-language 25

Variables and environments More Racket syntax

How do we know the value of a variable? Bindings b ::= (define x e) (define x (+ 1 2)) (define y (* 4 x)) Expressions (define diff (- y x)) e ::= v | x | ( + e e ) | … | (if e e e) (define test (< x diff)) (if test (+ (* x y) diff) 17) Literal Values (booleans, numbers) Keep a dynamic environment: v ::= #f | #t | n – A sequence of bindings mapping identifier (variable name) to value. Identifiers (variable names) – “Context” for evaluation, used in evaluation rules. x (see valid identifier explanation)

Expressions, Bindings, Meta-language 26 Expressions, Bindings, Meta-language 27 Dynamic environments Variable reference expressions

Grammar for environment notation: Syntax: x E ::= . (empty environment) x is any identifier | x ⟼ v, E (one binding, rest of environment) where: Evaluation rule: • x is any legal variable identifier Look up x in the current environment, E, and return • v is any value the value, v, to which x is bound. If there is no binding for x, a name error occurs.

Search from most to least recent (left to right). Concrete example: E ⊢ e ↓ v num ⟼ 17, absZero ⟼ -273, true ⟼ #t, .

Abstract example: Revised expression E(x) = v x1 ⟼ v1, x2 ⟼ v2, …, xn ⟼ vn, . evaluation judgment [var] uses environment. E ⊢ x ↓ v

Expressions, Bindings, Meta-language 28 Expressions, Bindings, Meta-language 29

Expression evaluation rules E ⊢ x ↓ v Derivation with environments must pass the environment. E ⊢ v ↓ v [value] E ⊢ e1 ↓ n1 E ⊢ e2 ↓ n2 Let E = test ⟼ #t, diff ⟼ 9, y ⟼ 12, x ⟼ 3 E(x) = v n = n1 + n2 [var] [add] E ⊢ x ↓ v E ⊢(+ e1 e2) ↓ n E ⊢ test ↓ #t [var] E ⊢ x ↓ 3 [var] E ⊢ e1 ↓ v1 E ⊢ e2 ↓ v2 E ⊢ 5 ↓ 5 [value] [mult] v1 is not #f E ⊢(* x 5) ↓ 15 [if nonfalse] E ⊢ (if e1 e2 e3) ↓ v2 E ⊢ diff ↓ 9 [var] [add] E ⊢ (+ (* x 5) diff) ↓ 24 E ⊢ e1 ↓ #f [if nonfalse] E ⊢ (if test (+ (* x 5) diff) 17) ↓ 24 E ⊢ e3 ↓ v3 [if false] E ⊢ (if e1 e2 e3) ↓ v3 Expressions, Bindings, Meta-language 30 Expressions, Bindings, Meta-language 31 define bindings Environment example

; E0 = . Syntax: (define x e) (define x (+ 1 2)) define is a keyword, x is any identifier, e is any expression ; E1 = x ⟼ 3, . (abbreviated x ⟼ 3; write as x --> 3 in text) Evaluation rule: (define y (* 4 x)) 1. Under the current environment, , evaluate to a value E e v. ; E2 = y ⟼ 12, x ⟼ 3 (most recent binding first) 2. Produce a new environment, E', by extending the current (define diff (- y x)) environment, E, with the binding x ⟼ v. ; E3 = diff ⟼ 9, y ⟼ 12, x ⟼ 3 (define test (< x diff)) E ⊢ b ß E' E ⊢ e ↓ v E' = x ⟼ v, E ; E4 = test ⟼ #t, diff ⟼ 9, y ⟼ 12, x ⟼ 3 [define] (if test (+ (* x 5) diff) 17) E ⊢ (define x e) ß E' ; (environment here is still E4)

Expressions, Bindings, Meta-language 32 Expressions, Bindings, Meta-language 33

Racket identifiers Big-step vs. small-step semantics

Most character sequences are allowed as identifiers, except: We defined a big-step operational semantics: evaluate "all at once" – those containing A small-step operational semantics defines step by step evaluation: • whitespace • special characters ()[]{}”,’`;#|\ (- (* (+ 2 3) 9) (/ 18 6)) – identifiers syntactically indistinguishable from numbers (e.g., -45) → (- (* 5 9) (/ 18 6)) → (- 45 (/ 18 6)) Fair game: ! @ $ % ^ & * . - + _ : < = > ? / → (- 45 3) – myLongName, my_long__name, my-long-name – is_a+b

Expressions, Bindings, Meta-language 34 Expressions, Bindings, Meta-language 35