I'm working though SICP and wanted to try out some of the examples in guile. I'm trying the stream examples and wanted an implementation for cons-stream, which I got from this StackOverflow question. However when I type this into guile I get:
guile> (define-syntax cons-stream
(syntax-rules ()
[(cons-stream x y) (cons x (delay y))]))
ERROR: invalid syntax ()
ABORT: (misc-error)
I have no idea what's wrong with this - I've tried replacing () with '(), removing the [ ], but it still doesn't work even though it seems to be valid R5RS. I'm currently on guile 1.8.7, I can't see a package for v2.0.1 which the GNU docs mention, could this be why its not working for me?
Looks like you need to import support for syntax-rules first (see http://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/Syntax-Rules.html):
(use-syntax (ice-9 syncase))
Then you need to change the square brackets to parens; after that it should work.
Definitely don't quote the literals list; that's a sequence of identifiers, like lambda formals, not an expression.
Related
In Lisp, a function's arguments are evaluated first before entering the function body. Macro arguments stay not evaluated.
But sometimes, one wants to inject code pieces stored in variables into a macro. This means evaluating the argument for the macro first, and then apply the macro-of-choice on this evaluated result.
One has to resort to
(eval `(macro ,arg))
To achieve this - but eval does not behave correctly in different environments.
The best thing would be, if one could do:
(apply macro (list arg))
or
(funcall macro arg)
But since the macro is not a function this doesn't work.
Is it possible to achieve something like this? - To circumvent that problem oder to make the macro available in the functions namespace?
Or am I missing some other ways to solve such problems?
I came to this question while trying to answer How to produce HTML from a list. but also in Generate TYPECASE with macro in common lisp, Evaluate arguments passed to a macro that generates functions in lisp, and How to convert a list to code/lambda in scheme?. But I always thought while answering them it would be good to have an apply or funcall-like function which can take macros.
It is not clear what you are trying to do, although it is almost certain that you are confused about something. In particular if you are calling eval inside macroexpansions then in almost all cases you are doing something both seriously wrong and seriously dangerous. I can't ever think of a case where I've wanted macros which expand to things including eval and I have written Lisp for a very very long time.
That being said, here is how you call the function associated with a macro, and why it is very seldom what you want to do.
Macros are simply functions whose domain and range is source code: they are compilers from a language to another language. It is perfectly possible to call the function associated with a macro, but what that function will return is source code, and what you will then need to do with that source code is evaluate it. If you want a function which deals with run-time data which is not source code, then you need that function, and you can't turn a macro into that function by some magic trick which seems to be what you want to do: that magic trick does not, and can not, exist.
So for instance if I have a macro
(defmacro with-x (&body forms)
`(let ((x 1))
,#forms))
Then I can call its macro function on a bit of source code:
> (funcall (macro-function 'with-x)
'(with-x (print "foo")) nil)
(let ((x 1)) (print "foo"))
But the result of this is another bit of source code: I need to compile or evaluate it, and nothing I can do will get around this.
Indeed in (almost?) all cases this is just the same as macroexpand-1):
> (macroexpand-1 '(with-x (print "foo")))
(let ((x 1)) (print "foo"))
t
And you can probably write macroexpand-1 in terms of macro-function:
(defun macroexpand-1/equivalent (form &optional (env nil))
(if (and (consp form)
(symbolp (first form))
(macro-function (first form)))
(values (funcall (macro-function (first form)) form env)
t)
(values form nil)))
So, if the result of calling a macro is source code, what do you do with that source code to get a result which is not source code? Well, you must evaluate it. And then, well, since the evaluator expands macros for you anyway, you might as well just write something like
(defun evaluate-with-x (code)
(funcall (compile nil `(lambda ()
(with-x ,#code)))))
So you didn't need to call the macro's function in any case. And this is not the magic trick which turns macros into functions dealing with data which is not source code: it is a terrible horror which is entirely made of exploding parts.
A concrete example: CL-WHO
It looks like this question might have its origins in this one and the underlying problem there is that that's not what CL-WHO does. In particular it is a confusion to think that something like CL-WHO is a tool for taking some kind of list and turning it into HTML. It's not: it's a tool for taking the source code of a language which is built on CL but includes a way of expressing HTML output mingled with CL code, and compiles it into CL code which will do the same thing. It happens to be the case that CL source code is expressed as lists & symbols, but CL-WHO isn't really about that: it's a compiler from, if you like, 'the CL-WHO language' to CL.
So, let's try the trick we tried above and see why it's a disaster:
(defun form->html/insane (form)
(funcall
(compile nil `(lambda ()
(with-html-output-to-string (,(make-symbol "O"))
,#form)))))
And you might, if you did not look at this too closely, think that this function does in fact do the magic trick:
> (form->html/insane '(:p ((:a :href "foo") "the foo")))
"<p></p><a href='foo'>the foo</a>"
But it doesn't. What happens if we call form->html/insane on this perfectly innocuous list:
(:p (uiop/run-program:run-program "rm -rf $HOME" :output t))
Hint: don't call form->html/insane on this list if you don't have very good backups.
CL-WHO is an implementation of a programming language which is a strict superset of CL: if you try to turn it into a function to turn lists into HTML you end up with something involving the same nuclear weapon you tinker with every time you call eval, except that nuclear weapon is hidden inside a locked cupboard where you can't see it. But it doesn't care about that: if you set it off it will still reduce everything within a few miles to radioactive ash and rubble.
So if you want a tool which will turn lists – lists which aren't source code – into HTML then write that tool. CL-WHO might have the guts of such a tool in its implemenentation, but you can't use it as it is.
And this is the same problem you face whenever you are trying to abuse macros this way: the result of calling a macro's function is Lisp source code, and to evaluate that source code you need eval or an equivalent of eval. And eval is not only not a terrible solution to almost any problem: it's also a nuclear weapon. There are, perhaps problems for which nuclear weapons are good solutions, but they are few and far between.
I'm trying to move from Common Lisp to Chicken Scheme, and having plenty of problems.
My current problem is this: How can I write a macro (presumably using define-syntax?) that calls other macros?
For example, in Common Lisp I could do something like this:
(defmacro append-to (var value)
`(setf ,var (append ,var ,value)))
(defmacro something-else ()
(let ((values (list))
(append-to values '(1)))))
Whereas in Scheme, the equivalent code doesn't work:
(define-syntax append-to
(syntax-rules ()
((_ var value)
(set! var (append var value)))))
(define-syntax something-else
(syntax-rules ()
((_)
(let ((values (list)))
(append-to values '(1))))))
The append-to macro cannot be called from the something-else macro. I get an error saying the append-to "variable" is undefined.
According to all the information I've managed to glean from Google and other sources, macros are evaluated in a closed environment without access to other code. Essentially, nothing else exists - except built-in Scheme functions and macros - when the macro is evaluated. I have tried using er-macro-transformer, syntax-case (which is now deprecated in Chicken anyway) and even the procedural-macros module.
Surely the entire purpose of macros is that they are built upon other macros, to avoid repeating code. If macros must be written in isolation, they're pretty much useless, to my mind.
I have investigated other Scheme implementations, and had no more luck. Seems it simply cannot be done.
Can someone help me with this, please?
It looks like you're confusing expansion-time with run-time. The syntax-rules example you give will expand to the let+set, which means the append will happen at runtime.
syntax-rules simply rewrites input to given output, expanding macros until there's nothing more to expand. If you want to actually perform some computation at expansion time, the only way to do that is with a procedural macro (this is also what happens in your defmacro CL example).
In Scheme, evaluation levels are strictly separated (this makes separate compilation possible), so a procedure can use macros, but the macros themselves can't use the procedures (or macros) defined in the same piece of code. You can load procedures and macros from a module for use in procedural macros by using use-for-syntax. There's limited support for defining things to run at syntax expansion time by wrapping them in begin-for-syntax.
See for example this SO question or this discussion on the ikarus-users mailing list. Matthew Flatt's paper composable and compilable macros explains the theory behind this in more detail.
The "phase separation" thinking is relatively new in the Scheme world (note that the Flatt paper is from 2002), so you'll find quite a few people in the Scheme community who are still a bit confused about it. The reason it's "new" (even though Scheme has had macros for a long long time) is that procedural macros have only become part of the standard since R6RS (and reverted in R7RS because syntax-case is rather controversial), so the need to rigidly specify them hasn't been an issue until now. For more "traditional" Lispy implementations of Scheme, where compile-time and run-time are all mashed together, this was never an issue; you can just run code whenever.
To get back to your example, it works fine if you separate the phases correctly:
(begin-for-syntax
(define-syntax append-to
(ir-macro-transformer
(lambda (e i c)
(let ((var (cadr e))
(val (caddr e)))
`(set! ,var (append ,var ,val)))))) )
(define-syntax something-else
(ir-macro-transformer
(lambda (e i c)
(let ((vals (list 'print)))
(append-to vals '(1))
vals))))
(something-else) ; Expands to (print 1)
If you put the definition of append-to in a module of its own, and you use-for-syntax it, that should work as well. This will also allow you to use the same module both in the macros you define in a body of code as well as in the procedures, by simply requiring it both in a use and a use-for-syntax expression.
I'm exploring Scheme macros, but I've been unable to find a portable way of writing anaphoric macros.
I'm trying to write an each-it macro, such that this code:
(each-it (list 1 2 3)
(display it))
Expands to this:
(for-each (lambda (it)
(display it))
(list 1 2 3))
I've written a macro with syntax-rules, but this gives me an error about an undefined identifier when I try to use it.
(define-syntax each-it
(syntax-rules ()
((each-it lst body)
(for-each (lambda (it) body)
lst))))
This SO question mentions define-syntax-parameter, which seems to be Racket only. This blog post gives some Scheme code samples, but the code samples don't run in DrRacket in R5RS mode (I think it's the square brackets?).
R4RS has an interesting macro appendix but it is not present in R5RS and I don't know if I can depend on it.
Can I write my each-it macro in a completely portable way? If not, what are the most widely available macro system features for writing my macro?
This should be portable, at least in R6RS:
(define-syntax each-it
(lambda (x)
(syntax-case x ()
((_ lst body)
(with-syntax ((it (datum->syntax x 'it)))
#'(for-each (lambda (it) body) lst))))))
Yes, you can write it in a portable way assuming that R6RS is portable enough for you. (The same cannot be said on R7RS, which currently has nothing more than just syntax-rules, and it's unclear what will be included in the large language, or when it will happen.) See uselpa's for how to do that.
So why am I writing another answer? Because actually doing that is going to be a bad idea. A bad idea not in some vague academic sense that doesn't matter for most real world code -- bad in a sense that is likely to bite you later on. I know that "paper" makes it look intimidating, but read at least the first two sections of the paper mentioned in the other SO question you've seen. Specifically, Section 1.2 shows the problem you'll be running against. Then, Section 2 shows how to do it "properly", in a way that makes it tedious to write macros that expand to uses of your macro. At this point, it will be appealing to take the "just keep it hygienic", but at the end of Section 2 you'll see why that's not working either.
The bottom line, IMO, is to just not do it unless you have syntax parameters or something similar. Maybe the only exception to that (which might be your case) is when the macro is something that you intend to use yourself, and you will never provide it to others.
I'm trying to go through "The Little Lisper" and already running into snags in the first chapter. I'm relatively new to Emacs (which has fueled my interest in learning Lisp and clojure). I downloaded the Mit-scheme app, and am working the exercises on Edwin.
I'm trying:
(atom? (cons a l))
where a is an atom and l is a list already defined. I get the following error:
;Unbound variable: atom?
Why? I have no problems using the "null?" function. I thought "atom?" is an internal function checking to see if the value returned is an atom.
Any explanation would be much appreciated. I still haven't set up my emacs to run scheme, and the minor differences between all the lisp dialects is testing my patience.
In "The Little Schemer" ("The Little Lisper"'s updated version) the atom? procedure is defined as follows (because atom? doesn't exist in Scheme):
(define (atom? x)
(and (not (null? x))
(not (pair? x))))
If you're following an old version of the book, I advise you to either look for a newer version or use the same programming language used in the book: Common Lisp for The Little Lisper, Scheme for The Little Schemer - and Racket is a great Scheme IDE to work with! take a look at this answer for some tips when going through The Little Schemer using Racket.
I'm trying to go through "The Little Lisper"...
I downloaded the Mit-scheme
Common Lisp and Scheme are very different languages.
You have to either use a different book (e.g., SICP) to match your language implementation or a different language implementation (e.g., clisp or sbcl) to match your book.
Take a look at the Scheme R5RS specification; it includes a list of functions and syntactic keywords. Although not part of the Scheme standard, mit-scheme has a function apropos that will find functions (other stuff) with a given name. try:
(apropos "atom")
(but it won't show anything, :-).
An atom is something that is not a 'cons cell' (generally, if I remember my CommonLisp). In Scheme you could implement one as:
(define (atom? thing) (not (pair? thing)))
Note: this definition of atom? is consistent with CommonLisp atom.
While looking at the syntax-case section in R6RS, I saw the keyword make-variable-transformer, described as an identifier macro. The example given is very minimal, and I am not groking why it is necessary, or what use-cases require it. Finding additional examples of its use is also proving difficult. Presumably it makes some form of syntax transformation possible, or more elegant?
After reading http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-13.html#node_sec_12.3 my take is as follows:
If mac is a syntax transformer
(mac foo (bar baz)) would replace the entire s-expr with the result of the transformation this could result in anything say (SOMETHING), while (foo mac bar) would replace only mac resulting in (foo SOMETHING bar).
Normally (set! mac 'foo) would signal an error it seems that the transformer can not appear on the left of a set expression, but if mac is a variable transformer (set! mac 'foo) would instead call mac with the whole s-expr.
My intuition tells me this would be useful if you start implementing datatypes with macros.
I came across this searching for documentation on make-variable-transformer. Here's a problem I had that make-variable-transformer was suggested for...
http://groups.google.com/group/comp.lang.scheme/browse_frm/thread/96b07d431f1a66de/777f8e07ae1855f3#777f8e07ae1855f3
Jack Trades