Agreed.
What I'd like to have is something that works like this:

(partial-pbm f ?sym? 1 ?x0 3)

that would produce (given 

(defn ?sym?                                                                 
                                                                            
                  
  [x]                                                                       
                                                                            
                  
  (and (symbol? x) (re-find #"\?[a-z][0-9]*" (name x))))   

(fn [?x0] (f 1 ?x0 x)). In other words: given a predicate that would
recognize use of free variables it would extract them and bind them in
fn form.

Clearly, I need a macro because ?x0 might not be bound in the context.

In that sense, the first example I gave does the exact thing I want.
However, I can't find a way to pass the predicate in, due to my inexperience
with macros, no doubt. So, the main question stands: how to deal with macros
where some of the passed-in parameters should be resolved without 
evaluating them.

Thanks for the help,
ranko


On Saturday, February 8, 2014 12:14:14 PM UTC-5, Gary Verhaegen wrote:
>
> When writing a somewhat complex macro, it is always a good idea to start 
> by writing the code you would like to write (using the macro), rather than 
> begin with the implementation.
>
> Could you perhaps provide an example use of the macro you would like to 
> have? Not one that works, obviously, but what you would like to be able to 
> write.
>
>
> On 8 February 2014 18:01, juan.facorro <juan.f...@gmail.com 
> <javascript:>>wrote:
>
>> When you use *`~p* what you are actually doing is  using the symbol of 
>> the predicate as a function. For example if you call *(partial-pbm f 
>> symbol? 1 x 3)*, the quote-unquote (`~) will return the symbol *symbol?* 
>> which 
>> is not what you want. What you can do is use the *resolve 
>> <http://clojuredocs.org/clojure_core/clojure.core/resolve>* function to 
>> get the var associated with that symbol, if it exists.
>>
>> I haven't tried this but the following should work:
>>
>>
>>
>>
>>
>> *(defmacro partial-pbm  [f p & args]   (let [argseq (flatten args)        
>> nargs (vec (filter (resolve p) argseq))]*
>> *    `(fn ~nargs (~f ~@argseq))))*
>>
>> Hope it help,
>>
>> Juan
>>
>> On Monday, February 3, 2014 8:09:55 PM UTC-3, r wrote:
>>>
>>> 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 clo...@googlegroups.com<javascript:>
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com <javascript:>
>> 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+u...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>
>

-- 
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