Fork me on GitHub
#babashka
<
2022-03-07
>
craftybones15:03:28

Quick question. How do you deal when you need to do something both imperative and functional in one iteration of a loop? Say I am iterating over a list of dirs, I need to git pull and generate some reports that I then return as a vector.

1. (map #(do (git-pull %) (generate-report %)) dirs)
2. (do (doseq [d dirs] (git-pull d)) (map generate-report dirs)) ;; yuck, iterating twice

jumar15:03:39

I would use mapv or a transducer.

craftybones15:03:20

Why a mapv specifically? It isn’t lazy, but other than that it doesn’t make a difference here?

craftybones15:03:36

my generate-report returns a vector

craftybones15:03:36

a transducer is interesting, but the git pull has to happen before anything else, so I am not sure it might directly help

borkdude15:03:59

I think either map or mapv is fine, as long as the git pull happens in the same "scope" as the report

craftybones15:03:24

It does. The only reason I don’t like it is it feels odd sticking something imperative like this in a map. Just something about it feels odd 😄

borkdude15:03:38

prefer arguments over dynamic vars, laziness doesn't play well with that combination

borkdude15:03:08

(just a general advice)

craftybones15:03:12

Yeah, nothing dynamic. Its all within one fn call with all arguments passed in

craftybones15:03:33

It is more a stylistic thing. I see this a lot more with Babashka because you tend to do slightly more imperative things with it

craftybones15:03:43

so I was not sure what you’d choose stylistically

craftybones15:03:37

Thanks @U04V15CAJ - Babashka is fantastic.

craftybones15:03:06

As are so many of your other libraries that get so much usage!

borkdude15:03:52

a new example of laziness + side effects (querying an API) in 1.11 is iteration

craftybones15:03:25

I read the Juxt blog on it. It is a similar problem but a slightly different use case since I sort of know what I am iterating over. But thanks for reminding me

jumar16:03:12

mapv specifically because it isn't lazy - I saw it way too many times that laziness escapes scope of a function it should not. but for more complex pipeline I'd consider a transducer. Otherwise I don't see anything super-weird with using a "mapping" operation for side effects.

alexdavis16:03:50

I don’t think I mind the doseq to do the side effects and map to generate the sequence, yes its not efficient but it just doesn’t matter in most cases, unless you’re literally iterating over many thousands of files (but surely git pull itself is slow enough that you won’t even notice how long the map part takes)

craftybones16:03:15

I have nothing complex, and I love transducers and use them all the time, but I’d not thought of the laziness call here. Will definitely consider mapv

craftybones16:03:03

@U7KPK060K - I know right? that’s what I thought so too initially, but after a while, not so sure about that solution

alexdavis16:03:20

I think code should be readable first, fast second. But probably in this case I would do both in a mapv, but I wouldn’t mind too much if I saw the doseq version

alexdavis16:03:52

I’ve definitely made the mistake of trying to use map or for and getting caught out by the lazyness before

craftybones15:03:00

Which would you prefer? Is there a better alternative here?

madstap22:03:48

I want to copy some text to the clipboard, but

(java.awt Toolkit)
(java.awt.datatransfer StringSelection Clipboard)
aren't currently available in bb. Is it possible to add them? Or is there some other way to copy to the clipboard?

borkdude22:03:37

There has been a discussion on this in this channel not too long ago. Use the search for more info.

👍 1