15
Static Guarantees for Macro Bindings Mitchell Wand Presentation for Gnosys site visit 12/14/12

Site visit presentation 2012 12 14

Embed Size (px)

Citation preview

Page 1: Site visit presentation 2012 12 14

Static Guarantees for Macro

BindingsMitchell Wand

Presentation for Gnosys site visit

12/14/12

Page 2: Site visit presentation 2012 12 14

Why study macros?

macros are a facility for lightweight compilers

translate DSL into host language (Racket), then let Racket compiler work

easy interoperation with host language, etc.

most translation is on a per-s-expression basis

Racket macro system has features that permit interaction between macros, optimizations, fancier syntax, etc.

Page 3: Site visit presentation 2012 12 14

Want: static reasoning about

hygiene Does the expansion of a macro obey its

intended scoping rules?

Does my-let act like let?

◦ Is id0 bound in body?

(define-syntax my-let

(syntax-rules ()

[(_ ((id0 val0) (id val) ...) body)

((lambda (id ...) body)

val ...)]))Answer: No

Page 4: Site visit presentation 2012 12 14

Didn't Dybvig solve this in 1993?

No notion of "intended scoping rules"

Dybvig's algorithm works out binding relationships dynamically.

We want static guarantees.

Page 5: Site visit presentation 2012 12 14

Didn't the nominal logic guys

solve this? Nominal logic: Pitts, et al. 2000 or so, et seq. Logic for reasoning about names Much work about representing terms with

binding. BUT: Aimed at theorem proving, not

programming Generally involves data representations that

carry their scoping rules with them:◦ lambda-terms, not s-expressions.◦ Macros must translate from s-expressions (or

something like them) to lambda-terms (or something like them)

Page 6: Site visit presentation 2012 12 14

Our Starting Points (I)

Ott: a specification language for binding patterns, like Ott (ICFP 2007, JFP 2010)

p ::= // patterns

| x binders = x

| { l1=p1,...,ln=pn } binders = binders(p1 ... pn)

t ::= // terms

| let p = t in t’ bind binders(p) in t’

A primitive binder

A composite binder

Bind these variables in t'

Page 7: Site visit presentation 2012 12 14

This doesn't solve the problem

Ott has back-ends for

◦ Latex

◦ several theorem provers

But it's not a general-purpose tool

Page 8: Site visit presentation 2012 12 14

Our Starting Points (II)

Dave Herman's thesis (2010)

◦ took Ott-like specification language

◦ static checking for syntax-rules style macros

Would reject my-let from slide 1.

Goal: extend this to procedurally-defined macros (e.g. syntax-case)

Page 9: Site visit presentation 2012 12 14

Our Starting Points (III)

Pottier's Functional Fresh ML (LICS 2007)

A programming language based on nominal logic.

His goal: programming with binders.

◦ functions map alpha-equivalent objects to alpha-equivalent objects

Attractive semantics

◦ no hidden gensym (!)

Page 10: Site visit presentation 2012 12 14

Pottier's Result

Theorem 1: Any function in Fresh ML either preserves alpha-equivalence or else faults

◦ careful language design, any bound variable that escapes its scope triggers a fault.

Theorem 2: From any program in Fresh ML, we can derive a formula G s.t. if G is true, then the program never faults.

Dynamic!

Static! Can use SMT prover

Page 11: Site visit presentation 2012 12 14

Does this solve the problem?

No: his data still carries around its own binding information dynamically

We need to manipulate plain old s-expressions (or something like them)

Page 12: Site visit presentation 2012 12 14

Our plan

Adapt Pottier's system to use plain old s-expressions.

Keep the binding information in types (static) rather than in the data (dynamic)

Page 13: Site visit presentation 2012 12 14

Progress [Work by Paul

Stansifer] Core language defined

Static checks defined (extension of Pottier's)

Now working on proofs of theorems

Page 14: Site visit presentation 2012 12 14

A Binding Specification

// input

Expr' = App' Expr Expr

| Lam' Atom Expr↓0

| Var' Atom

| Let LetClauses Expr↓0

| LetRec LetClauses↓0 Expr

LetClauses = LCNone

| LCBind Atom Expr LetClauses ⇑0⊎2

// output

Expr = App Expr Expr

| Lam Atom Expr↓0

| Var Atom

bindings from Atom and

LetClauses are bound in

Expr

Export bindings from

Atom and LetClauses

0 1

0 1 2

We use positional

notation for now

Atoms export themselves

Page 15: Site visit presentation 2012 12 14

Next Steps

Interface to SMT prover (w/ Fabian Muehlenboeck)

What adaptations are necessary to make these obligations acceptable to an SMT-style prover?

Actually write some macros in this system.