On Tue, Jan 27, 2009 at 9:20 AM, Daniel Jomphe <danieljom...@gmail.com> wrote: > > Michael Wood wrote: > >> I've seen various code snippets where people use something# in >> functions. Is there any point to this or gensym except in a macro?
The suffix# isn't made useful by being in a macro, but by being in a syntax-quote. user=> `foo# foo__211__auto__ Note that the # was expanded into a unique symbol suffix. However using a # outside of a syntax-quote, such as in a regular function doing a regular 'let', doesn't really buy you anything: user=> 'foo# foo# > If anyone could chime in and tell me if macros are the only out of > this problem, that would be really great. To simplify the problem to > its essence, let's say I'd like, without using macros, the following > to print better: > > (print (first [= 1 2])) > #<core$_EQ___2886 clojure.core$_eq___2...@830122> > > Hey, I just found out the following works: > > (print (first '(=))) > = The difference is in the quoting. Within [] each symbol is evaluated. If = were at the head of a list, the whole list would be evaluated as a function call: user=> [1 (= 2 3) 4] [1 false 4] But since = is *not* appearing at the head of a list, Clojure sees that it's the name of a Var and evaluates it as the object currently stored in that Var. Specifically the equality function. And functions print ugly: user=> = #<core$_EQ___3139 clojure.core$_eq___3...@1722456> Moreover, there's very little useful information that you can currently get out of a function object. There's not even any metadata or simple name. About all you can get is the string you see above. So the problem is that by allowing the = to be evaluated, you've lost some information that in this case you still want. This is analogous to what would happen if you want to assert on a more complex form, like (+ 1 2): user=> (+ 1 2) 3 By the time it's evaluated, all you have is the Integer 3; you've lost the information about the form that produced it. This is exactly the benefit of quoting. It allows you to pass an unevaluated form to a function: user=> '(+ 1 2) (+ 1 2) user=> '= = Of course now you have the opposite problem -- you've got the form, but now you would still like to be able to evaluate it. You might choose to use 'eval' directly: user=> (defn form-and-val [x] {:form x :val (eval x)}) user=> (form-and-val '(+ 1 2)) {:form (+ 1 2), :val 3} ...but eval is not recommended unless really necessary. Also note that as already described, I had to quote the arg. And it's not necessary here, because this macros solve two problems at once. First, the value they return is code that will be compiled at the same time as the rest of the code that uses your macro, so no extra eval or compile step is needed. Second, the values passed to a macro act as if they'd already been quoted, so users of your macro don't need to quote them explicitly. user=> (defmacro form-and-val [x] `{:form '~x :val ~x}) user=> (form-and-val (+ 1 2)) {:form (+ 1 2), :val 3} No quote, no eval. Trying to avoid writing macros as much as possible is a great rule of thumb. But in this case I think it's justified. --Chouser --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---