4 ms·
Why are there two variations for ~> and ~>> ? It looks like it limits you to using only functions that take parameters in the same position. Why not have one p
by sbjs 8y ago
Why are there two variations for ~> and ~>> ? It looks like it limits you to using only functions that take parameters in the same position.
Why not have one position-independent version? Something where you can specify at every level which position you want to use, like this:
(~>>> #"foobar"
(~> bytes-length)
(~>> number->string 16)
(~> string->bytes/utf-8))
But that still only limits you to first and last position. Why not use a positional special form like JavaScript has with __dirname called __var?
(~>>> #"foobar"
(__var bytes-length)
(number->string 16 __var)
(__var string->bytes/utf-8))
This way you can use it no matter what functions you want. But I don't write my code in Racket so maybe this is already a solved problem.
- KingMob 8y agoClojure has that, it's called as->, and you specify a symbol to represent the previous result in each subform. But the first/last variants, -> and ->>, are still useful because they fit a subtle design decision in Clojure. Fns that operate on objects/scalars tend to have the object modified as the very first parameter, while collection-operating fns tend to have the collection last.
- robto 8y agoIn clojure, you can do this with as->, but there are reasons to be careful. Stuart Sierra has a great (brief) article about it[0]. The long and short of it is that it's really easy to change the "type" of an expression as it goes through your pipeline in unintuitive ways. This can cause surprises later down the line, so it's probably better to refactor the functions you are calling so that they play nicely with thread-first or with thread-last. [0]https://stuartsierra.com/2018/07/15/clojure-donts-thread-as https://stuartsierra.com/2018/07/15/clojure-donts-thread-as
- vijaykiran 8y agoDid you mean Stuart Sierra? :-)
- robto 8y agoWhoops! Clojure is the only community I know with a confusion of Stuarts.
- truncate 8y agoI feel the same way. I also tend to forget which macro inserts argument at front and which one at back. I tend to use threading[1] package for macros which does what you are proposing: [1] https://docs.racket-lang.org/threading/index.html#%28form._%28%28lib._threading%2Fmain..rkt%29._~7e~3e%29%29 https://docs.racket-lang.org/threading/index.html#%28form._%...
- greghendershott 8y agoThese days that's what rackjure re-provides: http://docs.racket-lang.org/rackjure/index.html#(mod-path._rackjure%2Fthreading) http://docs.racket-lang.org/rackjure/index.html#(mod-path._r...
- likeclockwork 8y agoAside from `as->` which mentioned by others, you can nest thread-last into thread-first if you need to and it behaves appropriately. (You can't go the other way for obvious reasons but it works when you introduce a collection.)
- jaccarmac 8y agoPeople have already described the form that already exists in Clojure, but it's worth mentioning that this kind of macro is called an anaphoric macro and is featured in Let Over Lambda (https://letoverlambda.com/index.cl/guest/chap6.html https://letoverlambda.com/index.cl/guest/chap6.html) and On Lisp. They tend not to be viewed as idiomatic Clojure. I would assume they are less used in Schemes since Scheme macros are hygienic by design and anaphoric macros depend on variable capture. That said I'm not a Schemer and may be wrong. These kind of macros are very much part of the Lisp heritage though.