(defmacro ->
([x] x)
([x form] (if (seq? form)
(with-meta (replace {:? x} form) (meta form))
(list form x)))
([x form & more] `(-> (-> ~x ~form) ~@more)))
This allows for a more flexible threading operation:
user> (-> "c"
(third-param "a" "b" :? "d")
println)
first a second b third c fourth d
nil
Cheers
Andreas
The usual objection centers around the fact that whatever symbol is
used for the binding position then becomes a "varying" thing within
the expression:
(-newthread-> "x"
(str "y" :? "z")
(str "a" :? "b")
println)
Here :? means two different things which seems counter to how Clojure
works elsewhere...
Sean
Anyway, I'll delete this evil hack from my repository ;)
> --
> 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
> 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
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
But _ means "don't care" by convention in Clojure, for values that are
ignored...
The issue is about bindings and immutability: foo should mean the same
value throughout an expression - that's kind of fundamental to Clojure
(IMO). With your macro (and the previous examples introduced by
others), some arbitrary symbol changes its meaning in each consecutive
form without any marker for lexical or dynamic binding... so it's
behaving like a mutable iterator or loop variable :(
With only a couple more characters you can already do what you need
without a new macro:
(-> "x"
(#(str "y" % "z"))
(#(str "a" % "b"))
println)
There's also the possibility of mixing -> and ->> to splice in first
arg / last arg threading. There was a great blog post about this
recently but I can't find it (-> and ->> are remarkably hard to search
for on Google!)...
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/
Railo Technologies, Inc. -- http://www.getrailo.com/
"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)
> On Mon, Jul 18, 2011 at 5:41 PM, Andreas Kostler
> <andreas.koe...@gmail.com> wrote:
>> Ups, I'm not aware of that thread...I just found a more general threading operator handy sometimes.
>> I do kinda agree that we shouldn't necessarily encourage threading in arbitrary positions.
>> However, I can't quite follow your second argument.
>> While it does mean two different things, I don't see the problem with that.
>> We could use _ instead of :? to indicate we don't care about the 'meaning'.
>
> But _ means "don't care" by convention in Clojure, for values that are
> ignored...
>
> The issue is about bindings and immutability: foo should mean the same
> value throughout an expression - that's kind of fundamental to Clojure
> (IMO). With your macro (and the previous examples introduced by
> others), some arbitrary symbol changes its meaning in each consecutive
> form without any marker for lexical or dynamic binding... so it's
> behaving like a mutable iterator or loop variable :(
I agree with that, however, :? or _ or whatever doesn't bind to anything. It merely gets replaced.
-> already does this in a hidden way...e.g. there's no symbol but the meaning of 'first argument' changes
in each consecutive form.
>
> With only a couple more characters you can already do what you need
> without a new macro:
>
> (-> "x"
> (#(str "y" % "z"))
> (#(str "a" % "b"))
> println)
Here, the meaning of % changes?!?
>
> There's also the possibility of mixing -> and ->> to splice in first
> arg / last arg threading. There was a great blog post about this
> recently but I can't find it (-> and ->> are remarkably hard to search
> for on Google!)...
I agree :)
> --
> Sean A Corfield -- (904) 302-SEAN
> An Architect's View -- http://corfield.org/
> World Singles, LLC. -- http://worldsingles.com/
> Railo Technologies, Inc. -- http://www.getrailo.com/
>
> "Perfection is the enemy of the good."
> -- Gustave Flaubert, French realist novelist (1821-1880)
>
In this particular case, I'll bet that someone has an arbitrary threading macro in a library somewhere you can use…or, you can create such a library. Given the number of times this has come up, I'm certain it would find some love.
- Chas
Given the number of times this has come up, I'd say it's evidence that
something similar really should be in core -- just this once.
I'd go for one that uses a normal symbol, e.g. (-x> a (expr1) (foo a
3) (bar :k a 7) ...) where the symbol to be bound is explicitly
provided by the user.
It isn't desired that often, since collections tend to be the last
argument and maps tend to be the first, but there are some cases where
one changes type partway through (e.g. works on a collection, then
extracts an element and works on that) or a function takes an argument
in an awkward place (e.g. nth takes the collection first, not last).
And as we've noticed, it keeps getting reinvented regularly by new
people.
I actually rarely use any of the threading macros myself, mind.
--
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.
Not really, each #() is a scope for % as if it read:
(-> "x"
((fn [x] (str "y" x "z")))
((fn [c] (str "a" c "b"))
println)
Yeah, sorry, I kinda jumped on the negative instead of encouraging
this to go into a community library :(
> In this particular case, I'll bet that someone has an arbitrary threading macro in a library somewhere you can use…or, you can create such a library. Given the number of times this has come up, I'm certain it would find some love.
This is the third(?) time so you are probably right. This might be a
good place to start:
https://github.com/pallet/thread-expr
No, it probably just hasn't gotten to everyone yet...? I see it on the web:
http://groups.google.com/group/clojure/browse_thread/thread/949abab9c206dc1a
No, please don't apologize. I'm sorry for discouraging you :(
I really hope thread-expr picks this up...