Slide 1

Slide 1 text

Matthew Flatt ICFP 2002 Sam Tobin-Hochstadt Papers �e Love NYC Composable & Compilable Macros You want it when?

Slide 2

Slide 2 text

Prehistory • Scheme No standard module system Implementations used Common Lisp approach • Macros Hygenic macros 15 years old Still considered esoteric • PLT Scheme Mostly designed for teaching IDE with multiple language levels

Slide 3

Slide 3 text

Composable and Compilable Macros Matthew Flatt University of Utah

Slide 4

Slide 4 text

A Scheme Programmer...

Slide 5

Slide 5 text

... Programming in Scheme

Slide 6

Slide 6 text

... in Macro-Extended Scheme!

Slide 7

Slide 7 text

... Trying to Use a Compiler

Slide 8

Slide 8 text

... Accomodating the Compiler

Slide 9

Slide 9 text

... Trying a Different Compiler

Slide 10

Slide 10 text

... Trying a Complex Library

Slide 11

Slide 11 text

The Trouble with Scripting the Compiler (load "u.scm") (eval-when (compile load) (load "m.scm")) (load "a.scm") (load "b.scm") ... m (load "ma.scm") (load "mb.scm") a b u ma mb = load effect

Slide 12

Slide 12 text

The Trouble with Scripting the Compiler (load "u.scm") (eval-when (compile load) (load "m.scm")) (load "a.scm") (load "b.scm") ... m (load "ma.scm") (load "mb.scm") a b u ma mb = dependency

Slide 13

Slide 13 text

The Trouble with Scripting the Compiler (load "u.scm") (eval-when (compile load) (load "m.scm")) (load "a.scm") (load "b.scm") ... m (load "ma.scm") (load "mb.scm") a b u ma mb

Slide 14

Slide 14 text

The Trouble with Scripting the Compiler (load "u.scm") (eval-when (compile load) (load "m.scm")) (load "a.scm") (load "b.scm") ... m (load "ma.scm") (load "mb.scm") a b u ma mb never loaded in compile mode

Slide 15

Slide 15 text

The Trouble with Scripting the Compiler (load "u.scm") (eval-when (compile load) (load "m.scm")) (load "a.scm") (load "b.scm") ... (load "u.scm") (load "ma.scm") (load "mb.scm") a b u ma mb

Slide 16

Slide 16 text

The Trouble with Scripting the Compiler (load "u.scm") (eval-when (compile load) (load "m.scm")) (load "a.scm") (load "b.scm") ... (load "u.scm") (load "ma.scm") (load "mb.scm") a b u ma mb loaded twice in interactive mode

Slide 17

Slide 17 text

Problem Solution • Declarative • Consistent success/failure in all compilation modes • Supports lexically scoped macros macro-defining macros Example Experience

Slide 18

Slide 18 text

Modules and Macros (module a (define-syntax m ...) (define f ...) ...)

Slide 19

Slide 19 text

Modules and Macros = run-time expressions (module a (define-syntax m ...) (define f ... ...) ... ...)

Slide 20

Slide 20 text

Modules and Macros = compile-time expressions (module a (define-syntax m ... ...) (define f ... ...) ... ...)

Slide 21

Slide 21 text

Modules and Macros #' in escapes back to (module a (define-syntax m ... ...) (define f ... ...) ... ...) #'(f ...) (f ...)

Slide 22

Slide 22 text

Modules and Macros (module a (define-syntax m ... ...) (define f ... ...) ... ...) (module b (require "a.scm") (define-syntax n ...) (define g ...) ...) #'(f ...) (f ...)

Slide 23

Slide 23 text

Modules and Macros (module a (define-syntax m ... ...) (define f ... ...) ... ...) (module b (require "a.scm") (define-syntax n ...) (define g ... ...) ... ...) #'(f ...) (f ...)

Slide 24

Slide 24 text

Modules and Macros (module a (define-syntax m ... ...) (define f ... ...) ... ...) (module b (require "a.scm") (define-syntax n ... ...) (define g ... ...) ... ...) #'(f ...) (f ...)

Slide 25

Slide 25 text

Modules and Macros (module u (define fold ...) ...) (module a (define-syntax m ... ...) (define f ... ...) ... ...) (module b (require "a.scm") (require-for-syntax "u.scm") (define-syntax n ... ...) (define g ... ...) ... ...) #'(f ...) (f ...)

Slide 26

Slide 26 text

Modules and Macros (module u (define fold ...) ...) (module a (require "u.scm") (define-syntax m ... ...) (define f ... ...) ... ...) (module b (require "a.scm") (require-for-syntax "u.scm") (define-syntax n ... ...) (define g ... ...) ... ...)

Slide 27

Slide 27 text

Modules and Macros (module u (define fold ...) ...) (module u (define fold ...) ...) (module a (require "u.scm") (define-syntax m ... ...) (define f ... ...) ... ...) (module b (require "a.scm") (require-for-syntax "u.scm") (define-syntax n ... ...) (define g ... ...) ... ...) different instance for each phase

Slide 28

Slide 28 text

Problem Solution Example • Record matching with static checks Experience

Slide 29

Slide 29 text

Records and Matching (define-record zebra (weight stripes))

Slide 30

Slide 30 text

Records and Matching (define-record zebra (weight stripes)) (zebra 500 24) ; = a zebra instance

Slide 31

Slide 31 text

Records and Matching (define-record zebra (weight stripes)) (zebra 500 24) ; = a zebra instance (define-record lizard (weight length color)) (lizard 2 5 'green) ; = a lizard instance

Slide 32

Slide 32 text

Records and Matching (define-record zebra (weight stripes)) (zebra 500 24) ; = a zebra instance (define-record lizard (weight length color)) (lizard 2 5 'green) ; = a lizard instance (record-switch ... ((zebra w s) ...) ((lizard w l c) ...))

Slide 33

Slide 33 text

Records and Matching (define-record zebra (weight stripes)) (zebra 500 24) ; = a zebra instance (define-record lizard (weight length color)) (lizard 2 5 'green) ; = a lizard instance (define (animal-weight a) (record-switch a ((zebra w s) w) ((lizard w l c) w))) (animal-weight (zebra 500 24)) ; = 500 (animal-weight (lizard 2 5 'green)) ; = 2

Slide 34

Slide 34 text

Records and Matching (define-record zebra (weight stripes)) (zebra 500 24) ; = a zebra instance (define-record lizard (weight length color)) (lizard 2 5 'green) ; = a lizard instance (define (animal-weight a) (record-switch a ((zebra w s c) w) syntax error ((lizard w l c) w)))

Slide 35

Slide 35 text

Records and Matching (define-record zebra (weight stripes)) (zebra 500 24) ; = a zebra instance (define-record lizard (weight length color)) (lizard 2 5 'green) ; = a lizard instance (define (animal-weight a) (record-switch a ((zebra w s c) w) syntax error ((lizard w l c) w))) compile-time communication across module boundaries

Slide 36

Slide 36 text

Implementing Records (module record (define-syntax define-record ...) (define-syntax record-switch ...))

Slide 37

Slide 37 text

Implementing Records (module record (define-syntax define-record ...) (define-syntax record-switch ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...))

Slide 38

Slide 38 text

Implementing Records (module record (define-syntax define-record ...#'(define name (mkrec ...))...) (define-syntax record-switch ...#'(is-a name ...) ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...))

Slide 39

Slide 39 text

Implementing Records (module record (define-syntax define-record ...#'(define name (mkrec ...))...) (define-syntax record-switch ...#'(is-a name ...) ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...)) expands to (define zebra (mkrec ...))

Slide 40

Slide 40 text

Implementing Records (module record (define-syntax define-record ...#'(define name (mkrec ...))...) (define-syntax record-switch ...#'(is-a name ...) ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...)) expands to (define zebra (mkrec ...)) expands to (is-a zebra ...)

Slide 41

Slide 41 text

Implementing Records (module record (require "rt.scm") (define-syntax define-record ...#'(define name (mkrec mkrec ...))...) (define-syntax record-switch ...#'(is-a is-a name ...) ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...)) (module rt (define mkrec ...) (define is-a ...)) expands to (define zebra (mkrec mkrec ...)) expands to (is-a is-a zebra ...)

Slide 42

Slide 42 text

Implementing Records (module record (require "rt.scm") (define-syntax define-record ... table ...) (define-syntax record-switch ... table ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...)) (module rt (define mkrec ...) (define is-a ...))

Slide 43

Slide 43 text

Implementing Records (module record (require "rt.scm") (require-for-syntax "ct.scm") (define-syntax define-record ... table table ...) (define-syntax record-switch ... table table ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...)) (module rt (define mkrec ...) (define is-a ...)) (module ct (define table ...) ...)

Slide 44

Slide 44 text

Implementing Records (module record (require "rt.scm") (require-for-syntax "ct.scm") (define-syntax define-record ... table table ...) (define-syntax record-switch ... table table ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...)) (module rt (define mkrec ...) (define is-a ...)) (module ct (define table ...) ...) adds zebra to table while expanding

Slide 45

Slide 45 text

Implementing Records (module record (require "rt.scm") (require-for-syntax "ct.scm") (define-syntax define-record ... table table ...) (define-syntax record-switch ... table table ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...)) (module rt (define mkrec ...) (define is-a ...)) (module ct (define table ...) ...) adds zebra to table while expanding finds zebra in table while expanding

Slide 46

Slide 46 text

Implementing Records (module record (require "rt.scm") (require-for-syntax "ct.scm") (define-syntax define-record ...) (define-syntax record-switch ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...)) (module rt (define mkrec ...) (define is-a ...)) (module ct (define table ...) ...)

Slide 47

Slide 47 text

Implementing Records (module record (require "rt.scm") (require-for-syntax "ct.scm") (define-syntax define-record ...) (define-syntax record-switch ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...)) (module rt (define mkrec ...) (define is-a ...)) (module ct (define table ...) ...) (module client (require "zoo.scm") (record-switch ... ((zebra w s) ...)))

Slide 48

Slide 48 text

Implementing Records (module record (require "rt.scm") (require-for-syntax "ct.scm") (define-syntax define-record ...) (define-syntax record-switch ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...)) (module rt (define mkrec ...) (define is-a ...)) (module ct (define table ...) ...) (module client (require "zoo.scm") (record-switch ... ((zebra w s) ...))) cannot find zebra in table

Slide 49

Slide 49 text

Implementing Records (module record (require "rt.scm") (require-for-syntax "ct.scm") (define-syntax define-record ...#'(for-syntax ...table table...)...) (define-syntax record-switch ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...)) (module rt (define mkrec ...) (define is-a ...)) (module ct (define table ...) ...) (module client (require "zoo.scm") (record-switch ... ((zebra w s) ...)))

Slide 50

Slide 50 text

Implementing Records (module record (require "rt.scm") (require-for-syntax "ct.scm") (define-syntax define-record ...#'(for-syntax ...table table...)...) (define-syntax record-switch ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...)) (module rt (define mkrec ...) (define is-a ...)) (module ct (define table ...) ...) (module client (require "zoo.scm") (record-switch ... ((zebra w s) ...))) now expands to (for-syntax ...table table...) (define zebra (mkrec ...))

Slide 51

Slide 51 text

Implementing Records (module record (require "rt.scm") (require-for-syntax "ct.scm") (define-syntax define-record ...#'(for-syntax ...table table...)...) (define-syntax record-switch ...)) (module zoo (require "record.scm") (define-record zebra (wgt sc)) (record-switch ... ((zebra w s) ...)) (module rt (define mkrec ...) (define is-a ...)) (module ct (define table ...) ...) (module client (require "zoo.scm") (record-switch ... ((zebra w s) ...))) now expands to (for-syntax ...table table...) (define zebra (mkrec ...)) finds zebra in table

Slide 52

Slide 52 text

Problem Solution Example Experience • The many languages & compilers of PLT Scheme

Slide 53

Slide 53 text

PLT Scheme

Slide 54

Slide 54 text

PLT Scheme DrScheme supports multiple languages that share libraries

Slide 55

Slide 55 text

PLT Scheme

Slide 56

Slide 56 text

PLT Scheme One compilation mode

Slide 57

Slide 57 text

PLT Scheme Another compilation mode

Slide 58

Slide 58 text

PLT Scheme Yet another compilation mode

Slide 59

Slide 59 text

PLT Scheme

Slide 60

Slide 60 text

�hat happened after • Modules Became the basis for Scheme standards Influenced other module systems • Macros syntax-parse, more phases, debugging Tons of features • Languages Typed Racket, datalog, Scribble

Slide 61

Slide 61 text

Other papers to read

Slide 62

Slide 62 text

Other papers to read

Slide 63

Slide 63 text

Other papers to read

Slide 64

Slide 64 text

Other papers to read