Slide 1

Slide 1 text

Presented by Shriram Krishnamurthi Brown University

Slide 2

Slide 2 text

What is this paper about? We have sharp, mathematical distinctions between some classes of language features These offer advice to language designers Beyond a point (the “Turing Threshold”), we have none…

Slide 3

Slide 3 text

A Little Personal History

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

What’s Expressive?

Slide 6

Slide 6 text

L + F

Slide 7

Slide 7 text

Loop/Function-Free Language + Loops

Slide 8

Slide 8 text

while language + for

Slide 9

Slide 9 text

for language + while

Slide 10

Slide 10 text

Regular language + Context-free grammar

Slide 11

Slide 11 text

Two-Armed if + Multi-Armed if

Slide 12

Slide 12 text

Pure Language + State

Slide 13

Slide 13 text

Language w/ binary – + Unary –

Slide 14

Slide 14 text

Language w/out Exceptions + halt

Slide 15

Slide 15 text

Does F add expressive power to L? L L + F

Slide 16

Slide 16 text

Intuition: something about compilation If we can translate/compile L + F down to L, F is probably not expressive…

Slide 17

Slide 17 text

JavaScript x86 (Church) (Turing)

Slide 18

Slide 18 text

The genius of this paper: Extracting us from the “Turing tar-pit” (Perlis)

Slide 19

Slide 19 text

Better intuition: local translation “local” means “nobody else needs to know” Essentially, simple Lispy macro systems (The Las Vegas principle) (for i lo hi body) è (define i lo) (while (< i hi) body (increment i))

Slide 20

Slide 20 text

x + 2 [x*x | x <- l] x or y x.__add__(2) map (\x -> x*x) l let t = x in if t then t else y

Slide 21

Slide 21 text

Two Sides of Expressiveness

Slide 22

Slide 22 text

When is F not expressive relative to L? L L + F

Slide 23

Slide 23 text

When a macro for F to L exists! Given semantics for L and L + F, for all programs P in L + F: say PL (in L) is the result of “expanding” F then P (in L + F) is “equal” to PL (in L)

Slide 24

Slide 24 text

When is F expressive relative to L? L L + F

Slide 25

Slide 25 text

Need to show that no macro can possibly exist That is the interesting part of this paper! Both parts rely on a definition of “equality”

Slide 26

Slide 26 text

Equality is Hard

Slide 27

Slide 27 text

But first… * “closed terms” “capture-free substitution” “program contexts”

Slide 28

Slide 28 text

Equality is hard… Counterpoint: equality is easy! For two expressions e1 and e2 , run(e1 ) à v1 run(e2 ) à v2 compare v1 and v2

Slide 29

Slide 29 text

Comparing as strings What about 1 and 0.9999999…?

Slide 30

Slide 30 text

What about functions? (λ (x) (* 2 x)) (λ (x) (+ x x))

Slide 31

Slide 31 text

What about free variables? (* x 3) (+ x x x)

Slide 32

Slide 32 text

What about closures? Not just code, also environments, etc.

Slide 33

Slide 33 text

What if you can measure running time? power consumption? …

Slide 34

Slide 34 text

These aren’t just #TheoryWorldProblems… Every compiler optimization needs to replace terms with ones “equal” to them

Slide 35

Slide 35 text

Observational equivalence Is there a way in the language of telling the two answers apart? If so, some program might use it!

Slide 36

Slide 36 text

E :: = v | c | (op E …) | (E E …) | (λ (v …) E) A context C[•] is an expression E with some sub-expression replaced with a • (+ 1 •) (f x • y) (λ (x) (+ x •)) What are all the ways of using a piece of code in a program? We’ll treat ourselves to more language…

Slide 37

Slide 37 text

For all contexts C, if C[e1 ] = C[e2 ], e1 ≅ e2 Can you in code (i.e., with a context): • … tell apart 1 and 0.999…? • … inspect program source? • … measure time/power? more “observations” è fewer equivalences

Slide 38

Slide 38 text

Even more general definition: e1 ≅ e2 if, for all contexts C, C[e1 ] halts iff C[e2 ] halts A small “trick”: programs with errors don’t terminate Ω is a canonical non-terminating term

Slide 39

Slide 39 text

e1 ≅A e2 if, for all contexts C in language A, C[e1 ] halts iff C[e2 ] halts

