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
)
…
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?