I guess I'm alone on this, but I want as little special syntax as possible, it's the primary thing I like about Scheme. ' ` , # <- that's enough, let's stop there. Everything else should be in an s-expression.
Clojure does have a number of sigils and special syntax, but they all seem to have s-expression alternatives. e.g. a dict can be created with {:a 1, :b 2} or (hash-map :a 1, :b 2); dereferencing an atom can be done with @a or (deref a) and so on.
Part of the joy of Racket is that you can mix and match :-)
In some cases, it allows people who like some of the Clojure syntax to still write you libraries. In other cases it allows you to move a prototype from normal Racket to Typed Racket in a piecemeal way.
In general I like the purity of scheme as well, but sometimes that little bit of syntactic sugar goes a long way. Non-Racket Schemers use macros too, and Racket’s are second to none. Use what you want and avoid the rest!
It's not special syntax just because the identifier is some symbols. If you don't like the semantics, don't use it; but it's not correct to accuse it of being "special syntax".
Edit: oh, and if you _do_ like the semantics, but hate the weird name, just give it a new name that makes sense to you.
In my opinion one of the primary characteristics of Clojure is the implementation of the collection types. Without that it's not going to be an implementation of Clojure to me.
On the other hand the author is pretty explicit that this is a limited borrow from Clojure, and that when in conflict, he’ll do the more Rackety thing.
It started as a Scheme R5RS implementation in Java, then I translated everything to Kotlin. Finally, decided to make it a hybrid (abomination?) of Scheme and Racket and Clojure.
Still in development, don't know how to implement macros properly. Also, it's only an interpreter for now, there is no compiler (for the same reason: don't know yet how to write a compiler for Kotlin. Use ASM?)
Anyway, it is a great and enlightening experience and I would recommend everyone to write your own lang.
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.
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: