>

There seems to be a general consensus that some sort of explicit form  
of threading would be useful. Below are snippets of other messages,  
outlining the remaining points. I should point out that we are not  
limited to one macro/function to handle our needs. For my own part, I  
think as written let-> can meet most if not all needs (and I'll make a  
case for it below), but there is certainly the option of writing a  
family of threading functions/macros for more specialized purposes.

> BTW, I completely agree about the utility of the pipe macro, though I
> can't make up my mind about which syntax I would prefer. I remember
> that Paul Graham discusses such a macro in On Lisp, using "it" as the
> parameter, but I forgot what is macro is called.


I believe Graham calls these "anaphoric" macros 
(http://www.dunsmor.com/lisp/onlisp/onlisp_18.html 
). His examples tend to use a specified identifier ("it"), though I  
think the concept can be considered more broadly to be when a macro  
creates a binding that the user can use. (As compared to the macro  
creating a binding with a gensym that the user never sees). In  
Graham's case, the identifier is fixed ahead of time. In the case of  
let->, the user specifies the identifier.

> Somewhat along the lines of what Miekel says, if the special symbol is
> not user-defined, the macro could be named after the special symbol,
> e.g. x->, or, (keeping with the the "threading the needle" metaphor in
> ->'s docs) ndl->, or with the pipe metaphor, P->. The latter has the
> advantage that capitals aren't idiomatic for variable names in
> Clojure.

I dislike this strategy for two related reasons: (1) It cannont be  
nested. Here is a pseudo-example:

(?-> 2 ... some computations ... (f (?-> ... I don't have access to  
the outer "?" anymore... )))

(2) Shadowing user bindings. If I bind ? to something in my code (e.g.  
(let [? (pred? foo)] (....))) the ?-> form shadows my definition,  
preventing access.

By asking the user for an explicitly named identifier, both of these  
issues can be avoided. This is not to say a ?-> form shouldn't be  
allowed in the family of thread functions, just that let-> as written  
as a distinct purpose.

> The advantage of such an approach is that there is no new syntax
> rule: the parameter placeholder is the well-known %. Another
> advantage is that it can be written as a function. Of course, the
> drawback is that all those functions cause a run-time overhead. Plus
> a macro makes for shorter syntax, which is part of its purpose.

On to functions and the % symbol. To begin with, I'm not sure there is  
any additional runtime overhead of the functional version. Just as  
many functions are created and called in them macro version. There are  
differences. The first is stylistic: The macro saves key strokes for  
longer pipes in the form of fewer # and/or (fn [x] ....) definitions.  
Not a big point. The second issue is that the functional version can't  
nest function literals. In the example, we see #(map inc %). That is  
all well and good if you are using predefined single arity functions.  
I tend to use function literals in (map) all the time. But the  
following is invalid: #(map #(+ 1 %) %). Using explicit variables,  
e.g. x, would give us (map #(+ 1 %) x), which is valid. I think this  
is a very important benefit of the macro form.

> Overall I prefer Meikel's
> suggestion of just having the one macro -> with ? appearing in lists.
> For singular functions you wouldn't need to specify the ? so in most
> use-cases it would be unchanged, and for multiple arity calls it would
> be very explicit and clear what the desired operation was.

I'm not entirely clear on this proposal. It does prompt me to consider  
a more complicated macro that inspects its arguments and provides  
several behaviors under one name. If the first arg is a symbol, it  
works like let->. If the first argument is a list, it works like ->.  
If the first argument is the keyword :last it behaves like pipe. This  
would be backwards compatible with the current -> implementation, but  
also allow for the additional functionality described in this thread.  
I think a good implementation would be to have the three behaviors in  
their own macros, and have the super macro dispatch to the appropriate  
version (mullti-macros anyone?).

Thoughts?

- Mark Fredrickson
mark.m.fredrick...@gmail.com
http://www.markmfredrickson.com







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