CSE341: Programming Languages Lecture 15 Macros. Zach Tatlock Winter 2018

Similar documents
What is a macro. CSE341: Programming Languages Lecture 15 Macros. Example uses. Using Racket Macros. Zach Tatlock Winter 2018

Programming Languages. Thunks, Laziness, Streams, Memoization. Adapted from Dan Grossman s PL class, U. of Washington

CSE341: Programming Languages Winter 2018 Unit 5 Summary Zach Tatlock, University of Washington

CSE 341: Programming Languages

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018

CSE341 Spring 2016, Final Examination June 6, 2016

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

CSE 341, Autumn 2015, Ruby Introduction Summary

Racket. CSE341: Programming Languages Lecture 14 Introduction to Racket. Getting started. Racket vs. Scheme. Example.

CSE341, Spring 2013, Final Examination June 13, 2013

Racket: Macros. Advanced Functional Programming. Jean-Noël Monette. November 2013

Concepts of programming languages

CSE 341 Section 7. Eric Mullen Spring Adapted from slides by Nicholas Shahan, Dan Grossman, and Tam Dang

CSE341 Autumn 2017, Final Examination December 12, 2017

CS 360 Programming Languages Day 14 Closure Idioms

Typical workflow. CSE341: Programming Languages. Lecture 17 Implementing Languages Including Closures. Reality more complicated

CSE341 Spring 2017, Final Examination June 8, 2017

Today. CSE341: Programming Languages. Late Binding in Ruby Multiple Inheritance, Interfaces, Mixins. Ruby instance variables and methods

User-defined Functions. Conditional Expressions in Scheme

CS 342 Lecture 7 Syntax Abstraction By: Hridesh Rajan

CSE341: Programming Languages Lecture 19 Introduction to Ruby and OOP. Dan Grossman Winter 2013

CSE341 Spring 2017, Final Examination June 8, 2017

CSE 341 Section 7. Ethan Shea Autumn Adapted from slides by Nicholas Shahan, Dan Grossman, Tam Dang, and Eric Mullen

Intro. Scheme Basics. scm> 5 5. scm>

CSE 341: Programming Languages

Writing Interpreters Racket eval. CSE341 Section 7. ASTs, Interpreters, MUPL. Sunjay Cauligi. February 21 st, Sunjay Cauligi CSE341 Section 7

Ruby logistics. CSE341: Programming Languages Lecture 19 Introduction to Ruby and OOP. Ruby: Not our focus. Ruby: Our focus. A note on the homework

Functional abstraction. What is abstraction? Eating apples. Readings: HtDP, sections Language level: Intermediate Student With Lambda

Functional abstraction

Variables. Substitution

CS422 - Programming Language Design

CSE 505: Concepts of Programming Languages

Lecture 09: Data Abstraction ++ Parsing is the process of translating a sequence of characters (a string) into an abstract syntax tree.

CSE 341 : Programming Languages

CSE 341 Section 5. Winter 2018

9/23/2014. Why study? Lambda calculus. Church Rosser theorem Completeness of Lambda Calculus: Turing Complete

CSE 374 Programming Concepts & Tools

6.184 Lecture 4. Interpretation. Tweaked by Ben Vandiver Compiled by Mike Phillips Original material by Eric Grimson

CSE 505: Programming Languages. Lecture 10 Types. Zach Tatlock Winter 2015

CS251 Programming Languages Spring 2016, Lyn Turbak Department of Computer Science Wellesley College

Scheme: Expressions & Procedures

Introduction to Parsing. Lecture 5

Extensible Pattern Matching

Fundamentals and lambda calculus

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

COP4020 Programming Assignment 1 - Spring 2011

Macros in C/C++ Computer Science and Engineering College of Engineering The Ohio State University. Lecture 33

QUIZ. What is wrong with this code that uses default arguments?

Introduction to Scheme

From Syntactic Sugar to the Syntactic Meth Lab:

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

Local definitions and lexical scope

Local definitions and lexical scope. Local definitions. Motivating local definitions. s(s a)(s b)(s c), where s = (a + b + c)/2.

Computer Science 21b (Spring Term, 2015) Structure and Interpretation of Computer Programs. Lexical addressing

Some Naughty Bits. Jeremy Brown. January 7-8, 2003

Principles of Programming Languages Topic: Functional Programming Professor L. Thorne McCarty Spring 2003

CSE 331 Software Design and Implementation. Lecture 14 Generics 2

mk-convert Contents 1 Converting to minikanren, quasimatically. 08 July 2014

An Introduction to Scheme

