A Theory of Hygienic Macros

75
A Theory of Hygienic Macros PhD Thesis Proposal David Herman

description

A Theory of Hygienic Macros. PhD Thesis Proposal David Herman. The power of macros. Derived (user-defined) syntactic constructs Defined by rewriting to existing constructs Translated at compile-time (define-macro (increment! a) (set! a (+ a 1))). local bindings, software contracts,. - PowerPoint PPT Presentation

Transcript of A Theory of Hygienic Macros

Page 1: A Theory of Hygienic Macros

A Theory ofHygienic Macros

PhD Thesis ProposalDavid Herman

Page 2: A Theory of Hygienic Macros

2

The power of macros

Derived (user-defined) syntactic constructs Defined by rewriting to existing constructs Translated at compile-time

(define-macro (increment! a) (set! a (+ a 1)))

Page 3: A Theory of Hygienic Macros

3

The power of macros

Abstractions for scope, control, program structure Powerful meta-programming idioms Allow for a minimal language core

functions, recursion, iteration, primitive datatypes

custom loop forms, derived datatypes, first-class module systems, object-orientation, test harnesses, data

constructors, laziness, short-circuit boolean operators, iteration protocols,

static analyses, parser generators, partial evaluation, debuggers,

coroutines, exceptions, threads, type checkers,

introspection, etc…

local bindings, software contracts,

languagedesigner

language user

Page 4: A Theory of Hygienic Macros

4

The need for hygiene

(define-macro (or e1 e2) (with ([t e1]) (if t t e2)))

