Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are some things that you've used Scheme macros for? [closed]

Many examples of macros seem to be about hiding lambdas, e.g. with-open-file in CL. I'm looking for some more exotic uses of macros, particularly in PLT Scheme. I'd like to get a feel for when to consider using a macro vs. using functions.

like image 494
Steven Huwig Avatar asked Oct 29 '08 03:10

Steven Huwig


People also ask

What are macros in programming?

A macro (which stands for "macroinstruction") is a programmable pattern which translates a certain sequence of input into a preset sequence of output. Macros can make tasks less repetitive by representing a complicated sequence of keystrokes, mouse movements, commands, or other types of input.

What can macros do that functions cant?

Firstly, what macros can do that functions cannot is all those actions that special operators can do. A macro call can expand into special operators, whereas a function call cannot. For instance, if we have a lexical variable x , then (mac x) can plausibly update its value. But (fun x) cannot.


2 Answers

Practical Common Lisp, by Peter Seibel, has a good introduction to macros. On Lisp, by Paul Graham, might be a good source of more complicated examples. Also, have look at the built-in macros in, say, Common Lisp.

like image 102
Luís Oliveira Avatar answered Nov 14 '22 03:11

Luís Oliveira


I only use Scheme macros (define-syntax) for tiny things like better lambda syntax:

(define-syntax [: x]
  (syntax-case x ()
    ([src-: e es ...]
     (syntax-case (datum->syntax-object #'src-: '_) ()
       (_ #'(lambda (_) (e es ...)))))))

Which lets you write

[: / _ 2]  ; <-- much better than (lambda (x) (/ x 2))

Dan Friedman has a mind-bending implementation of OO using macros: http://www.cs.indiana.edu/~dfried/ooo.pdf

But honestly, all the useful macros I've defined are stolen from Paul Graham's On Lisp and are generally easier to write with defmacro (define-macro in PLT Scheme). For example, aif is pretty ugly with define-syntax.

(define-syntax (aif x)
  (syntax-case x ()
    [(src-aif test then else)
     (syntax-case (datum->syntax-object (syntax src-aif) '_) ()
       [_ (syntax (let ([_ test]) (if (and _ (not (null? _))) then else)))])]))

define-syntax is odd in that it's only easy to use for very simple macros, where you are glad of the inability to capture variables; and very complicated macro DSLs, where you are glad of the inability to capture variables easily. In the first case you want to write the code without thinking about it, and in the second case you have thought enough about the DSL that you are willing to write part of it in the syntax-rules/syntax-case language which is not Scheme in order to avoid mystifying bugs.


But I don't use macros that much in Scheme. Idiomatic Scheme is so functional that many times you just want to write a functional program and then hide a few lambdas. I got on the functional train and now believe that if you have a lazy language or a good syntax for lambda, even that isn't necessary, so macros are not all that useful in a purely functional style.

So I'd recommend Practical Common Lisp and On Lisp. If you want to use PLT Scheme, I think most of their defmacro macros will work with define-macro. Or just use Common Lisp.

like image 22
Nathan Shively-Sanders Avatar answered Nov 14 '22 02:11

Nathan Shively-Sanders