Organization of Programming Languages CS3200/5200N. Lecture 11

Documentation for LISP in BASIC

Ruby: Introduction, Basics

CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Zach Tatlock Winter 2018

CSE413 Midterm. Question Max Points Total 100

Function definitions. CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Example, extended. Some gotchas. Zach Tatlock Winter 2018

CS 320: Concepts of Programming Languages

Programming Languages Third Edition

An Explicit Continuation Evaluator for Scheme

Parsing. Note by Baris Aktemur: Our slides are adapted from Cooper and Torczon s slides that they prepared for COMP 412 at Rice.

Func+on applica+ons (calls, invoca+ons)

Lecture Outline. COOL operational semantics. Operational Semantics of Cool. Motivation. Lecture 13. Notation. The rules. Evaluation Rules So Far

A Functional Evaluation Model

Sardar Vallabhbhai Patel Institute of Technology (SVIT), Vasad M.C.A. Department COSMOS LECTURE SERIES ( ) (ODD) Code Optimization

YOUR NAME PLEASE: *** SOLUTIONS ***

CSE341: Programming Languages Lecture 20 Arrays and Such, Blocks and Procs, Inheritance and Overriding. Dan Grossman Spring 2017

Discussion 11. Streams

PIC 10A Objects/Classes

Scheme Basics > (butfirst '(help!)) ()

CS321 Languages and Compiler Design I. Winter 2012 Lecture 4

Tradeoffs. CSE 505: Programming Languages. Lecture 15 Subtyping. Where shall we add useful completeness? Where shall we add completeness?

Lecture Notes on Program Equivalence

Operational Semantics of Cool

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

CS 314 Principles of Programming Languages

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

6.001 Notes: Section 8.1

SML Style Guide. Last Revised: 31st August 2011

Lecture 4 CSE July 1992

Functional Languages. CSE 307 Principles of Programming Languages Stony Brook University

Operational Semantics. One-Slide Summary. Lecture Outline

Typescript on LLVM Language Reference Manual

Ruby: Introduction, Basics

Lecture Outline. COOL operational semantics. Operational Semantics of Cool. Motivation. Notation. The rules. Evaluation Rules So Far.

6.001 Notes: Section 15.1

The Typed Racket Guide

CS 415 Midterm Exam Spring SOLUTION

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming


Introduction to Typed Racket. The plan: Racket Crash Course Typed Racket and PL Racket Differences with the text Some PL Racket Examples

Transcription:

CSE341: Programming Languages Lecture 15 Macros Zach Tatlock Winter 2018

What is a macro A macro definition describes how to transform some new syntax into different syntax in the source language A macro is one way to implement syntactic sugar Replace any syntax of the form e1 andalso e2 with if e1 then e2 else false A macro system is a language (or part of a larger language) for defining macros Macro expansion is the process of rewriting the syntax for each macro use Before a program is run (or even compiled) 2

Using Racket Macros If you define a macro m in Racket, then m becomes a new special form: Use (m ) gets expanded according to definition Example definitions (actual definitions coming later): Expand (my-if e1 then e2 else e3) to (if e1 e2 e3) Expand (comment-out e1 e2) to e2 Expand (my-delay e) to (mcons #f (lambda () e)) 3

Example uses It is like we added keywords to our language Other keywords only keywords in uses of that macro Syntax error if keywords misused Rewriting ( expansion ) happens before execution (my-if x then y else z) ; (if x y z) (my-if x then y then z) ; syntax error (comment-out (car null) #f) (my-delay (begin (print "hi") (foo 15))) 4

Overuse Macros often deserve a bad reputation because they are often overused or used when functions would be better When in doubt, resist defining a macro? But they can be used well 5

Now How any macro system must deal with tokens, parentheses, and scope How to define macros in Racket How macro definitions must deal with expression evaluation carefully Order expressions evaluate and how many times The key issue of variable bindings in macros and the notion of hygiene Racket is superior to most languages here 6

Tokenization First question for a macro system: How does it tokenize? Macro systems generally work at the level of tokens not sequences of characters So must know how programming language tokenizes text Example: macro expand head to car Would not rewrite (+ headt foo) to (+ cart foo) Would not rewrite head-door to car-door But would in C where head-door is subtraction 7

Parenthesization Second question for a macro system: How does associativity work? C/C++ basic example: #define ADD(x,y) x+y Probably not what you wanted: ADD(1,2/3)*4 means 1 + 2 / 3 * 4 not(1 + 2 / 3) * 4 So C macro writers use lots of parentheses, which is fine: #define ADD(x,y) ((x)+(y)) Racket won t have this problem: Macro use: (macro-name ) After expansion: something else in same place 8

Local bindings Third question for a macro system: Can variables shadow macros? Suppose macros also apply to variable bindings. Then: Would become: (let ([head 0][car 1]) head) ; 0 (let* ([head 0][car 1]) head) ; 0 (let ([car 0][car 1]) car) ; error (let* ([car 0][car 1]) car) ; 1 This is why C/C++ convention is all-caps macros and non-all-caps for everything else Racket does not work this way it gets scope right! 9

Example Racket macro definitions Two simple macros (define-syntax my-if ; macro name (syntax-rules (then else) ; other keywords [(my-if e1 then e2 else e3) ; macro use (if e1 e2 e3)])) ; form of expansion (define-syntax comment-out ; macro name (syntax-rules () ; other keywords [(comment-out ignore instead) ; macro use instead])) ; form of expansion If the form of the use matches, do the corresponding expansion In these examples, list of possible use forms has length 1 Else syntax error 10

Revisiting delay and force Recall our definition of promises from earlier Should we use a macro instead to avoid clients explicit thunk? (define (my-delay th) (mcons #f th)) (define (my-force p) (if (mcar p) (mcdr p) (begin (set-mcar! p #t) (set-mcdr! p ((mcdr p))) (mcdr p)))) (f (my-delay (lambda () e))) (define (f p) ( (my-force p) )) 11

A delay macro A macro can put an expression under a thunk Delays evaluation without explicit thunk Cannot implement this with a function Now client should not use a thunk (that would double-thunk) Racket s pre-defined delay is a similar macro (define-syntax my-delay (syntax-rules () [(my-delay e) (mcons #f (lambda() e))])) (f (my-delay e)) 12

What about a force macro? We could define my-force with a macro too Good macro style would be to evaluate the argument exactly once (use x below, not multiple evaluations of e) Which shows it is bad style to use a macro at all here! Do not use macros when functions do what you want (define-syntax my-force (syntax-rules () [(my-force e) (let([x e]) (if (mcar x) (mcdr x) (begin (set-mcar! x #t) (set-mcdr! p ((mcdr p))) (mcdr p))))])) 13

Another bad macro Any function that doubles its argument is fine for clients (define (dbl x) (+ x x)) (define (dbl x) (* 2 x)) These are equivalent to each other So macros for doubling are bad style but instructive examples: (define-syntax dbl (syntax-rules()[(dbl x)(+ x x)])) (define-syntax dbl (syntax-rules()[(dbl x)(* 2 x)])) These are not equivalent to each other. Consider: (dbl (begin (print "hi") 42)) 14

More examples Sometimes a macro should re-evaluate an argument it is passed If not, as in dbl, then use a local binding as needed: (define-syntax dbl (syntax-rules () [(dbl x) (let ([y x]) (+ y y))])) Also good style for macros not to have surprising evaluation order Good rule of thumb to preserve left-to-right Bad example (fix with a local binding): (define-syntax take (syntax-rules (from) [(take e1 from e2) (- e2 e1)])) 15

Local variables in macros In C/C++, defining local variables inside macros is unwise When needed done with hacks like strange_name34 Here is why with a silly example: Macro: (define-syntax dbl (syntax-rules () [(dbl x) (let ([y 1]) (* 2 x y))])) Use: (let ([y 7]) (dbl y)) Naïve expansion: (let ([y 7]) (let ([y 1]) (* 2 y y))) But instead Racket gets it right, which is part of hygiene 16

The other side of hygiene This also looks like it would do the wrong thing Macro: (define-syntax dbl (syntax-rules () [(dbl x) (* 2 x)])) Use: (let ([* +]) (dbl 42)) Naïve expansion: (let ([* +]) (* 2 42)) But again Racket s hygienic macros get this right! 17

How hygienic macros work A hygienic macro system: 1. Secretly renames local variables in macros with fresh names 2. Looks up variables used in macros where the macro is defined Neither of these rules are followed by the naïve expansion most macro systems use Without hygiene, macros are much more brittle (non-modular) On rare occasions, hygiene is not what you want Racket has somewhat complicated support for that 18

More examples See the code for macros that: A for loop for executing a body a fixed number of times Shows a macro that purposely re-evaluates some expressions and not others Allow 0, 1, or 2 local bindings with fewer parens than let* Shows a macro with multiple cases A re-implementation of let* in terms of let Shows a macro taking any number of arguments Shows a recursive macro 19