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 <[email protected]
> <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 [email protected]<javascript:>
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> [email protected] <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 [email protected] <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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.