Itβs new episode Thursday! In our latest episode, we wonder: must simple be simplistic? What is idiomatic composition? What does Clojure already know, and what do you have to teach it? https://clojuredesign.club/episode/095-composing-core/ Take a look and let us know what you think.
I end up with very similar blocks as well. I find the biggest problem, is walking through each step in blocks with new data that is failing for some reason. I have not found a way of inspecting the state at each step (or all of the let blocks inside any one of these function calls) in a way that is easy to navigate. I the comment above, "@pez suggested using "taps", and I have heard @seancorfield using portal and similar things. I'm curious what everyone else's suggestions are.
Happy to talk more about that, since I'm a heavy user of tap> (even before I started using Portal).
Inside a -> pipeline, you can (doto tap>) or even (doto println) but inside ->> it's a bit harder. I guess you could (map #(doto % println)) inside ->> (or use tap> instead of println).
If you switch from ->> to transducer pipelines then you can avoid all the intermediate sequences but not every sequence function is amenable to that (`frequencies`, for example).
I will note that AoC (and Exercism etc) tend to focus on problems that are not exactly real-world so you tend to get artificially dense code solving them, compared to what you might find out "in the wild".
Good stuff ππ» one thing I still have a bit of trouble with is where/when/how to wrap up "units" of composition. I think I've got the hang of the "teach Clojure" part, and it's so nice and simple (and easy) to have these little, testable functions that work on a single input. Using them with the core functions gives a lot of power, as you noted. But then what tends to happen for me is that, since I'm just kind of plugging away with my repl, I end up with these long threading macros that take me from input to final result. It's really nice and easy to work with, and satisfying to get that result out the other side, but I don't think it's particularly readable in a future-proof sense. The piece missing I suppose is to chunk up the pipeline and then compose those chunks. I find trouble naming those pieces sometimes, though. And also, if the pipeline is being chunked, then I'm kind of back to working with aggregates again. Maybe the "trick" is to reduce the number of steps in the pipeline by leveraging transducers? I don't know. Does my problem make sense? I'll try and find an example.
Here's an example: https://github.com/jbullers/advent_of_code/blob/main/src/advent2021/day05.clj Notice near the bottom there's chunky threading macros. I feel like these require a lot of brain cells to figure out when I come back to it
Wow, I had not heard of tap> before. Looks useful with println. I have the same issue trying to figure out what's coming through through a pipeline when reading code.