Meet the Macro. a quick introduction to Lisp macros. Patrick Stein / TC Lisp Users Group /

Similar documents
INF4820. Common Lisp: Closures and Macros

Common LISP Tutorial 1 (Basic)

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 4. LISP: PROMĚNNÉ, DALŠÍ VLASTNOSTI FUNKCÍ, BLOKY, MAPOVACÍ FUNKCIONÁLY, ITERAČNÍ CYKLY,

Symbolic Programming. Dr. Zoran Duric () Symbolic Programming 1/ 89 August 28, / 89

Department of Computer and information Science Norwegian University of Science and Technology

Lambda Calculus and Lambda notation in Lisp II. Based on Prof. Gotshalks notes on Lambda Calculus and Chapter 9 in Wilensky.

LISP. Everything in a computer is a string of binary digits, ones and zeros, which everyone calls bits.

Common Lisp. Blake McBride

Imperative, OO and Functional Languages A C program is

Announcement. Overview. LISP: A Quick Overview. Outline of Writing and Running Lisp.

Lisp Basic Example Test Questions

Recursion & Iteration

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 5. LISP: MAKRA, DATOVÁ STRUKTURA ZÁZNAM

Associative Database Managment WIlensky Chapter 22

Associative Database Managment

INF4820: Algorithms for Artificial Intelligence and Natural Language Processing. More Common Lisp

Lecture Notes on Lisp A Brief Introduction

a little more on macros sort of like functions, but..

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 3. LISP: ZÁKLADNÍ FUNKCE, POUŽÍVÁNÍ REKURZE,

Functional Programming with Common Lisp

Artificial Intelligence Programming

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 2. ÚVOD DO LISPU: ATOMY, SEZNAMY, FUNKCE,

Chapter 1. Fundamentals of Higher Order Programming

CS 480. Lisp J. Kosecka George Mason University. Lisp Slides

Homework #2. Source code with description. Tzewen Wang ECE578 Winter 2005

A Brief Introduction to Common Lisp

Modern Programming Languages. Lecture LISP Programming Language An Introduction

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

Debugging in LISP. trace causes a trace to be printed for a function when it is called

(defmacro while (condition &body body) `(iterate loop () (if,condition (loop)))))

Notes on Higher Order Programming in Scheme. by Alexander Stepanov

Allegro CL Certification Program

A little bit of Lisp

Scheme. Functional Programming. Lambda Calculus. CSC 4101: Programming Languages 1. Textbook, Sections , 13.7

Extra Lecture #7: Defining Syntax

MIDTERM EXAMINATION - CS130 - Spring 2005

Functional programming with Common Lisp

Common LISP-Introduction

(defun fill-nodes (nodes texts name) (mapcar #'fill-node (replicate-nodes nodes (length texts) name) texts))

Lambda Calculus see notes on Lambda Calculus

A Genetic Algorithm Implementation

LFE - a lisp on the Erlang VM

Languages as Libraries

Lecture #5 Kenneth W. Flynn RPI CS

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

CIS4/681 { Articial Intelligence 2 > (insert-sort '( )) ( ) 2 More Complicated Recursion So far everything we have dened requires

INF4820: Algorithms for Artificial Intelligence and Natural Language Processing. Common Lisp Fundamentals

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

Robot Programming with Lisp

11/6/17. Functional programming. FP Foundations, Scheme (2) LISP Data Types. LISP Data Types. LISP Data Types. Scheme. LISP: John McCarthy 1958 MIT

Announcements. Today s Menu

Allegro CL Certification Program

Functional Programming. Pure Functional Programming

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Introduction to Lisp

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

CSCI337 Organisation of Programming Languages LISP

Func%onal Programming in Scheme and Lisp

UMBC CMSC 331 Final Exam

Functional Programming. Big Picture. Design of Programming Languages

Lecture #2 Kenneth W. Flynn RPI CS

Expressions and Assignment

Func%onal Programming in Scheme and Lisp

MetacircularScheme! (a variant of lisp)

UMBC CMSC 331 Final Exam

Functional Programming

Streams and Lazy Evaluation in Lisp

CSCI 2210: Programming in Lisp. Progn. Block. CSCI Programming in Lisp; Instructor: Alok Mehta 1. ANSI Common Lisp, Chapters 5-10

Symbolic Computation and Common Lisp

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

Scheme: Data. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Monday, April 3, Glenn G.

Review of Functional Programming

Vanilla Lisp Shell (VLS)

Robot Programming with Lisp

CS 314 Principles of Programming Languages

Structure Programming in Lisp. Shared Structure. Tailp. Shared Structure. Top-Level List Structure

Documentation for LISP in BASIC

19 Machine Learning in Lisp

FP Foundations, Scheme

CS61A Midterm 2 Review (v1.1)

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

Normal Order (Lazy) Evaluation SICP. Applicative Order vs. Normal (Lazy) Order. Applicative vs. Normal? How can we implement lazy evaluation?

This should prevent residual sexism, racism, favoritism lurking in the unconscious of your professor & TA from biasing grading!!

An introduction to Scheme

Concepts of programming languages

Lisp. Versions of LISP

Introduction to Functional Programming

Jatha. Common Lisp in Java. Ola Bini JRuby Core Developer ThoughtWorks Studios.

4/19/2018. Chapter 11 :: Functional Languages

Pattern Matching WIlensky Chapter 21

Functional programming techniques

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

Scheme: Expressions & Procedures

Programming Languages

CS 320: Concepts of Programming Languages

Type-checking on Heterogeneous Sequences

Introduction to lambda calculus Part 3

LECTURE 16. Functional Programming

Allegro CL Certification Program

CSCI 3155: Principles of Programming Languages Exam preparation #1 2007

Transcription:

Meet the Macro a quick introduction to Lisp macros Patrick Stein / TC Lisp Users Group / 2009-07-14

Attack Plan Some other things called macros First look at Lisp macros More advanced macros Uh-oh, my macro is messing up other things Toy surprise in the box Where to learn more 2

Called Macro (C/LaTeX/make) #define abs(x) \ ((x) < 0? -(x) : (x)) cpp macros can do string substitutions \frac{dx}{ \sqrt[3]{1 + x^2} } LaTeX macros can be LaTeX wrappers around other LaTeX SRCS := $(wildcard *.c) GNU make macros are a mini-language 3

Called Macro (ant,nroff,m4) Ant macros can do string and element substitutions nroff macros can barely stringsubstitute m4 can cheesily subst varargs <macrodef name= say-do > <attribute name= say default= (silent) /> <element name= do /> <sequential> <echo>@{say} :::</echo> <do /> </sequential> </macrodef>.nr LL 5i define( `quotify, ` $@ ) 4

First Lisp Macros (replacement) #define assert_good_x() \ assert( x!= NULL ) (defmacro assert_good_x () '(assert x)) (defun car+cdr (x) (assert_good_x) (cons x x)) (defun car+cdr (x) (assert x) (cons x x)) A very weak cpp macro An equally weak Lisp version How you d use it How it will look expanded. 5

First Lisp Macros (arg subst.) Bad cpp macro for reference Equivalent (i.e. equally bad) version in Lisp How you d use it #define abs(x) \ (((x) < 0)? -(x) : (x)) (defmacro abs (x) `(if (minusp,x) (-,x),x)) (defun taxi-dist (x y z) (+ (abs x) (abs y) (abs z))) My taxis go vertically! (abs (realpart (ack 3 z))) 6

First Lisp Macros (lists) (defmacro awhen (cond &body body) `(let ((it,cond)) (when it,@body))) (defun a-then-b? (a b list) (awhen (member a list) (write it) (member b (rest it)))) A macro that plops in the members instead of the list itself How you might use it 7

More Advanced (lisp @ comp.) A macro that uses more Lisp at compile time How you d use it What it would be expanded to (defun absify (arg) `(abs,arg)) (defmacro taxi-dist (&rest args) `(+,@(mapcar #'absify args))) (taxi-dist a b c) (+ (abs a) (abs b) (abs c)) 8

More Advanced (recursive) ;; recursive version of same macro (defmacro taxi-dist (&rest args) (case (length args) (0 '0) (1 `(abs,(first args))) (t `(+ (abs,(first args)) (taxi-dist,@(rest args)))))) ;; some examples of how it expands (taxi-dist) => 0 (taxi-dist a) => (abs a) (taxi-dist a b) => (+ (abs a) (taxi-dist b)) (taxi-dist a b c) => (+ (abs a) (taxi-dist b c)) 9

More Advanced (code-walking) CL-WHO macro that walks through the expression tree It turns some parts into output code (with-html-output (*s*) (:body (dotimes (j 5) (htm (:p Foo ) (:p Bar ))))) (write-string "<body>" *s*) (dotimes (j 5) (write-string "<p>foo</p>" *s*) (write-string "<p>bar</p>" *s*)) (write-string "</body>" *s*) Only approximate expansion 10

More Advanced (more walking) Turn infix notation into prefix notation: (!! (let ((a 42)) a - 2 * 2 * 10)) http://folk.uio.no/jornv/infpre/infpre.html Make translators that turn Lisp into other langs http://www.cliki.net/parenscript Make embedded domain-specific languages see any number of HTML, SQL, and XML input or output DSLs 11

Uh-Oh (double eval) (defmacro abs (x) `(if (minusp,x) (-,x),x)) (abs (incf x)) (abs (realpart (ack 3 z))) Problem: if x is an expression, it s evaluated twice Side-effects x2 Runtime x2 #define abs(x) \ ((x) < 0? -(x) : (x)) abs(++x); abs(realpart(ack(3,z))); cpp version has the same issue 12

Uh-Oh (variable capture) In Lisp, we can do better We have to take (defmacro abs (x) `(let ((v,x)) (if (minusp v) (- v) v))) care though This macro breaks if body uses a v from outside this scope. (defmacro when-car=cdr (x &body body) `(let ((v,x)) (when (= (car v) (cdr v)),@body))) 13

Uh-Oh (stopping variable capture) (defmacro when-car=cdr (x &body body) (let ((v (gensym))) `(let ((,v,x)) (when (= (car,v) (cdr,v)),@body)))) (when-car=cdr p (write p)) (let ((#:G772 p)) (when (= (car #:G772) (cdr #:G772)) (write p))) Gensym bails us out by generating a symbol that won t exist anywhere else Here is a use Here is one expansion 14

Uh-Oh (macros for macro-writing) Up to your ears in gensyms? Here s a macro for macro writers with-gensyms makes syms for a and b, then we bind them to this macro s args (defun symify (s) `(,s (gensym))) (defmacro with-gensyms (syms &body body) `(let,(mapcar #'symify syms),@body)) (defmacro crow-dist (x y) (with-gensyms (a b) `(let ((,a,x)(,b,y)) (sqrt (+ (*,a,a) (*,b,b)))))) 15

Toy Surprise (destructuring) (defmacro det+? ((x1 y1) (x2 y2) &body body) `(when (plusp (- (*,x1,y2) (*,x2,y1))),@body)) (det+? (a b) (c d) (do-something a b c d)) You can put extra structure into the way your arguments are laid out to make your syntax more natural for the problem 16

Toy Surprise (deeper destruct.) ;; macro used internally in ironclad (defmacro with-words (((&rest word-vars) array initial-offset &key (size 4) (big-endian t)) &body body)...) (with-words ((c d a b) ciphertxt ciphertxt-start :big-endian nil) (setf c (logxor c (aref round-keys 4)) d (logxor d (aref round-keys 5)) a (logxor a (aref round-keys 6)) b (logxor b (aref round-keys 7)))...) 17

Where to Learn More Slava Akmechet s Blog Post About Macros http://www.defmacro.org/ramblings/lisp.html Chapters 7 & 8 of Practical Common Lisp by Peter Seibel http://gigamonkeys.com/book Chapters 7-11 of On Lisp by Paul Graham http://paulgraham.com/onlisp.html Sections 3.1.2.1.2.2 and 3.4.4 of the HyperSpec Practice, Practice, Practice 18

(sb-ext:quit) the end Patrick Stein / TC Lisp Users Group / 2009-07-14

Uh-Oh Redux (infinite recursion) This would terminate as a function, but not as a macro This will terminate (defmacro argc (&rest args) `(if,(null args) 0 (1+ (argc,@(rest args))))) (defmacro argc (&rest args) (if args `(1+ (argc,@(rest args))) '0)) X

Uh-Oh Redux (other messes) (defmacro save (x) `(push vars,x)) (defun foo (vars) (save *random-state*)...) (defmacro both+? (a b) `(and (plusp,b) (plusp,a)) (both+? (incf x) (incf y)) (defmacro emph (x) (nconc x (list ':!!))) (defun foo () (emph (list :b))) Reference global that is later local Non-standard eval order Side-effects considered harmful X

Appendix (Ackermann function) ;; positive-integer version of Ackermann ;; function... can be extended to cover ;; n being a complex number if m is 1, 2, or 3. (defun ack (m n) (cond ((zerop m) (1+ n)) ((zerop n) (ack (1- m) 1)) (t (ack (1- m) (ack m (1- n)))))) ;; (ack 3 12) took me 11.007 seconds ;; (ack 3 13) blew out my stack after 50 seconds X