Fork me on GitHub
#beginners
<
2024-06-25
>
growthesque08:06:54

can you recommend a resource for learning how to do repl-driven development with clojure?

Jason Bullers15:06:21

I found it useful to watch people doing it who are clearly proficient with their tools: Lambda island videos, Arne (of lambda island) doing Advent of Code puzzles, parens of the dead on YouTube, etc

šŸ™ 1
āž• 1
seancorfield16:06:58

Depending on your tolerance for length, in videos, I did a long REPL-driven presentation for London Clojurians a while back https://youtu.be/gIoadGfm5T8?si=aFZ_CprlkY904jK7

šŸ™ 1
āž• 3
growthesque16:06:47

i will take a look for sure, thanks.

Leo E08:06:24

Hi all! How do you space out side effects like metrics from the main body code without ending up like the example below? It seems to me that the code below does not provide the reading logic =( but side effects also need to be done. What approaches do you use?

(some->>
 profiles
 (intercept-fn keep-profiles :invalid-profiles)
 (intercept-fn (partial filter-valid-emails main-db) :invalid-emails)
 (intercept-fn (partial remove-unsubscribed main-db) :invalid-unsubscribed)
 (intercept-fn remove-rejected :invalid-rejected)
 (first))
intercept-fn in the example wraps up the runtime calculation and send metric. I can remove the calculation of metrics inside the keep-profiles functions, but then the functions responsible for the logic lose their purity by performing side effects

phill10:06:38

You could represent legible (business) logic as a vector of steps keep-profiles, etc, etc., remove-rejected. And then in plumbing you could map the vector members to an intercept-fn-wrapped variant and compose the results of that mapping to achieve the some->> effect.

phill10:06:45

I think "Software Design for Flexibility" by Hanson & Sussman has something to say about this.. programs often built of parts that are legible to people of different disciplines.

šŸ‘ 1
growthesque11:06:43

is it objectively a code smell that clojure has very similar function names for certain things like vec vector and repeat repeatedly or is this something that I just don't get why it's good as a beginner?

daveliepmann11:06:13

The names are similar because the functions are similar, despite being different in important and useful ways.

daveliepmann11:06:21

To me it's a consequence of a large, useful standard library

growthesque11:06:46

well yes, but cognitively doesn't feel right, because it uses different forms of the same word, for different functions. just by reading them it's hard to figure out which is which. you could infer that repeatedly is the weirder one, since it doesn't use the more obvious name.

šŸ‘ 1
daveliepmann11:06:48

to me it's a good distinction: repeat the thing, or repeatedly do the thing

šŸ‘ 3
growthesque11:06:55

it's not a big deal, just wondering if people from other programming languages can actually read clojure and understand anything.

daveliepmann11:06:58

fair point. do you have jump-to-definition set up in your editor?

growthesque11:06:57

i probably do, I use calva, but haven't explored it much yet.

growthesque11:06:48

for now I rely on a cheatsheet in an odt file šŸ˜…

šŸ˜± 1
daveliepmann11:06:30

I still get tripped up on less-common parts of the stdlib, so jump-to-definition for this kind of repeat/edly situation is a crucial part of my interactive/REPL workflow. takes 2 seconds, doesn't interrupt my thoughts

growthesque11:06:58

is this like a popup with the fn info?

daveliepmann12:06:02

sort of ā€” CIDER has a keybinding to change the current buffer to go to the definition of the var your cursor is on. So i'll be in the company sourcecode hacking away, I see repeat or whatever that I can't remember precisely which one it is, I press M-. and I'm in the clojure.core source code where repeat is defined. I read a second to refresh my memory, then M-, and I'm back where I was. more here https://lambdaisland.com/blog/29-12-2017-the-bare-minimum-clojure-mayonnaise

growthesque12:06:51

isn't it much easier to look what it does in clojure.docs rather than how it's implemented?

jpmonettas13:06:47

@U05V9JANJQK if you use Calva you can https://calva.io/clojuredocs/ for the symbol under the cursor with a keystroke, which is probably better for beginners than looking at the source

āž• 3
daveliepmann15:06:01

> isn't it much easier to look what it does in clojure.docs rather than how it's implemented? Depends. If I need a quick disambiguation between repeat and repeatedly then jump-to-def is what I want because the docstring suffices. If I need examples then I go to clojuredocs.

šŸ™ 1
andy.fingerhut16:06:12

This requires a separate browser pane, vs. being inside your code editor/IDE, but you may find this cheatsheet useful https://jafingerhut.github.io/ Hovering the cursor over a name gives you the docs, and clicking on it takes you to http://clojuredocs.org with the same doc string, and some community-provided examples of use. Perhaps just as useful, the functions and macros are grouped together by similar or related functionality.

šŸ†’ 1
andy.fingerhut16:06:11

The officially released one can be found here: https://clojure.org/api/cheatsheet

daveliepmann16:06:21

Whoa, this is really cool

didibus21:06:50

One man's code smell is another man's perfume šŸ˜

didibus21:06:57

I think you can say either/or in this case. You need to use a lot of functions. Some of them are similar but different in small ways. The alternatives would be: ā€¢ Split them up into different namespaces ā€¢ Give them longer more descriptive names ā€¢ Make them one function that takes options These all have their pros/cons. I think the logic in "core" is that you kind of just learn these as vocabulary. And they are used so often, you want them on hand. If they were named too verbosely, it would get annoying seeing all these long names everywhere, etc.

Fredrik19:06:40

Just a small tip: My mnemonic for vec vs vector is that vec goes with seq (spelled similarly), in that they both take a collection and "converts" it to the wanted type, while vector is spelled out more like list , and both are constructors that take individual elements.