Fork me on GitHub
#clojure-uk
<
2017-06-27
>
thomas07:06:01

morning 😼 mogge

thomas07:06:03

@maleghast I just looked it up on the map.... just one word... WOW!!!

yogidevbear08:06:46

Anyone here watched Collateral Beauty? Saw it last night. I thought it was really good (bit of a tear jerker)

maleghast09:06:47

Morning All 🙂

maleghast09:06:16

@thomas - Yep; I am a lucky bugger (who pays for it by travelling a LOT, but I am not even CLOSE to complaining 😉 )

maleghast13:06:31

Does anyone have a neat way of creating a map from a vector of keys where all the values are nil..? I've already figured out that (zipmap coll emptycoll) returns an empty map 😞

otfrom13:06:53

(zipmap coll (constantly nil))

peterwestmacott13:06:35

constantly -> repeat ?

maleghast13:06:40

Oh I like that, @otfrom

maleghast13:06:45

I will try, thanks

maleghast13:06:15

Sadly that does not work, though I feel as though it should. I get the following error:

java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$constantly$fn__6693

otfrom13:06:16

(didn't test it sry)

maleghast13:06:07

Will do - and no need for an apology; I asked 'cos I was stumped, any input is good 🙂

otfrom13:06:02

lmk what code works. 😉

maleghast13:06:57

will do - about to try repeatedly

maleghast13:06:53

OK, @otfrom, sadly "repeatedly" does not work, but this train of thought brought me to this, which does:

maleghast13:06:58

(zipmap coll1 (repeat (count coll1) nil))

shan13:06:16

you can actually remove the (count coll1)

shan13:06:30

(zipmap coll1 (repeat nil))

otfrom13:06:53

> (zipmap [:foo :bar :baz] (repeat nil))
{:baz nil, :bar nil, :foo nil}

maleghast13:06:40

Oh man, that is awesome!

maleghast13:06:04

I am so going to do that - thanks all 🙂

glenjamin13:06:22

probably no better now i look at it

maleghast14:06:54

@glenjamin - It's interesting, however, as it shows me another way of thinking about things... 🙂

maleghast14:06:07

I have never really spent the time to grok "for" properly, and this is another timely reminder that I should pay it more attention.

maleghast14:06:51

(Am I right in saying that this is a "list comprehension" approach?)

thomas14:06:53

@maleghast I tend not to use for a lot either.

practicalli-john14:06:49

for is really handy, although I prefer the elegance and composability of zipmap. Sometimes for has tendency to use temporary names that lack meaning, like k. To me that make the code feel a little less elegant than using zipmap.

glenjamin14:06:50

I never used to use for much, but someone on IRC used to use it in answers a lot and then i got the hang of it

glenjamin14:06:14

once I started thinking “for = list comprehension” instead of “for = loop”, i found it easier

bronsa14:06:25

that's essentially what for is

bronsa14:06:32

i tend to use for instead of map quite often

bronsa14:06:04

esp if I have to destructure arguments or introduce additional let bindings

bronsa14:06:18

I find it much more readable

maleghast15:06:15

Interesting...

maleghast15:06:34

I am liking getting these alternative perspectives 🙂 Thanks people 🙂

peterwestmacott15:06:04

for can be quite useful with :let and :when to avoid a separate map and filter

peterwestmacott15:06:23

often you can write it quite reasonably either way, and it’s a question of preference

dominicm15:06:09

I get frustrated when I want mapcat, but I also want to use for, it's very conflicting 😞

dominicm15:06:26

(into [] cat) has been nice recently though

peterwestmacott15:06:45

dominicm: is that with cat as xform?

peterwestmacott15:06:32

I have a forcat in my utils ns for that

maleghast17:06:50

@dominicm - This looks awesome!

madstap20:06:56

@peterwestmacott Is your forcat lazy? I'm trying to write one, and can't figure out how to make it lazy.

peterwestmacott20:06:17

I think it should be.

(defmacro forcat [seq-exprs body-expr]
  `(apply concat (for ~seq-exprs ~body-expr)))

peterwestmacott20:06:24

from memory I looked at mapcat and did what that did

madstap20:06:35

Yeah, that's exactly how I wrote it as well, and it doesn't seem to be.

madstap20:06:02

Huh, it doesn't look like mapcat is either.

madstap20:06:56

;; Doesn't print things until it's realized.
(def xs (map identity (repeatedly 10 #(do (prn "foo") (range 10)))))

;; Prints things
(def xs (mapcat identity (repeatedly 10 #(do (prn "foo") (range 10)))))

madstap20:06:56

I guess that forcat is consistent with mapcat then.

dominicm20:06:58

(defmacro forcat [for-args]
  `(apply concat (for [email protected])))
should work as well as a concat & for.

dominicm20:06:39

concat is pseudo lazy. It has some mixed reviews. I've been trying to work around them with things like (sequence cat) & such, but I've no idea if cat fixes many of the issues with concat

madstap20:06:48

I tried that as well

(defmacro forcat
  [seq-exprs body-expr]
  `(apply sequence cat (for ~seq-exprs ~body-expr)))
But it seems to exhibit the same non-lazy behavior.

madstap20:06:19

I ended up just returning a vector so it's obvious that it's not lazy

dominicm21:06:09

apply that's why 🙂

dominicm21:06:20

I'll have a play

seancorfield21:06:40

It was a good series of do’s/don’ts. Pity he stopped writing them.

dominicm21:06:06

There's just not that many don'ts for clojure 😉

practicalli-john21:06:06

dont stop using clojure, thats my favorite 🙂

bronsa21:06:17

@madstap the issue you're seeing with laziness & mapcat+apply is known and a combination of https://dev.clojure.org/jira/browse/CLJ-1218 and https://dev.clojure.org/jira/browse/CLJ-1583

dominicm21:06:50

@bronsa I'm curious about what you'd recommend for a lazy concat?

bronsa21:06:52

what do you mean? concat is fine as is

bronsa21:06:58

did you mean mapcat?

dominicm21:06:23

Oh, I think I'm hugely confused about something. Maybe apply. If I apply a sequence to concat, it has to realize the sequence right? Or no?

bronsa21:06:35

user=> (take 10 (apply concat (repeat (range))))
(0 1 2 3 4 5 6 7 8 9)

bronsa21:06:41

if that were the case the above would never terminate

bronsa21:06:15

apply is "lazy"

bronsa22:06:29

it can force more elements than needed (see CLJ-1583) but it will never force the whole seq

dominicm22:06:02

Oh, that's awesome. Well, I guess it can only do that for & args, but yeah.

dominicm22:06:21

Any reason 1583 isn't merged?

bronsa22:06:44

I have no control over it ¯\(ツ)

bronsa22:06:36

if you care leave a comment/vote on the ticket & alex will eventually take a look at it

bronsa22:06:02

otherwise it's just a matter of waiting a few (more) years and eventually it will get applied

bronsa22:06:47

my guess is that it's been considered low priority & alex/rich/stu simply haven't looked at it yet

bronsa22:06:29

generally, enhancement tickets have much lower priority than bug fixes

madstap22:06:02

Thanks for clearing up my confusion