Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.


Clojure 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.


In 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


Did you mean Stuart Sierra? :-)


Whoops! Clojure is the only community I know with a confusion of Stuarts.


People 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) 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.


Aside 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.)


I 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._%...


These days that's what rackjure re-provides: http://docs.racket-lang.org/rackjure/index.html#(mod-path._r...




Consider applying for YC's Winter 2027 batch! Applications are open till November 2.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: