Macros and general code walkers in Lisp: how useful! or, how useful? Ernst van Waning

Slides:



Advertisements
Similar presentations
09 Examples Functional Programming. Tower of Hanoi AB C.
Advertisements

ANSI Common Lisp 5. Control 16 June Blocks -- progn progn > (progn (format t “a”) (format t “b”) ( )) ab 23 The expressions within its body.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
1 Programming Languages and Paradigms Lisp Programming.
A problem with functions: arguments must always have values that can be worked out Whenever we call a function we give it arguments. Lisp then works out.
Lisp – Introduction יעל נצר מערכות נבונות סמסטר ב' תשס"ו.
First Lecture on Introductory Lisp Yun Peng. Why Lisp? Because it’s the most widely used AI programming language Because AI researchers and theoreticians.
Introduction CSC 358/458 3/27/2006. Outline Introductions Course goals Course organization History of Lisp Lisp syntax Examples Lisp IDE.
CSE S. Tanimoto Macros 1 Defining Macros in Lisp Extensibility: A language is extensible if the language can be extended. New Lisp control structures.
CSE S. Tanimoto Explicit Function Application 1 Explicit Application of Functions, Functional Arguments and Explicit Evaluation Implicit and explicit.
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
PRACTICAL COMMON LISP Peter Seibel 1.
SchemeCOP Introduction to Scheme. SchemeCOP Scheme Meta-language for coding interpreters –“ clean ” semantics Scheme = LISP + ALGOL –simple.
Functional Programming COMP2003 A course on functional programming using Common Lisp Dr Eleni Mangina
LISP A brief overview. Lisp stands for “LISt Process” –Invented by John McCarthy (1958) –Simple data structure (atoms and lists) –Heavy use of recursion.
Error Handling Common Lisp has the throw/catch statements so that you can simulate exception handling as seen in languages like Java But CL goes far beyond.
Common Lisp Macros Read for Input Macros Macro lifetime Macro syntax
1 Lisp Functions –Built-in functions –Defining functions –Function Evaluation and Special Forms defun, if Control statements –Conditional if, cond –Repetition.
Functional Programming in Scheme and Lisp. Overview In a functional programming language, functions are first class objects. You can create them, put.
CSE 341, S. Tanimoto Lisp Defining Functions with DEFUN Functions are the primary abstraction mechanism available in Lisp. (Others are structures.
Functional Programming and Lisp. Overview In a functional programming language, functions are first class objects. In a functional programming language,
04 Control. Control-Blocks Common Lisp has 3 basic operators for creating blocks of code progn block tagbody If ordinary function calls are the leaves.
Lecture 1-2CS251: Intro to AI/Lisp II “And now for something completely different…”
Macros “How can you get anything done in [other languages], I think, without macros?” - Paul Graham, 2003.
1 The Evaluator. 2 Compiler vs. Interpreter Command Processing Unit The Computer Program in Low Level Machine Language Program in High Level Language.
CSE S. Tanimoto Lisp Defining Macros in Lisp Extensibility: A language is extensible if the language can be extended. New Lisp control structures.
Introduction to LISP. Lisp Extensible: It lets you define new operators yourself Lisp programs are expressed as lisp data structures –You can write programs.
UMBC CMSC Common Lisp II. UMBC CMSC Input and Output Print is the most primitive output function > (print (list 'foo 'bar)) (FOO BAR) The.
CSE S. Tanimoto Macros 1 Defining Macros in Scheme Extensibility: A language is extensible if the language can be extended. New Scheme control structures.
PRACTICAL COMMON LISP Peter Seibel 1.
Milos Hauskrecht (PDF) Hieu D. Vu (PPT) LISP PROGARMMING LANGUAGE.
Basic Scheme February 8, 2007 Compound expressions Rules of evaluation Creating procedures by capturing common patterns.
1/33 Basic Scheme February 8, 2007 Compound expressions Rules of evaluation Creating procedures by capturing common patterns.
1 COSC generating functions, templates, and macros Yves Lespérance Adapted from Peter Roosen-Runge.
Basic Introduction to Lisp
CSE 341, S. Tanimoto Lisp Explicit Application of Functions and Functional Arguments In Lisp, functions can be passed as arguments to other functions.
PRACTICAL COMMON LISP Peter Seibel 1.
Macros CSC 358/ Outline  Homework #6  Macro Intro  Backquote  Macros  Modify macros  Read Macros.
Clojure Macros. Homoiconicity All versions of Lisp, including Clojure, are homoiconic This means that there is no difference between the form of the data.
Macros Forms that the compiler expands into code ● Decide if the macro is really necessary ● Write down the syntax of the macro ● Figure out what the macro.
1 Outline Review Introduction to LISP Symbols and Numbers Lists Writing LISP Functions LISPWorks.
Artificial Intelligence and Lisp Lecture 6 LiU Course TDDC65 Autumn Semester,
Functional Programming
Basic Scheme February 8, 2007 Compound expressions Rules of evaluation
Defining Macros in Lisp
LISP A brief overview.
First Lecture on Introductory Lisp
The Metacircular Evaluator
Functions and Macros.
Modern Programming Languages Lecture 21 Fakhar Lodhi
CSE 341 Section 7 Winter 2018 Adapted from slides by Eric Mullen, Nicholas Shahan, Dan Grossman, and Tam Dang.
Dynamic Scoping Lazy Evaluation
3.4 Local Binding Recall Scheme's let: > (let ((x 5)‏ (y 6))
Modern Programming Languages Lecture 20 Fakhar Lodhi
CSE S. Tanimoto Explicit Function Application
6.001 SICP Further Variations on a Scheme
Explicit Application of Procedures, and Explicit Evaluation
Lisp, Then and Now.
Streams and Lazy Evaluation in Lisp and Scheme
Lisp: Using Functions as Data
LISP A brief overview.
6.001 SICP Variations on a Scheme
Defining Macros in Lisp
Clojure Macros.
Defining Functions with DEFUN
Peter Seibel Practical Common Lisp Peter Seibel
Abstraction and Repetition
Lisp: Using Functions as Data
Common Lisp II.
Defining Macros in Scheme
Presentation transcript:

Macros and general code walkers in Lisp: how useful! or, how useful? Ernst van Waning

Benelux-LispersMacros in Common Lisp2 Overview Short overview of macros in Lisp Macros transform macro calls Macros are not code transformers In frustration I have sometimes thought macros have a certain smell Lisp has many specific code walkers Q: can we make general code walkers?

Benelux-LispersMacros in Common Lisp3 Macros are replaced by their expansion (expansion time) The original call evaporates After expansion, their code may be evaluated (evaluation time) Macros in Lisp

Benelux-LispersMacros in Common Lisp4 Expansion and evaluation Arguments of macro calls are not evaluated At expansion time, appropriate error messages do make sense Evaluation is done after the macro expanded

Benelux-LispersMacros in Common Lisp5 Debugging macros Macroexpand-1 expands your macro once (i.e., applies the expander once) Macroexpand expands your macro call until it is no longer a macro call With a non-macro they just return (values form ’nil) Expanding all macros in all subforms is a different game: code walker

Benelux-LispersMacros in Common Lisp6 Tracing expansions Useful for debugging local macros Useful for studying system macros (defmacro trexp (form &environment env) (let ((*print-pretty* t)) (multiple-value-bind (expansion expanded-p) (macroexpand-1 form env) (cond (expanded-p (format *trace-output* "~&~S~%-m1->~%“ form) `(trexp,expansion)) (t (format *trace-output* "~&~S~%~%" form) expansion)))))

Benelux-LispersMacros in Common Lisp7 A model for macros Lisp is explained using Lisp, so we explain Lisp’s macros with Lisp (defmacro our-expander (name) `(get,name 'expander)) Our-expander is an accessor, i.e., it can be set with setf

Benelux-LispersMacros in Common Lisp8 A model for macros (defun our-macro-call? (xpr) (and (consp xpr) (our-expander (car xpr)))) (defun our-macroexpand-1 (xpr) (if (our-macro-call? xpr) (funcall (our-expander (car xpr)) xpr) xpr))

Benelux-LispersMacros in Common Lisp9 A model for macros (defmacro our-defmacro (name args &body body) (let ((g (gensym)));unique symbol `(progn (setf (our-expander ',name) ;store (lambda (,g) (block,name;for return-from (destructuring-bind,args ',name)))

Benelux-LispersMacros in Common Lisp10 A model for macros The actual argument to an expander is the entire macro call Macros do not evaluate the arguments of the macro call The expander is really a function retaining its lexical environment Macros are not first-class values

What are macros good for?

Benelux-LispersMacros in Common Lisp12 Macros control evaluation Special syntax (dotimes (i 10 i) (princ i)) Implicit quoting `(setf (our-expander ‘,name) …) Design your own control structures (aif xpr pos zero neg) Multiple evaluations (dotimes (i 10 i) (princ i))

Benelux-LispersMacros in Common Lisp13 Macros compute during expansion (defmacro avg (&rest numbers) `(/ numbers))) Definers also compute during expansion Defun, defmacro, &c. do a lot of bookkeeping Think of writing your own definers!

Benelux-LispersMacros in Common Lisp14 Macros as accessors (setf (our-expander name) new) ~m~> (something like) (let ((#:g452 name) (#:g453 'expander) (#:g455 new)) (inverse-get #:g452 #:g453 #:g455)) Setf looks “inside” its first argument There are many accessors with their own setf-expanders

Benelux-LispersMacros in Common Lisp15 Macros set up lexical bindings (dotimes (i 10 i) (princ i)) With-macros with-open-file, with-output-to-string &c. Do-macros do, dolist, dotimes, do-symbols &c.

What more do we want?

Benelux-LispersMacros in Common Lisp17 Macros as code transformers Suppose we want to have type-strict expressions but without pain A macro scalar is fine: (scalar :e) –m-> … But what if I want this? (scalar (exp 1)) -m-> (exp (scalar 1)) -m-> (exp 1d0) -m-> …;at expansion time

Benelux-LispersMacros in Common Lisp18 Code transformation Sums of squares of real numbers are non-negative (at least, in theory ): (scalar (sqrt ssq)) -m*-> (the (scalar 0) (sqrt (the (scalar 0) ssq))) Can we prove that ssq is non-negative by expanding a macro? Macros do not allow arbitrary code transformations

Benelux-LispersMacros in Common Lisp19 Domain specific extensions Lisp is an extensible programming language Build applications as extensions to Lisp Telescoping: a strategy to automatically generate highly optimized domain specific libraries But how easy is it to write in Lisp domain-specific semantic checks? domain-specific optimizations?

Benelux-LispersMacros in Common Lisp20 Term Rewriting Systems (TRS) aka Code Walkers Useful in automatic theorem proving Lisp has many code walkers: Read, eval, print, compile Cross-referencers, and more… Lisp makes it easy to write specific ones

Benelux-LispersMacros in Common Lisp21 A general code walker in Lisp? What is a general code walker? Minimizes effort to write specific ones Traverses all forms, a fortiori special ones …more…? Integration with macros is possible Change macroexpand-1 Surrounding code can be made visible by means of a stack

Benelux-LispersMacros in Common Lisp22 A general code walker in Lisp? The infamous 24 special forms of Lisp: Special forms implemented as macro Macros implemented as special form Traversal of implementation-specific special forms All special forms retrievable in any Lisp We can check if they have a walker

Benelux-LispersMacros in Common Lisp23 A general code walker in Lisp? What about macros? What about system-macros? What about the portability of your walkers?

Benelux-LispersMacros in Common Lisp24 A general code walker in Lisp? Looks like a clear idea, but is it? Even if the idea would be clear, there are real problems to solve Would it really help you write your code walkers? Specific code walkers, however, remain very useful