Fork me on GitHub
#core-async
<
2018-10-16
>
leonoel08:10:47

letfn is an IOC boundary as a whole, but it seems only bound functions should be, not the body. e.g (a/go (letfn [(f [x] (do-something-with x))] (f (a/<! port)))) looks perfectly legit to me, but fails because <! is outside of go boundaries. Is this intended, and why ?

markmarkmark12:10:03

letfn is a special from with special semantics (namely that you can use any of the fns that you define in its bindings in any order), which I think is the issue. it holds onto the body of the letfn until the very last minute, so the go block can't properly see the <! to transform it away.

markmarkmark12:10:37

I can't really explain it very well, but if you do something like (clojure.walk/macroexpand-all '(go (letfn [(f [x] (println x))] (f (<! port))))) vs (clojure.walk/macroexpand-all '(go (let [f (fn [x] (println x))] (f (<! port))))) then you can see that the (f (<! port)) still exists in the paren soup that gets spit out in the first case, but it works how you're expecting in the second case

markmarkmark12:10:06

so basically, the explanation is that letfn is weird

markmarkmark12:10:49

also, that might just be a bug?

bronsa12:10:33

looks like a bug to me

bronsa12:10:16

i'll take a look if you make a ticket to track this @leonoel

markmarkmark12:10:18

ha yeah, I typed all of that up and then thought about it one more time and realized it's probably just a bug

leonoel13:10:42

can't wait to hear about your strategy on this one @bronsa that sounds definitely fixable but all the solutions I can think of fight against the overall design

bronsa13:10:02

the fix is actually trivial AFAICT

bronsa13:10:42

@leonoel I've attached a patch, give it a spin

Alex Miller (Clojure team)14:10:54

that looks pretty simple. can someone add a test?

bronsa14:10:22

I'll turn the example in the ticket into one and update the patch

leonoel14:10:36

it works by coincidence, I fear

leonoel14:10:32

the even? function can't see odd? because it's not bound yet

leonoel14:10:06

it works because clojure.core has a function named odd?, but if you rename it then it won't compile

leonoel14:10:48

my example isn't that good 🙂

markmarkmark14:10:23

I see what's happening

markmarkmark14:10:34

it's collapsing the letfn into a regular let

markmarkmark14:10:39

it's binding the name of the fn after the fn has been defined, but that means that odd? doesn't exist when even? is defined

markmarkmark14:10:00

which happens to work when you use odd? and even? but if you change the names of the functions, it breaks

Erik Thorselius16:10:00

Hi! I'm having problem with integrant and channels in the repl. When I start the application all my channels works fine. Then when I stop and start again, it is like the new channels are closed. When I send a message on the channel it replies with false. On the halt-hook I'm closing the existing channels and when starting again I'm creating new ones. Should I try to keep them when restaring or is there anything else I'm doing wrong?

dadair16:10:03

Are your functions referencing old channels somehow?

dadair16:10:16

I do something very similar with integrant and works just fine

dadair16:10:34

This is likely more relevant for #integrant channel

Erik Thorselius16:10:55

aaa sorry I'm new here. I will check in the integrant channel

dadair16:10:04

No worries! 😄

bronsa16:10:27

heh, I hadn't connected my brain yet @leonoel, I'll make another patch handing this correctly

bronsa16:10:43

should still be relatively easy, just not that trivial :)

😎 4