Hello all,

For various reasons, and despite the convenience of anonymous functions,
I'd like to have a proper positional parameter binding partial function 
application. (Actually,
I'd like to have by-name parameter binding, but that's another story.)

For example, the following seems to work:


(defmacro partial-pbm
[f & args]
(let [argseq (flatten args)
nargs (vec (filter symbol? argseq))]
`(fn ~nargs (~f ~@argseq))))


and I can do my partials like:


   1. tools.core=>
   2.  
   3. tools.core=> (defn f [a b c] (/ a (- b c)))
   4. #'tools.core/f
   5. tools.core=> (partial-pbm f 1 x 3)
   6. #<core$eval2368$fn__2369 tools.core$eval2368$fn__2369@2d7cdb8>
   7. tools.core=> ((partial-pbm f 1 x 3) 2)
   8. -1
   9. tools.core=> (f 1 2 3)
   10. -1
   11. tools.core=>
   

And it is almost ok. However, I'd like to be able to pass in the
predicate that should recognize what the resulting function's new formal 
params
should be. In other words I'd like "symbol?" in the macro definition above 
to
be passed in. This brings me to the first, general, question (about macros):

This means that some of the invocation arguments to this macro should be 
evaluated, and some should not (e.g. the one specifying the predicate should
be evaluated/dereferenced to enable filtering, but the one specifying the
new formal parameters and constants for the rest should not, until the 
unbound variables in that param are safely captured in the param list of
the (fn ...) form). How is this, usually, resolved? Eval?

In other words: If there is a need to do some computation _before_ the
quoted (template) form of the macro, how is it usually done? Most
macros I've seen start with the quoted form.

Now, my various attempts to make this work have been quite confusing 
(and I thought I almost got this ...). 

First, it seems that the quote must move to the beginning, because
I can't find a way to refer to the actual function (predicate) passed,
not its symbol. Something like this fails:

(defmacro partial-pbm
[f p & args]
(let [argseq (flatten args)
        nargs (vec (filter `~p argseq))]
...)


which made me realize I don't understand the scope of `/~.

I can calculate this properly by:

(defmacro ppbm
  [f vp & argdef]
  `(let [argseq# (flatten '~argdef)
         nargs# (vec (filter ~vp argseq#))] 

(fn nargs# (~f argseq#))))

But this fails to compile with

CompilerException java.lang.IllegalArgumentException: Parameter declaration 
f should be a vector, compiling:(/tmp/form-init5231854403593049721.clj:1:1) 
,

and I'm unsure why. This type of error is obtained when one forgets [] 
parameter list in fn form. 
But if I try to print or examine (class, ..) stuff passed to (fn ...) form 
they seem correct. Furthermore,
this does not look all that different from the functional version at the 
beginning.

I'm going to InfoQ to re-watch all Macros talks, but if someone could 
kick-start me on this, it'd be much appreciated. 
 
Cheers!

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to