My reasoning was that basically, regardless of the threading macros, you are going to have to learn to read/write s-expressions as-is for a couple of reasons:
1. The threading macros won't be the best way forward in all cases. 2. You're going to need to read other people's code, which wasn't using the macros.
Overall, I was trying to make the point that it is a real hurdle (at least that's how it felt for me), but worth getting over. As a week or so later, you can read s-expressions with relative ease. That it's worth making the effort, because they are pretty awesome. Maybe I just didn't communicate that very well.
(->> (range 10)
(map (fn [x] (+ x 2)))
(reduce +))
And then later on you can explain the #() shorthand (-<> (range 10)
(map #(+ % 2) <>)
(reduce + <>))
[0] https://github.com/rplevy/swiss-arrowsIt's more common in functional languages and called a thrush or pipe operator.
F#:
[|0..9|] |> Seq.map ((+) 2) |> Seq.sum
Javascript (Ramda): R.pipe(R.range(0,10), R.map(R.add(2)), R.sum)();
//With slightly more magic
let {pipe, range, map, add, sum} = R;
pipe(range(0), map(add(2)), sum)(10);The problem is that -<> looks like a regular function call, but does things that a function call can't do. In a language without macros, which are most of the mainstream ones, <> would have to be a language feature, and then it's not clear why you'd need to use -<> to 'activate' it.
Now, I've read enough about Lisp and AST and such to understand what a macro is, but the concept doesn't map easily to mainstream languages.
(as-> (range 10) _
(map #(+ % 2) _)
(reduce + _)) _.flow(_.range(0,10), _.map(_.add(2)), _.sum)();
//With slightly more magic
let {flow, range, map, add, sum} = _;
flow(range(0), map(add(2)), sum)(10); [1,2,3,4,5,6,7,8,9,10]
.map(function (x) { return x + 2 })
.reduce(function (a, b) { return a + b })
so the "." in OOP ends up working like "->" or "->>". Heck, you can make the dot in OOP code behave like anything, even like monadic bind (`>>=` or `do` notation in Haskell), if you do OOP-style-monads in JS: https://www.youtube.com/watch?v=b0EF0VTs9Dc(off-topic: this is also my main problem with OOP... the "." can actually end up meaning anything practically, as program logic is concerned, it's like some kind of "infinite operator overloading" :) )
"foo->" means exactly the same thing as "(*foo)." That is, you use "." when you have an object, and "->" when you have a pointer to an object.
I don't know of any other OO language that uses "->". If there is one, my comments here probably do not apply to it...
(Or were you talking about the "." as used in OO, compared with the "->" as used in Clojure? If so, disregard this comment...)
I'm afraid I was :)
Newcomers should learn the underlying ordinary evaluation first.
..because some people were even smart enough to pull this off: http://www.nand2tetris.org/ :)
(reduce + (map (comp inc inc) (range 10)))
Is the following a correct Haskell equivalent? foldr1 (+) (map (succ.succ) [1..10])
This is almost close to showing a code snippet like this to someone trying to learn Haskell:
(it only prints the powers of 2, but it was enough to scare some people into calling Haskell “the Taliban version of ML”... http://www.theregister.co.uk/Print/2012/12/21/financial_soft...)...really, people, stop scaring learners away!