Take this (simplified) example:
(defmacro make [v & body]
`(let [~'nv ~(some-calc v)]
~(map #(if (= % :value) 'nv %) body)))
Right now the symbol nv is hardcoded. Is there a way to somehow gensym nv and still being able to use it in the map function?
By the way, is this actually an anaphoric macro?
The answer is contained within the question: just use gensym like you would if Clojure didn't have auto-gensyms.
(defmacro make [v & body]
(let [value-sym (gensym)]
`(let [~value-sym ~(some-calc v)]
~#(replace {:value value-sym} body))))
Note that I'm not sure whether you really want ~ or ~# here - it depends if body is supposed to be a sequence of expressions to execute in the let, or a sequence of arguments to a single function call. But ~# would be a lot more intuitive/normal, so that's what I'm going to guess.
Whether this macro is anaphoric is a little questionable: definitely introducing nv into the calling scope was, but it was basically unintentional so I would say no. In my revised version, we're no longer introducing nv or anything like it, but we are "magically" replacing :value with v. We only do that at the topmost level of the body, though, so it's not like introducing a real scope - I'd say it's more like making the client's code unexpectedly break in corner cases.
For an example of how this deceptive behavior can crop up, imagine that one of the elements of body is (inc :value). It won't get replaced by the macro, and will expand to (inc :value), which never succeeds. So instead I'd recommend a real anaphoric macro, which introduces a real scope for a symbol. Something like
(defmacro make [v & body]
`(let [~'the-value ~(some-calc v)]
~#body))
And then the caller can just use the-value in their code, and it behaves just like a real, regular local binding: your macro introduces it by magic, but it doesn't have any other special tricks.
It's not actually an anaphoric macro as I understand it.
An anaphoric equivalent would have give you a syntax like:
(make foo 1 2 3 4 it 6 7 it 8 9)
i.e. the symbol it has been defined so that it can be used inside the body of the make macro.
I'm not sure precisely if this is what you want because I don't have enough context on how this macro is going to be used, but you could implement the above like:
(defmacro make [v & body]
`(let [~'it ~v]
(list ~#body)))
(make (* 10 10) 1 2 3 4 it 6 7 it 8 9)
=> (1 2 3 4 100 6 7 100 8 9)
Alternatively, if you're not really trying to create new syntax and just want to replace :value in some collection, then you don't really need a macro: it would be better to just use replace:
(replace {:value (* 10 10)} [1 2 :value 3 4])
=> [1 2 100 3 4]
In your example, both some-calc and map happen during macroexpansion, not at runtime, thus nv does not need to be let anyway. The macro itself is not written properly, irrespective of anything to do with symbol capture.
One approach is to use a dynamic binding.
(declare ^:dynamic *nv*)
(defmacro make [v & body]
`(binding [*nv* ~(some-calc v)]
~(map #(if (= % :value) *nv* %) body)))
In practice, dynamic variables suck when their scope is too wide (it's harder to test and debug programs etc.), but in cases like this where the scope is confined to the local calling context where an anaphor is needed, they can be quite handy.
An interesting aspect of this use is that it's kind of the inverse of a common idiom of using a macro to hide a dynamic binding (many in the with-* style). In this idiom (which as far as I know is not all that common) the binding is used to expose something hidden by the macro.
Related
Imagine the following code to dynamically create a macro:
(def a (list '+ 1 2))
(def b (list '- 10 5))
(def c (list '/ 22 2))
(defmacro gg [h]
(let [k# `~h]
k#))
The intent is to pass a vector of symbols to a macro, do some evaluation on each element of the vector such that it returns a nice macro-esque form, then have the macro combine them into a nice macro and evaluate it. The above example works all except the actual evaluation.
When I run it I get:
(gg [a b c])
=> [(+ 1 2) (- 10 5) (/ 22 2)]
What is the secret to passing a symbol that is a list of symbols and getting a macro to evaluate them? I have tried lots of combinations of quoting and have yet to hit the right one.
The real purpose of this question is to build an Archimedes Ogre query based on a definition of a path through the graph. If someone has an example of that, I would be grateful.
EDIT:
(defmacro gg2 [h]
`(do ~#(map identity h)))
(macroexpand '(gg2 [a b c]))
=> (do a b c)
(gg2 [a b c])
=> (/ 22 2)
I was hoping to get 11 rather than the form.
You don't need a macro. Macros don't do what you're looking for here. What you are looking for is eval.
(def a '/)
(def b 22)
(def c 2)
(eval (list* [a b c]))
=> 11
Of course, you can write a macro which expands into (eval (list* ...)) if you want. It could just as well be a function though.
This is a very common mistake when starting out with macros; trying to write a macro which depends on the run-time value of its arguments. Macros run at compile-time, and generally the values of the symbols which you pass to a macro are not yet available when the macro is expanded.
About the use of eval, some cautions are in order. No one said it better than Paul Graham:
Generally it is not a good idea to call eval at runtime, for two reasons:
It’s inefficient: eval is handed a raw list, and either has to compile it on the spot, or evaluate it in an interpreter. Either way is slower than compiling the code beforehand, and just calling it.
It’s less powerful, because the expression is evaluated with no lexical context. Among other things, this means that you can’t refer to ordinary variables visible outside the expression being evaluated.
Usually, calling eval explicitly is like buying something in an airport gift-shop. Having waited till the last moment, you have to pay high prices for a limited selection of second-rate goods.
I'm learning Lisp from the book 'Practical Common Lisp'. At one point, I'm supposed to enter the following bit of code:
[1] (remove-if-not #'evenp '(1 2 3 4 5 6 7 8 9 10))
(2 4 6 8 10)
I suppose the idea here is of course that remove-if-not wants a function that can return either T or NIL when an argument is provided to it, and this function is then applied to all symbols in the list, returning a list containing only those symbols where it returned NIL.
However, if I now write the following code in CLISP:
[2] (remove-if-not 'evenp '(1 2 3 4 5 6 7 8 9 10)
(2 4 6 8 10)
It still works! So my question is, does it even matter whether I use sharp-quote notation, or is just using the quote sufficient? It now seems like the additional sharp is only there to let the programmer know that "Hey, this is a function, not just some random symbol!" - but if it has any other use, I'd love to know about it.
I use GNU CLISP 2.49 (2010-07-07, sheesh that's actually pretty old).
Sharp-quote and quote do not have the same behaviour in the general case:
(defun test () 'red)
(flet ((test () 'green))
(list (funcall 'test)
(funcall #'test))) => (red green)
Calling a quoted symbol will use the function value of the quoted symbol (ie, the result of symbol-function). Calling a sharp-quoted symbol will use the value established by the lexical binding, if any, of the symbol. In the admittedly common case that there is no lexical binding the behaviour will be the same. That's what you are seeing.
You should get into the habit of using sharp-quote. Ignoring function bindings is probably not what you want, and may be confusing to anybody trying to understand your code.
This is not CLISP specific, it works in every Common Lisp implementation (I use Clozure Common Lisp here).
What happens is that if you give a symbol as a function designator then the implementation will look up the symbol-function (assuming the symbol is available in the global environment) for you:
? #'evenp
#<Compiled-function EVENP #x3000000F2D4F>
? (symbol-function 'evenp)
#<Compiled-function EVENP #x3000000F2D4F>
In general you can use either, but there's an interesting effect if you rebind the called function later. If you specify the function (#' or (function)) then the calls will still call the old function because the lookup has been done at compile time; if you use the symbol then you will call the new function because the lookup is re-done at runtime. Note that this may be implementation-specific.
As you have noticed (or read) funcall et. al. are will make an effort to convert the function argument you provide into something approprate. So as you have noticed they will take a symbol and then fetch the symbol-function of that symbol; if that works out they will then invoke that.
Recall that #'X is converted at readtime into (symbol-function x) and 'x into (quote x). It's good practice to have the symbol-function work done at compile time.
But why? Well two trival reasons it is slightly faster and it signals that you don't intend to redefine F's symbol-function after compile time. Another reason is that in a recent Pew Research study 98.3% of Lisp developers prefer it, and 62.3% will shun those that don't do this.
But there's more.
'(lambda (..) ...) is quite different v.s. #'(lambda (..) ...). The first is very likely to end up using eval, i.e. it will be slow. The first runs in a different scope v.s. the second one, i.e. only the second one can see the lexical scope it appears in.
This question already has answers here:
What can you do with Lisp macros that you can't do with first-class functions?
(8 answers)
Closed 5 years ago.
In my quest to fully understand the so powerful lisp macros a question came to my mind. I know that a golden rule about macros is the one saying "Never use a macro when a function will do the work".
However reading Chapter 9 - Practical: Building a Unit Test Framework - from the book Practical Common Lisp I was introduced to the below macro whose purpose was to get rid of the duplication of the test case expression, with its attendant risk of mislabeling of results.
;; Function defintion.
(defun report-result (result form)
(format t "~:[FAIL~;pass~] ... ~a~%" result form))
;; Macro Definition
(defmacro check (form)
`(report-result ,form ',form))
OK, I understand its purpose but I could have done it using a function instead of a macro, for instance:
(setf unevaluated.form '(= 2 (+ 2 3)))
(defun my-func (unevaluated.form)
(report-result (eval unevaluated.form) unevaluated.form))
Is this only possible because the given macro is too simple ?
Furthermore, is Lisp Macro System so powerful relatively its opponents due to the code itself - like control structures, functions, etc - is represented as a LIST ?
But if it were a macro you, could have done:
(check (= 2 (+ 2 3)))
With a function, you have to do:
(check '(= 2 (+ 2 3)))
Also, with the macro the (= 2 (+ 2 3)) is actually compiled by the compiler, whereas with the function it's evaluated by the eval function, not necessarily the same thing.
Addenda:
Yes, it's just evaluating the function. Now what that means is dependent upon the implementation. Some can interpret it, others can compile and execute it. But the simple matter is that you don't know from system to system.
The null lexical environment that others are mentioning is also a big deal.
Consider:
(defun add3f (form)
(eval `(+ 3 ,form)))
(demacro add3m (form)
`(+ 3 ,form))
Then observe:
[28]> (add3m (+ 2 3))
8
[29]> (add3f '(+ 2 3))
8
[30]> (let ((x 2)) (add3m (+ x 3)))
8
[31]> (let ((x 2)) (add3f '(+ x 3)))
*** - EVAL: variable X has no value
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of X.
STORE-VALUE :R2 Input a new value for X.
ABORT :R3 Abort main loop
Break 1 [32]> :a
That's really quite damning for most use cases. Since the eval has no lexical environment, it can not "see" the x from the enclosing let.
The better substitution would be not with eval, which won't perform as expected for all cases (for example, it doesn't have access to the lexical environment), and is also overkill (see here: https://stackoverflow.com/a/2571549/977052), but something using anonymous functions, like this:
(defun check (fn)
(report-result (funcall fn) (function-body fn)))
CL-USER> (check (lambda () (= 2 (+ 2 3))))
By the way, this is how such things are accomplished in Ruby (anonymous functions are called procs there).
But, as you see, it becomes somewhat less elegant (unless you add syntax sugar) and, there's actually a bigger problem: ther's no function-body function in Lisp (although there may be non-standard ways to get at it). Overall, as you see, for this particular task the alternative solutions are substantially worse, although in some cases such approach could work.
In general, though, if you want to do something with the source code of the expressions passed into the macro (and usually this is the primary reason of using macros), functions would not be sufficient.
The report-result function needs both the source code and the result of the execution.
The macro CHECK provides both from a single source form.
If you put a bunch of check forms into the file, they are easily compiled using the usual process of compiling Lisp files. You'll get a compiled version of the checking code.
Using a function and EVAL (better use COMPILE) you would have deferred the source evaluation to a later time. It would also not be clear if it is interpreted or compiled. In case of compilation, you would then later get the compiler's checks.
Note: this is NOT about concurrency. This is about the thread macro.
I know that -> puts the object at the 2nd position and ->> puts the argument at the last position.
Now, I'm curious, much like the short hand notation of #( ... % ) for functions, is there a short hand notation for threads that lets me place the argument at arbitrary location?
The goal would be that instead of having a fixed location for the thread to run through ... I can write arbitrary forms, and insert %% at special places, and the %% is where the thread gets inserted.
Thanks!
There is now a generalized threading macro in Clojure since 1.5 called as->.
This tweet gives an example of how it works: https://twitter.com/borkdude/status/302881431649128448
(as-> "/tmp" x
(java.io.File. x)
(file-seq x)
(filter (memfn isDirectory) x)
(count x))
First 'x' is bound to "/tmp" and a file is made out of it. 'x' is rebound again to the resulting file and a put through the 'file-seq' function, etc.
The 'diamond wand' from Swiss Arrows library would do what you're asking for:
(-<> 0
(* <> 5)
(vector 1 2 <> 3 4))
; => [1 2 0 3 4]
That said, it isn't something you end up needing often (or ever in my Clojure experience)
In case anyone else comes across this, there is a reason the provided macros exist, but an arbitrary placement one does not: the latter would lead to poor API design.
The -> macro places the argument in the first position. This corresponds to functions that work on some subject argument, e.g., conj, assoc.
The ->> macro places the argument in the last position. This corresponds to functions that work on sequences, e.g., map, reduce.
Design your APIs well, and you'll be less likely to need such a macro.
There was a library that provided this feature, but I forgot where. It might of been in the deprecated clojure-contrib. It was the -$> macro.
But you could derive one from clojure's core -> macro to make the one you're looking for:
(defmacro -$>
([x] x)
([x form] (if (seq? form)
(with-meta (map #(if (= %1 '$) x %1) form) (meta form))
(list form x)))
([x form & more] `(-$> (-$> ~x ~form) ~#more)))
And use $ to indicate the insertion point:
user=> (-$> 2 str (identity $) (println $))
2
nil
Technically, you could use multiple $ in one form. But this implementation suffers from expanding the same form multiple times (in exchange for simplicity).
I'm a bit confused as to exactly when symbol capture will occur with clojure macros. Suppose that I have a macro which defines a function from keywords. In this trivial example,
(defmacro foo [keywd1 keywd2] `(defn ~(symbol (name keywd1))
[~(symbol (name keywd2))] (* 2 ~(symbol (name keywd2)))))
I call (foo :bar :baz), and this gets expanded into (defn bar [baz] (* 2 baz)).
So now the question -- can this lead to symbol capture? If so, under what circumstances?
I know that it's preferred to use gensym (e.g. bar#) to prevent symbol capture, but in some cases (not many, but still) I'd like to have a pretty macro-expansion, without the auto-generated symbols.
Bonus question: does the answer change if we are considering a macro that creates macros?
In your example symbol capture does not happen, because provide the variable parts as parameters. So the developer can choose the names himself.
Symbol capture happens when your macro introduces new locals which are not specified by the user. Consider the following (really silly and nonsensical just to show the point) example:
(defmacro foo
[name & body]
`(defn ~name
[~'bar]
(println ~'bar)
~#body))
In this case bar is captured. Now suppose the user has some code like this.
(def bar 5)
(foo baz (* 2 bar))
(baz 7)
This would not give what the would expect. Because the global bar, the user refering to gets shadowed by the local bar introduced by the macro. As you already said: in this case one should use bar# to introduce the local.
So capture is always indicated by ~'. Macro writing macros don't really change that. Just add one more level: ~~'.