Fork me on GitHub
#clojure
<
2018-02-08
>
grzm00:02:18

You know how you can keep a go-loop from looping without error? Easy. Don't include a recur statement.

borkdude10:02:55

`(fn [a b] b)` (constantly b)~?

moxaj10:02:56

@borkdude you don't know b beforehand

borkdude10:02:12

oh, of course… duh - still waking up I guess 😉

cpmcdaniel14:02:44

anyone here building custom runtimes with jlink/Java 9 and Clojure?

octahedrion16:02:22

is Datomic Cloud data stored encrypted ?

noisesmith16:02:09

a cute way to do (fn [a b] b) is (comp second vector) - probably not a good way to do it, mind you

burke16:02:04

#(identity %2) :thinking_face:

mpenet16:02:32

Still the first version reads better ;)

mpenet16:02:48

Hmm #(%& 1)?

noisesmith17:02:38

clever, but %& isn’t associative

noisesmith17:02:13

#((vec %&) 1) doesn’t have the same catchy ring to it

mpenet16:02:59

Perl territory

Alex Miller (Clojure team)16:02:30

I like #(identity %2) for intent :)

joelsanchez18:02:37

The REPL hasn't been weekly for a while now and that makes me sad. I used to be very excited for the next issue every week :white_frowning_face:

sam19:02:18

what's The REPL in this context? Link?

joelsanchez20:02:45

the best thing a clojure dev could find in its inbox 🙂

danielcompton19:02:41

@joelsanchez sorry 😐 work has been pretty busy plus holidays but that’s winding down now

joelsanchez19:02:48

don't feel pressured, you're doing it for free after all, just wanted to say I'd love to have it back

danielcompton19:02:04

No worries no pressure :)

gnejs19:02:24

Same here - looking forward to the next REPL. Great work, Daniel :thumbsup:

nha14:02:13

Like it as well - weekly or not 🙂

sam19:02:05

is linking to , which is listed as domain for sale 😞

bronsa20:02:35

unfortunately the owner passed away last year

sam14:02:24

oh, that’s terrible 😕

noisesmith20:02:52

@sammy.castaneda90 the whole site is on github if you can find the code or markup with that link

noisesmith20:02:39

@sammy.castaneda90 I just tried to find it - where is the tryclj link?

sam07:02:31

http://4clojure.com -> click on REPL in the navigation bar

sam19:02:46

Oh awesome, I forgot that it was open source

sam12:02:10

opened a PR, thanks @noisesmith!

the2bears20:02:55

Oh... I misinterpreted which domain was for sale.

lspector20:02:09

It looks from my simple experiments like iterate doesn't chunk, and that it computes its results one at a time. Great! But is this something I should be able to rely on?

noisesmith20:02:09

@lspector best practice is to isolate side effects or resource usage from laziness - eg. if you have a side effect to run on the first N results of some lazy-op, you can use (run! side-effect! (take N (iterate f x))) or (doseq [y (take N (iterate f x))] (side-effect! y))

lspector20:02:26

@noisesmith in my case there are no side effects, but in every case there is resource usage and in mine that may be big here

noisesmith20:02:07

such that 32 items in memory would break something but 1 in memory would not?

lspector20:02:33

such that computing the 32 items would take a lot of time

lspector20:02:36

Imagine you have an expensive transformation that you'd like to apply to a state many times in succession

lspector20:02:06

You want to apply it until you find one that meets some condition, but you don't want to do it any more times than necessary because it takes a long time

noisesmith20:02:09

there’s code floating about to “dechunk” to ensure you are not processing chunked, but it seems like there should be a cleaner solution

noisesmith20:02:35

@lspector if all you want is the first match, (first (eduction ...)) is great

lspector20:02:28

I could just use an explicit loop, but iterate would be more elegant if I could be sure it wouldn't chunk... which it doesn't seem to, but I'd like to know if that's reasonably reliable

noisesmith20:02:22

peregrine.circle=> (first (eduction (filter even?) (map println) (take 3) (range)))
0
2
4
nil

noisesmith20:02:42

I guess doing something inside that returns nil makes the example less clear

lspector20:02:51

iterate also does the right thing now as far as I can tell:

