Thanks, I realize my example is a bit of a corner case, and feels a
little artificial:) It came after some narrowing down a larger problem

Another thing that appeared curious to me, is that Clojure apparently
counts unique %'s inside the #() definition to determine arity of the
macro. But does this mean that macros with no arguments should be
legal?
How about this:

(#(true)), is this not calling a function that has no arguments and
returns true? But it still gives same exception

<CompilerException java.lang.ClassCastException: java.lang.Boolean
cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)>

I come from Scala experience, where it is easy to define a quick
lambda function returning a constant or another simple expression,
e.g. "=> true" is a function with no args and returning true. Things
like that are sometimes useful to pass into higher-order functions
expecting a function, not a constant. I guess I should forgo the macro
and go directly with (fn  [] true)

I think all of this confusion could have been avoided if the compiler
did a better error message, e.g. actually citing the definition of #()
and what it expanded into? Would improve usability. Even macroexpand
does not provide any useful info in this case...

Certainly macros are not for the fainthearted anyway, but all
literature seems to go into #() really fast, so it will be stumbled
upon by novices

Julian

On Sep 6, 12:44 pm, Laurent PETIT <laurent.pe...@gmail.com> wrote:
> 2011/9/4 julianrz <julia...@yahoo.com>
>
> > Hello All,
> > I am new to Clojure. Surprised why this code does not work:
>
> > user=> (filter #(%) [1 2 3])
> > ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn
>
> > Here my intent behind #(%) is to define a lambda function returning
> > its argument. Since Clojure defines truth on any type, it should be
> > acceptable as filter function, and the result should be the original
> > array
>
> > Some narrowing down. What's #(%) really good for?
>
> Hello,
>
> #(%) is a macro which expands to (fn* [p1#] (p1#))
>
> #(%) could only be 'useful' if % is a callable without arguments.
>
> What you seem to be after is the builtin function named identity : identity
> returns its argument :
>
> Clojure> (filter ident­ity [1 true false­ nil])­
> (1 true)
> Clojure>
>
> HTH,
>
> --
> Laurent
>
>
>
> > user=> #(%)
> > #<user$eval48$fn__49 user$eval48$fn__49@5e2c17f7>
>
> > so it is a function
>
> > user=> (#(%))
> > ArityException Wrong number of args (0) passed to: user$eval26$fn
>
> > Ok, here not enough arguments supplied, fair enough. Let's fix that:
> > user=> (#(%) 1)
> > ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn
>
> > Same problem as the first example. So Clojure understands this is a
> > function, knows it takes some arguments, but cannot call it? What's
> > wrong? The following works:
>
> > (user=> (filter (fn [a] a) [1 2 3])
> > (1 2 3)
>
> > So apparently it has something to do with the fact that #() is
> > shorthand. So in my case, it produces a function which cannot be
> > used... In fact, it seems to just yield the constant, not a function.
> > Ask me, it should work (auto-wrap the constant in a function) or the
> > expression should be illegal. I think it deserves better
> > diagnostics...
>
> > Also, in Practical Clojure book, it says: "The shothand function form
> > #(* %1 %2) is actually identical to the longer form (fn [x y] (* x y))
> > before it is even seen by the compiler." If you literally apply this
> > rule, you will get
>
> > ((fn[x] (1)) 1)
>
> > which throws same exception, not surprisingly, since it tries to
> > evaluate 1 as a fucntion. What it should have done is transform the
> > expression into
>
> > ((fn[x] 1) 1)
>
> > which works fine... Special-case it?
>
> > What do you think?
>
> > Julian
>
> > --
> > 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
> > Note that posts from new members are moderated - please be patient with
> > your first post.
> > 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

-- 
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
Note that posts from new members are moderated - please be patient with your 
first post.
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

Reply via email to