The Clojure operator '->', as I know it, is called 'thread-first'. And in Clojure it used to inject a value (as the first argument) into a provided expression. It then returns a result which will get piped through, in the same manner, to any additional expressions supplied.
There is also a thread-last '->>' which obviously injects the value as the last argument. It looks like you've decided that thread-last is more useful in Arc (which I would agree with) and have chosen the '->' operator.
I think that's a great idea.
For interest sake here are my conversions of thread-first and thread-last respecting Clojures implementation:
In Clojure, however, the thread-first operator works really well when querying deeply nested tables/hash-maps while in Arc these do not. This really is just because of the difference in hash-map/table implementations.
arc> (= animals (obj cat (obj toby (obj age 9))
dog (obj thaddeus (obj age 5))))
...
arc> (-> animals 'dog 'thaddeus 'age)
5
I believe this will work for your afn/recstring example, but the other one would be a little different:
arc> (-> [* _ 2] 3)
6
[note: I had to install arc to give this a try - not having used it for probably a year or so. So if it's really hacky my apologies, but took me 10 mins just to re-learn how to write even really basic expressions, and I certainly don't remember being very good with macros.]
Interesting! Clearly my knowledge of the clojure primitives was extremely vague; I wasn't even aware that they operated on forms rather than function values.
(-> "a b c d" upcase [replace _ "A" "X"] [split _ " "] first)
What's more, you could mix first and last because all the arguments are actual values rather than hacky s-exprs. I already used that in the second example above, if you look closely.
---
The one missing use case is this:
(-> animals 'dog 'thaddeus 'age)
Arc just has a different, retro-email solution for that:
animals!dog!thaddeus!age
Though it all unravels if one of the keys is a string. Ok, we could use some help here. But it feels like a separate mechanism; I would avoid mixing `(,form ,x) and `(,x ,form) in different paths of a single macro.
---
Hmm, even this isn't too bad:
(-> animals [_ 'dog] [_ 'thaddeus] [_ 'age])
You don't save typing compared to:
(((animals 'dog) 'thaddeus) 'age)
But the matching parens are closer together and so easier to read.
I agree, mixing `(,form ,x) and `(,x ,form) is really ugly and I do like
animals!dog!thaddeus!age
much better - I forgot arc could do that lol.
Also, if anyone were really caught up on the strings as keys hiccup, the idiomatic approach for arc would likely be this: http://arclanguage.org/item?id=13006. If one could only find a pleasant & available symbol.
Also, and I'm not sure, but I have a sneaking suspicion I might need to w/uniq those input args. I just didn't get that far into arcs' internals last night.