This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
You know what might be nice? An thread macro that can optionally escape forms, like
(-> n dec #esc #(- 9 % 1) inc)
such that, instead of the value being threaded into the beginning or end of the anonymous function, the fn is allowed to convert itself into its evaluated form, and the thread sees it as a one arg fn.
(-> n dec #esc #(- 9 % 1) inc) it's not all that different -- and it's built-in, no language extensions needed
(-> n dec #~(- 9 % 1) inc) that might look prettier... and I wouldn't have to switch between two different thread macro contexts
Meh... you've saving so few keystrokes, and introducing non-standard syntax... I see no benefit.
(-> n (- 3) dec (->> (assoc state :n)) keys) (-> n (- 3) dec (as-> % (assoc state :n %)) keys) (-> n (- 3) dec #~#(assoc state :n %) keys) ; more cryptic and only one character shorter?
I hear you, I'm not completely sold on it either... I'd have to kick the tires on it some more.
And I'm not saying add a reader macro for
#~ language wide. Just add another thread macro that detects it, like
-#> or something
Don't get me wrong, I find
(partial f a b) to be annoyingly long, as well as
(comp f g), compared to Haskell's auto-currying and therefore
f a b and
f . g but it really isn't worth messing up the language syntax for a few characters of typing...
It's not about saving characters. It's about semantic context switching between various thread macro semantics
I find this much more readable than your proposal
(-> n (- 3) dec (->> (assoc state :n)) keys)
There's also a strong argument that such long threads are inherently hard to read already and should be broken into named segments with
hmmm. perhaps the idea could be further generalized and simplified... Perhaps
-#> could just evaluate all anonymous functions defined within the thread first ... then it's just
(-#> n #(- 9 % 3) dec #(assoc state :n %) keys)
It makes sense though... It's a thread macro that auto-evaluates anonymous functions first.
I know you're just saying that to goad me into writing a library for it... And I'm not gonna do it!
(as-> n % (- 9 % 3) (dec %) (assoc state :n %) (keys %)) is also horrible but at least it's consistent (and, hey, already possible/legal in Clojure).
well, I guess that
-#> is pointless, since it's basically just doing function application, just unwinding it, for less parenthesis
Consistency has had me recently move to wrapping all the forms in
( .. ) in a threaded macro BTW.
The more code I maintain, the more consistency and simplicity have come to matter.
And we're at
Clojure source 280 files 65913 total loc, Clojure tests 320 files 22004 total loc,
(nearly 88k lines... that's quite shocking to me, really, given where we were just a few years ago!)
(and, of course, Clojure 1.10 in production, and testing against 1.11 master 🙂 )
I guess that last
-#> I described is really
comp>. It reverses the order of comp, so it reads like definition order, but allows you to thread in forms in the comp that are not functions.
so when i notice I'm Doing It Again i rewrite the whole thing with lets to see which is simpler
When it comes to weird threading macros, this library is funny https://github.com/rplevy/swiss-arrows
My issue with using
lets instead of threading macros is it allows me to write more procedural/pythonic code, instead of finding a functional way to write it
I’ve been working on a lot of ETL pipelines recently, so extracting my complicated
let conditionals into functions I can thread has been very helpful in maintaining the functional mindset
To store clojure data structures in a database (postgresql in my case), would you just store the EDN representation or encode it with transit?
@hmaurer using transit json-pretty gives you the option to query it in the future if you please.
When I try to require a namespace in the REPL but it fails because of a syntax error in said namespace’s file, how can I reload it after correcting the error? running require again throws a “namespace not found” error
I have probably a silly question:
(let [foo (my-macro)] ...)
my-macroto know that it has been bound to the symbol
fooin this context. Impossible, yes?
OK, followup: is there any way (hacky or otherwise) to get at the let bindings inside of a function?
I have a lib where I’d like to provide some report of how it’s used inside of an opaque function
using some fancy tricks I can show what was passed in when the library functions were invoked, and the order of invocation, but I’m losing some semantics because there’s no names attached to them
[ANN] com.cognitect.aws/api-0.8.243 is released: https://groups.google.com/forum/#!topic/clojure/wzEy8tSSKF0
it would still be hard to know exactly what name it was bound to, but that could be hilariously hacky