Slide 40

Slide 40 text

Is this okay? Doesn’t this imply 5 ≅ 6? C[•] ≜ (if (=? • 5) “halt” Ω) The definition is for all contexts, and that’s one of ’em!

Slide 41

Slide 41 text

What if the language doesn’t have any way of telling 5 and 6 apart? What if (=? • 5) is not a language operation? Maybe it has only 0? C[•] ≜ (if (0? (- • 5)) “halt” Ω)

Slide 42

Slide 42 text

Back to Expressiveness!

Slide 43

Slide 43 text

Motivation for the definition Suppose we have 3 ≅L (+ 1 2) Could adding F0 leave 3 ≅L + F0 (+ 1 2)? Could an F1 leave all ≅L pairs ≅L + F1 ? Could adding F2 make 3 ≆L + F2 (+ 1 2)?

Slide 44

Slide 44 text

Key Theorem Suppose F can be written as a local macro Then for all e1 and e2 such that e1 ≅L e2 , e1 ≅L + F e2 That is, F has not added power to L

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

How to show expressiveness? Start with L terms e1 and e2 such that e1 ≅L e2 If we can find a C in L + F that can distinguish e1 from e2 (i.e., e1 ≆L + F e2 ) Then, F has added power to L (and can’t be expressed as a local macro)

Slide 47

Slide 47 text

Language w/out Exceptions + halt

Slide 48

Slide 48 text

Reminder Start with L terms e1 and e2 such that e1 ≅L e2 If we can find a C in L + halt that can distinguish e1 from e2 (i.e., e1 ≆L + halt e2 ) …

Slide 49

Slide 49 text

e1 ≜ (λ (f) Ω) e2 ≜ (λ (f) ((f 0) Ω)) C[•] ≜ (• halt) C[e2 ] = 0 C[e1 ] = Ω

Slide 50

Slide 50 text

e1 ≜ (λ (f) Ω) e2 ≜ (λ (f) ((f 0) Ω)) C[•] ≜ (call/cc •) C[e2 ] = 0 C[e1 ] = Ω

Slide 51

Slide 51 text

Pure Language + State

Slide 52

Slide 52 text

e1 ≜ (λ (_) (f 0)) e2 ≜ (λ (_) (f 0) (f 0)) C[e2 ] = Ω C[e1 ] = 0 C[•] ≜ (define (f x) (set! f (λ (_) Ω)) x)) (• 0) take a parameter and return it changing f to a diverging function

Slide 53

Slide 53 text

Pure w/ Boolean-only if (Bif) + Truthy/Falsy if (Lif)

Slide 54

Slide 54 text

Semantics of Lif: (Lif #f A B) à B (Lif A B) à A (Similar argument for other truthy/falsy)

Slide 55

Slide 55 text

e1 ≜ (Bif (p (λ () Ω)) (Bif (p #f) 0 1) Ω) e2 ≜ The same term but with 1 replaced by Ω C[•] ≜ (define p (λ (x) (Lif x #t #f))) • C[e2 ] = Ω C[e1 ] = 1 p is not a procedure p applies its arg p does arith its arg p Bif’s its arg p ignores its arg

Slide 56

Slide 56 text

Local vs global transformations pure language + state: store-passing style control operators: continuation-passing style They can’t be local transformations They do add expressive power

Slide 57

Slide 57 text

Wrapping Up

Slide 58

Slide 58 text

What have we learned? A beautiful, practical definition of equality A clever definition of expressiveness Proof sketches that show us it matches intuition

Slide 59

Slide 59 text

What else is in the paper? Multiple notions of expressiveness Proof of that theorem (not trivial at all!) Relationship to logic Relationship to other formalizations

Slide 60

Slide 60 text

Implications for language design Desugaring/macros are now everywhere Macros can have a variety of powers Allowing macros that increase expressiveness… is something to be done with care

Slide 61

Slide 61 text

Benefits of expressive features Avoids non-local/global transformation Greater modularity otherwise Patterns…which can be misused Patterns…which hide intent

Slide 62

Slide 62 text

Homework Is the with construct of JavaScript expressive w.r.t. the rest of JavaScript?

Slide 63

Slide 63 text

Homework Is the generator construct of Python expressive w.r.t. the rest of Python?

Slide 64

Slide 64 text

No content