(with ([x 1]) (or #f x))=>(with ([x 1]) (with ([t #f]) (if t t x)))

(with ([t 1]) (or #f t))=>(with ([t 1]) (with ([t #f]) (if t t t)))

Page 5: A Theory of Hygienic Macros

5

The need for hygiene

(define-macro (or e1 e2) (with ([t e1]) (if t t e2)))

(with ([x 1]) (or #f x))=>(with ([x 1]) (with ([t #f]) (if t t x)))

(with ([t 1]) (or #f t))=>(with ([t 1]) (with ([t′ #f]) (if t′ t′ t)))

Page 6: A Theory of Hygienic Macros

6

What are hygienic macros?

Page 7: A Theory of Hygienic Macros

7

What are hygienic macros?

(define-macro (or e1 e2) (with ([t e1]) (if t t e2)))

(with ([x 1]) (or #f x))=>(with ([x 1]) (with ([t #f]) (if t t x)))

(with ([t 1]) (or #f t))=>(with ([t 1]) (with ([t #f]) (if t t t)))

Page 8: A Theory of Hygienic Macros

8

What are hygienic macros?

Page 9: A Theory of Hygienic Macros

9

What are hygienic macros?

KFFD ’86:

Generated identifiers that become binding instances in the completely expanded program must only bind variables that are generated at the same transcription step.

i.e., not provided as the macro’s input

i.e., a single rewriting of a macro application

Page 10: A Theory of Hygienic Macros

10

What are hygienic macros?

Clinger and Rees ’91:

1. It is impossible to write a macro that inserts a binding that can capture references other than those inserted by the macro.

2. It is impossible to write a macro that inserts a reference that can be captured by bindings other than those inserted by the macro.

again: not provided as the macro’s input

Page 11: A Theory of Hygienic Macros

11

Why isn’t this enough?

Page 12: A Theory of Hygienic Macros

12

Pathological macros in Scheme

Impossible with hygienic macros, right?

(loop (begin (when (prime? i) (break i)) (increment! i)))

Page 13: A Theory of Hygienic Macros

13

Pathological macros in Scheme

Contrast with the explicit version:

(loop/explicit break (begin (when (prime? i) (break i)) (increment! i)))

provided as input

Page 14: A Theory of Hygienic Macros

14

Pathological macros in Scheme

Petrofsky extraction:

(loop (begin (when (prime? i) (break i)) (increment! i)))

Page 15: A Theory of Hygienic Macros

15

Pathological macros in Scheme

Dumpster diving:

(loop (begin (when (prime? i) (break i)) (increment! i)))

Page 16: A Theory of Hygienic Macros

16

Pathological macros in Scheme

Dumpster diving:

(loop/explicit break (begin (when (prime? i) (break i)) (increment! i)))

Page 17: A Theory of Hygienic Macros

17

Pathological macros in Scheme

(define-macro (murky a e) (begin (set! a e) (lambda (a) e)))

(let ([foo 10]) (murky foo (+ foo 1)))

Page 18: A Theory of Hygienic Macros

18

Pathological macros in Scheme

(define-macro (indecisive ([a e]) body) (if-zero …complicated computation… ((lambda (a) body) e) ((lambda (a) e) body)))

Page 19: A Theory of Hygienic Macros

19

What do we know about hygiene?

Page 20: A Theory of Hygienic Macros

20

Hygiene and lexical scope

(define-macro (or e1 e2) (with ([t e1]) (if t t e2)))

(with ([x 1]) (or #f x))=>(with ([x 1]) (with ([t #f]) (if t t x)))

(with ([t 1]) (or #f t))=>(with ([t 1]) (with ([t′ #f]) (if t′ t′ t)))

=

Page 21: A Theory of Hygienic Macros

21

Hygienic macro expansion isinsensitive to -conversion.

The essence of hygienic macros

In other words,hygienic = respects

!

Page 22: A Theory of Hygienic Macros

22

What is the scope of with?

(define-macro (with ([a e1]) e2) …)

First try: look at results of expansion

(with ([x 1]) (or #f x))=>((lambda (x) ((lambda (t) (if t t x)) #f) 1)

(with ([t 1]) (or #f t))=>((lambda (t) ((lambda (t′) (if t′ t′ t)) #f) 1)

Page 23: A Theory of Hygienic Macros

23

Using expansion to define scope

Goal: define hygienic macro expansion in terms of -equivalence.

Strategy: define -equivalence in terms of hygienic macro expansion.

Oops.

Page 24: A Theory of Hygienic Macros

24

What is the scope of with?

(define-macro (with ([a e1]) e2) …)

Better idea: provide a binding specification

with consumes an argument of shape(with ([a e1]) e2) and produces an expression, where:

a is an identifier e1 and e2 are expressions a is bound in e2

Page 25: A Theory of Hygienic Macros

25

What is the scope of with?

(define-macro (with ([a e1]) e2) …)

Better idea: provide a binding specification

with : (with ([<a> expr]) expra) → expr

Page 26: A Theory of Hygienic Macros

26

Annotated with macro

(define-macro (with ([a e1]) e2) : expr [(a : binder) (e1 : expr) (e2 : expr a)] …)

States macro writer’s intention about scope Admits rigorous -equivalence definition Provides correctness criterion for hygienic

macro expansion

Page 27: A Theory of Hygienic Macros

27

Thesis

The key to specifying and verifying hygienic macro expansion is specifying the binding structure of macros.

Page 28: A Theory of Hygienic Macros

28

A Theory of Hygienic Macros

m, a model of hygienic macros

1. Macro binding specifications (types)2. Theory of -equivalence3. High-level expansion semantics4. Definition and proof of hygiene

Page 29: A Theory of Hygienic Macros

29

A Theory of Hygienic Macros

m, a model of hygienic macros

1. Macro binding specifications (types)2. Theory of -equivalence3. High-level expansion semantics4. Definition and proof of hygiene

Page 30: A Theory of Hygienic Macros

30

m: a model of hygienic macros

(with ([x 1]) x)

(x.x) 1

S-expressions

-calculus

Page 31: A Theory of Hygienic Macros

31

m: a model of hygienic macros

→ (with ([x 1]) x)

→ ((lambda (x) x) 1)

→ ((x.x) 1)

→ (x.x) 1

Page 32: A Theory of Hygienic Macros

32

m: a model of hygienic macros

let syntax fun = macro ((a) e) : ((<a>) expra) => a.e with = macro (([a e]) body) : (([<a> expr])

expra) => ((a.body) e)in (with ([f (fun (x) 42)]) (f y.y))end

Page 33: A Theory of Hygienic Macros

33

A Theory of Hygienic Macros

m, a model of hygienic macros

1. Macro binding specifications (types)2. Theory of -equivalence3. High-level expansion semantics4. Definition and proof of hygiene

Page 34: A Theory of Hygienic Macros

34

1. Macro binding specifications

Shape types based on Culpepper and Felleisen ’03:

with : (with ([id expr]) expr) → expr

Types for reasoning about scope inspired by nominal datatypes and nominal logic of Gabbay and Pitts ’01

Page 35: A Theory of Hygienic Macros

35

1. Type checking

let syntax m = macro p : => …in x.eend

[m : → expr] ⊢ x.e : expr

Page 36: A Theory of Hygienic Macros

36

1. Type checking

let syntax m = macro p : => …in x.eend

[m : → expr, x : expr] ⊢ e : expr

Page 37: A Theory of Hygienic Macros

37

1. Meta-level scope

let syntax m = macro (e1 e2) : (expr expr) => t.(e1 e2)in …end

[t : expr], [e1 : expr, e2 : expr] ⊢ e : expr

Page 38: A Theory of Hygienic Macros

38

1. Two dimensions of binding

: program bindings (object-level) : macro pattern bindings (meta-level)

, ⊢ s :

Page 39: A Theory of Hygienic Macros

41

A Theory of Hygienic Macros

m, a model of hygienic macros

1. Macro binding specifications (types)2. Theory of -equivalence3. High-level expansion semantics4. Definition and proof of hygiene

Page 40: A Theory of Hygienic Macros

42

2. Theory of -equivalence Adapted to macro applications by exploiting

shape type annotations Relies on novel shape-directed -conversion Based on Gabbay/Pitts “swapping” formulation of

-equivalence

Page 41: A Theory of Hygienic Macros

43

2. -equivalence via swapping

let val x = x in x (fn x => x) end=

let val y = x in y (fn w => w) end

binding occurrence

Page 42: A Theory of Hygienic Macros

44

2. -equivalence via swapping

let val z = x in x (fn x => x) end=

let val z = x in y (fn w => w) end

free

Page 43: A Theory of Hygienic Macros

45

2. -equivalence via swapping

let val z = x in x (fn x => x) end=

let val z = x in y (fn w => w) end

Page 44: A Theory of Hygienic Macros

46

2. -equivalence via swapping

let val z = x in z (fn z => z) end=

let val z = x in z (fn w => w) end

Page 45: A Theory of Hygienic Macros

47

2. -equivalence via swapping

let val z = x in z (fn z′ => z′) end=

let val z = x in z (fn z′ => z′) end

Page 46: A Theory of Hygienic Macros

48

2. -equivalence via swapping For each binder x, pick fresh name z Rename the binding occurrence of x In the body, swap all occurrences of x with z Recur on subterms Compare results syntactically

Page 47: A Theory of Hygienic Macros

49

2. -equivalence for m

(with ([x x]) (x (fun (x) x)))

=

(with ([y x]) (y (fun (w) w)))

?

Page 48: A Theory of Hygienic Macros

50

2. Shape-directed -conversion

(with ([x x]) (x (fun (x) x)))

(with ([<a> expr]) expra)

(with ([y x]) (y (fun (w) w)))

binding occurrence

Page 49: A Theory of Hygienic Macros

51

2. Shape-directed -conversion

(with ([z x]) (x (fun (x) x)))

(with ([<a> expr]) expra)

(with ([z x]) (y (fun (w) w)))

not in scope of a;not converted

Page 50: A Theory of Hygienic Macros

52

2. Shape-directed -conversion

(with ([z x]) (x (fun (x) x)))

(with ([<a> expr]) expra)

(with ([z x]) (y (fun (w) w)))

entering scope of a;swap all occurrences of x / y

with z

Page 51: A Theory of Hygienic Macros

53

2. Shape-directed -conversion

(with ([z x]) (z (fun (z) z)))

(with ([<a> expr]) expra)

(with ([z x]) (z (fun (w) w)))

Page 52: A Theory of Hygienic Macros

54

2. Shape-directed -conversion

(with ([z x]) (z (fun (z) z)))

(fun (<b>) exprb)

(with ([z x]) (z (fun (w) w)))

Page 53: A Theory of Hygienic Macros

55

2. Shape-directed -conversion

(with ([z x]) (z (fun (z′) z′)))

(fun (<b>) exprb)

(with ([z x]) (z (fun (z′) z′)))

Page 54: A Theory of Hygienic Macros

56

2. -equivalence for m

(with ([z x]) (z (fun (z′) z′)))

=

(with ([z x]) (z (fun (z′) z′)))

Page 55: A Theory of Hygienic Macros

57

But what is hygienic expansion?

Page 56: A Theory of Hygienic Macros

58

A Theory of Hygienic Macros

m, a model of hygienic macros

1. Macro binding specifications (types)2. Theory of -equivalence3. High-level expansion semantics4. Definition and proof of hygiene

Page 57: A Theory of Hygienic Macros

59

3. Hygienic macro expansion

Simple substitution semantics:

let syntax x = m in e end → e[m/x]

if BV(e) ∩ FV(m) =

(m . s) → transcribe(e, match(p, s))

if m = (macro p : => e) and BV(s) ∩ FV(e) = and BV(e) # s

Page 58: A Theory of Hygienic Macros

60

3. Expansion up to x.let syntax m = macro (e) : (expr) => (e x) in x.(m x) end

Page 59: A Theory of Hygienic Macros

61

3. Expansion up to x.let syntax m = macro (e) : (expr) => (e x) in x′.(m x′) end

x.x′.((macro (e) : (expr) => (e x)) x′)

x.x′.(x′ x)

Page 60: A Theory of Hygienic Macros

62

3. Confluence

(with ([x 1]) (or #f x))

((x.(with ([t #f]) (if t t x))) 1)

((x.(or #f x)) 1)(with ([x 1]) (with ([t #f]) (if t t x)))

Page 61: A Theory of Hygienic Macros

63

3. Confluence

Theorem: Let s be a term such that , ⊢ s : . Ifs → s1 and s → s2 then there exists an s′ such that s1 →

* s′ and s2 →*

s′.

* *

s

s1 s2

s′

Page 62: A Theory of Hygienic Macros

64

A Theory of Hygienic Macros

m, a model of hygienic macros

1. Macro binding specifications (types)2. Theory of -equivalence3. High-level expansion semantics4. Definition and proof of hygiene

AKA, paydirt

Page 63: A Theory of Hygienic Macros

65

4. Hygiene

The expansion relation → is hygienic if for any well-typed expressions e0 and e′0 such that e0 = e′0 and fully-expanded expressions e and e′ such thate0 →

* e and e′0 →

* e′, then e = e′.

e0

e′0

e

e′

*

*

Hygienic = respects !

Page 64: A Theory of Hygienic Macros

66

4. Remember confluence?

* *

s up to-equivalence

s1 s2

s′

Page 65: A Theory of Hygienic Macros

67

4. Hygiene

Theorem: the relation → is hygienic.

e0

e′0

e′

e

Page 66: A Theory of Hygienic Macros

68

Research Plan

Page 67: A Theory of Hygienic Macros

69

Additional properties and proofs

Joint confluence with evaluation:

(with ([x ((y.y) 1)]) x)

(with ([x 1]) x)((x.x) ((y.y) 1))

((x.x) 1)

Page 68: A Theory of Hygienic Macros

70

Evaluation of classic algorithms

KFFD ’86 Macros that Work (Clinger and Rees ’91) Proof of correctness, if possible

Page 69: A Theory of Hygienic Macros

71

Elements of syntax-rules

Core features: Recursive macros Case dispatch

Advanced features: Macro-defining macros

Conveniences: Variable-length sequences Ellipsis patterns (Kohlbecker and Wand ’87)

Page 70: A Theory of Hygienic Macros

72

Research plan

Formal model (Completed.) Correctness proofs (Completed.) Elements of syntax-rules

(Expected May 2008.) Evaluation of classic algorithms

(Expected June 2008.) Additional properties and proofs

(Expected August 2008.) Dissertation and defense

(Expected November 2008.)

Page 71: A Theory of Hygienic Macros

73

Related Work

Page 72: A Theory of Hygienic Macros

74

Related work

Hygienic macro systems Kohlbecker et al ’86: Hygienic macro expansion Kohlbecker and Wand ’87: Macro-by-example Bawden and Rees ’88: Syntactic closures Clinger and Rees ’91: Macros that work Dybvig et al ’93: Syntactic abstraction in Scheme Krishnamurthi ’01: Linguistic reuse

Models of macros Bove and Arbilla ’92: Confluent calculus of expansion Gasbichler ’06: Modules with hygienic macros

Page 73: A Theory of Hygienic Macros

75

Related workMacro types Culpepper and Felleisen ’03: Well-shaped macros

Variables and binding Higher-order abstract syntax, de Bruijn, “locally nameless” Gabbay, Pitts: Nominal logic

Staged programming Davies and Pfenning: Modal analysis of staged computation Taha et al: Multi-stage programming, MetaML, MacroML Nanevski: Meta-programming with names and necessity. Kim et al ’06: Polymorphic modal type system for Lisp-like

multi-staged languages

Page 74: A Theory of Hygienic Macros

76

Hygienic = respects !

Thank you.

Page 75: A Theory of Hygienic Macros

77

Thank you.