user=> (take 10 (iterate #(do (println :hi) (inc %)) 0))
:hi
:hi
:hi
:hi
:hi
:hi
:hi
:hi
:hi
(0 1 2 3 4 5 6 7 8 9)

lspector20:02:23

But should one count on this?

noisesmith20:02:49

isn’t the main thing that jira post adresses the fact that the function provided to iterate must be free of side-effects because there are corner cases where it can be calculated twice for the same input?

lspector20:02:14

I don't understand the jira post so I'm not sure 🙂. But I put a side effect in there just to see if iterate was chunking. My intended use case wouldn't include that.

Kathy20:02:19

Hello Slackers!!!!!!!!!!!!!!!!!

lspector20:02:01

Not yet understanding the eduction example either, FWIW. I do understand and love the simplicity and elegance of iterate, and would just like to know if I can rely on it not chunking.

Kathy20:02:17

We are hiring Candidates for Contract/Full time for Clojure - Who can work onsite in Atlanta or remote amywhere from USA

noisesmith20:02:25

@lspector AFAIK nothing lazy in clojure makes any promises about future chunking behavior, we can say that it does or doesn’t chunk now but can’t say that about future implementations, and if the chunking changes your correctness AFAIK the right answer is not to use laziness

Kathy20:02:27

interested DM me!!!!! we can discuss further

joelsanchez20:02:43

post in #jobs pls

lspector21:02:04

Thanks @noisesmith. FWIW this isn't the first reason I've wished that there was a non-lazy version of every lazy thing in Clojure. I guess I'll avoid iterate for this, and probably use loop, though it'll make me sad. BTW this isn't a matter of correctness for me, but of avoiding taking much more time.

noisesmith21:02:45

@lspector via transducing arities we do have non-lazy versions of most things lazy

lspector21:02:23

@noisesmith I haven't fully wrapped my head around transducers. What would be the way to get something like iterate using tranducing arities?

noisesmith22:02:32

iterate’s one of the ones that doesn’t directly translate to transducing currently

noisesmith22:02:03

though I could see something that acts like iterate but implements IReduceInit - similar to hiredman’s link above

shaun-mahood22:02:50

@lspector: There's a pretty interesting conversation about chunking in #clojure-dev from a few days ago (still visible for me) - it looks like it might be relevant (might not, but I thought they were the same conversation when I was scrolling through so at least it will have some of the same words 🙂 )

andy.fingerhut22:02:15

@lspector @noisesmith Here is one of several implementations of an 'unchunk' function for Clojure: https://crossclj.info/fun/flatland.useful.seq/unchunk.html

noisesmith22:02:13

I’ve seen a few versions - my worry is that needing unchunk is a code smell of using laziness for something it’s not quite suited for

noisesmith22:02:27

but maybe I’m wrong, I’m unsure about this stuff

lspector22:02:03

Thanks @andy.fingerhut. So if I want to do (take-while condition (iterate f v)) but want to be sure f doesn't get called more than necessary (because of time, not side effects), I should do (take-while condition (unchunk (iterate f v)))?

noisesmith22:02:50

unchunk in that position wouldn’t help if iterate already chunked

noisesmith22:02:40

my concern was that it could in some future clojure version - if we know it will never be that concern is moot

bronsa22:02:51

ah ok sorry

bronsa22:02:55

missed the scrollback

andy.fingerhut22:02:55

I haven't re-read the issue to steep myself in the details yet, but it was added in math.combinatorics to handle a case where memory blew up when chunking occurred, but became reasonable when chunking was removed: https://dev.clojure.org/jira/browse/MCOMB-2

noisesmith22:02:08

it would protect something that surrounds iterate from chunking caused by iterate though

andy.fingerhut22:02:25

It sounds similar in flavor to @lspector's situation -- too many wasted resources due to chunking

noisesmith22:02:04

so yeah, unchunk could help surrounding v (if generation of v is an issue) but you’d need to completely replace iterate, or get a promise that it won’t ever chunk

bronsa22:02:17

iterate doesn't do any chunking

andy.fingerhut22:02:00

So looks like perhaps (take-while condition (iterate f (unchunk v))) might be what could help here?

bronsa22:02:17

that would be non sensical

bronsa22:02:24

(iterate inc (unchunk 1))

andy.fingerhut22:02:39

Sorry, not fully awake here.

andy.fingerhut22:02:24

I was so excited I had something possibly relevant to add that I didn't fully engage the brain 🙂

bronsa22:02:26

I had a bit of a rant on chunking in #clojure-dev but half of it has already disappeared

andy.fingerhut22:02:43

Please rant in the clojure-dev Google group, where it will have a much-longer lasting URL 🙂

bronsa22:02:51

yeah I meant to do that

bronsa22:02:58

and then I forgot

noisesmith22:02:12

I’m interested in the possibility that issues around chunking / not chunking expose an impedance mismatch around using laziness for resource intensive or side effecting things - but I’m not sure if the right solution is a principled one (use something not lazy, make a non-lazy alternative for iterate(?)) or to accept that chunking needs to be abstracted from the implementation details of lazy things

noisesmith22:02:24

not to mention the fact that RH might reject either of those things of course

andy.fingerhut22:02:00

The current implementation of iterate can be copied out of core into your code if it becomes chunking.

noisesmith22:02:09

that’s true

andy.fingerhut22:02:44

not that any necessarily red flag will be raised if that happens, to let you know you should do it, if you are one of the relatively few whose use cases it matters for.

bronsa22:02:45

except iterate now is a massive java class

andy.fingerhut22:02:17

Ah, well in that case, a lower performance short sweet pure Clojure version can be written in your own code 🙂

andy.fingerhut22:02:31

The less you care about core changing, the better.

andy.fingerhut22:02:12

Huh, the fact that I can say that means that I may actually be recovering.

Ryan Radomski23:02:02

What is the most actively maintained Oauth2 library for clojure? This looks like it has a good team https://github.com/weavejester/ring-oauth2

lspector23:02:19

Thanks @andy.fingerhut, @noisesmith, and @bronsa. I think I'll just use iterate since it doesn't chunk now, and it sounds like that's unlikely to change soon. At least until somebody reuses my code 😉 it's not safety critical, and I'm using this in an educational context in which the simplicity and elegance of iterate will make it worthwhile.