Fork me on GitHub
#beginners
<
2020-03-04
>
gibb05:03:16

@tylertracey09 Datomic cloud could fit your usecase. Manged infrastructure if you desire it (or just run it locally to start), fits well with event sourcing and most of all fits well with Clojure.

💯 1
jlmr08:03:03

Hi, is there a way I can apply doall recursively? I would like to catch any exceptions that may occur upon realizing the returned data from a function (let’s call it f. The problem is that f might call other functions (which might call other functions etc.) returning lazy sequences which “escape” my catch.

andy.fingerhut08:03:38

Are you wanting something that works for one particular situation, or you are trying to handle an arbitrary return value that could be any kind of nested collection(s)?

andy.fingerhut08:03:06

For example, if you want to handle a case where f always returns a sequence, and some of the elements might be lazy sequences, but nothing nested any further deeply than that you suspect is a lazy sequence you want to force, you could use (doall (map doall (f arg1 ...)))

andy.fingerhut08:03:26

If you want something that can handle lazy sequences nested arbitrarily deeply, but you know that all of them are in a short list of different types of collections, e.g. maps, sets, vectors, and/or sequences only, then you could look into something like (clojure.walk/postwalk doall (f arg1 ...))

andy.fingerhut08:03:07

Or actually not that, but replace doall with a function that only calls doall if the argument is not a vector, map, or set, since those are never lazy.

jlmr09:03:46

What would be the best predicate for that? Could I use something like:

(fn [x] (if (not (realized? x)) (doall x) x)
?

jlmr09:03:59

@andy.fingerhut, thanks! I am indeed trying to handle an arbitrary return value. Will look at the postwalk solution later today,

noisesmith16:03:41

(dorun (tree-seq coll? seq x)) should realize recursively every lazy thing in x (edit - forgot some args)

jlmr20:03:23

Thanks, this one works! 🙂

jlmr20:03:54

I had come up with

(clojure.walk/postwalk (fn [x] (if (seq? x) (doall x) x))

noisesmith21:03:24

postwalk uses that same coll? condition but it also would recreate your structure which isn't strictly needed and might be a detriment

noisesmith21:03:11

you know, (postwalk identity x) would already realize the entire coll now that I think of it...

noisesmith21:03:33

otherwise it couldn't fulfill it's behavioral contract

noisesmith16:03:14

unless x contains a non-clojure object that in turn contains something lazy.... - but for the common case where you have layers of native clojure coll types it would get them and due to the args I forgot, you could special case the types of containers you expect by replacing coll? with a new predicate and seq with a new extraction function

Scott Starkey21:03:41

Hi folks - I have a lazy sequence of letters that I’m going to use for a regex matcher. It’s basically every combination of 13 letters (done with clojure.math.combinatorics) so:

(take 3 alpha-combo)
=>
(("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m")
 ("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "n")
 ("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "o"))
However, I’d like the output to look more like a regex, so I get something like:
(take 3 alpha-re)
=>
("[abcdefghijklm]" "[abcdefghijkln]" "[abcdefghijklo]")
I’m close, if I do it one at a time, like:
(apply str (first alpha-combo))
=> "abcdefghijklm"
Can someone help me over the last couple of hurdles? Thanks!

Scott Starkey21:03:24

Maybe looking at the above dorun command, I think I can use that…

chrisulloa21:03:03

maybe (map str (take 3 alpha-combo))

chrisulloa21:03:03

ahh laziness

Scott Starkey21:03:12

LOL yes, my enemy!

bfabry21:03:21

(map (fn [group] (str "[" (apply str group) "]")) alpha-combo)

Scott Starkey21:03:23

Oof, yes!!! map!

chrisulloa21:03:17

map then take would work i think

Scott Starkey21:03:52

That worked splendidly!

(def alphas
    (map (fn [group] (str "[" (apply str group) "]")) alpha-combo))
=> #'further-testing.core/alphas
(take 5 alphas)
=> ("[abcdefghijklm]" "[abcdefghijkln]" "[abcdefghijklo]" "[abcdefghijklp]" "[abcdefghijklq]")

noisesmith21:03:55

(map (partial apply str) ...)

noisesmith21:03:12

oh you want the brackets, OK

bfabry21:03:32

no worries