Fork me on GitHub
#core-async
<
2017-02-13
>
Alex Miller (Clojure team)20:02:02

hiredman I dropped a comment on http://dev.clojure.org/jira/browse/ASYNC-169 - trying to move some of this forward but need some feedback there

hiredman20:02:44

cool, I am looking at removing those reflection warnings right now

bronsa22:02:34

@alexmiller RE: ASYNC-138, I see you're on a core.async ticket spree and that's a ticket I'd really like to get fixed sooner rather than later, do you think you'll be able to get back to those tickets in the near future? if not I'll try to fix the patch today

Alex Miller (Clojure team)22:02:35

I hope to get a release out this week but I’m not urgent to do it today

hiredman22:02:35

that is a neat patch

bronsa22:02:55

it's also a terrible hack

bronsa22:02:18

but I'll take a hack that works over memory leaks

hiredman22:02:19

"uses existing facilities"

bronsa22:02:06

it's technically still holding references

bronsa22:02:25

but it's holding a reference to a pointer rather than to data

hiredman22:02:08

it does seem like you could play whack-a-mole with that stuff until the ioc macros implement their own locals clearing

tbaldridge22:02:04

yeah, locals clearing is the only real answer

tbaldridge22:02:30

And now that we have volatile we could switch to using that instead of atomic arrays.

bronsa22:02:05

@tbaldridge not sure we can do proper locals clearing in macros, without using the ^:once fn* trick, locals still have to cross into the ioc loop, and once they do the compiler will never let them get cleared

bronsa22:02:38

well, not until the loop exits

tbaldridge22:02:41

I'm not sure I understand

tbaldridge22:02:09

"cross into the ioc loop"...

bronsa22:02:17

(let [a (range)] (loop [..] .. a ..))

bronsa22:02:36

that loop is the state machine loop generated by go

tbaldridge22:02:15

oh yeah, that

bronsa22:02:17

as soon as a local enters a loop body, the compiler won't allow clearing of that loop until the loop exits

bronsa22:02:25

because it might run more than once

tbaldridge22:02:38

didn't realize that was the problem.

bronsa22:02:41

so to make it cross from the outside into the loop & allowing it to clear

bronsa22:02:15

we transform it into (let [a (range) a' (^:once fn* [] a)] (loop [..] (let [a (a')] ..))

tbaldridge22:02:27

that's not even locals clearing, right? more like "closure clearing" ?

bronsa22:02:35

some weird thing

bronsa22:02:41

but it works fine

bronsa23:02:10

because we have the (informal) guarantee that a will be actually only used once to be inserted into the locals array

bronsa23:02:18

but the compiler is not able to figure it out

bronsa23:02:31

so that's a way to trick the compiler into doing it

tbaldridge23:02:51

Is that a thing in Clojure though? Does Clojure do that currently (let [a (range)] (fn [] (doseq [x a])))

tbaldridge23:02:32

I would have thought that would hold onto the head of a but I guess that may not be the case (learn something new every day).

bronsa23:02:50

@tbaldridge dunno but it's manifesting in very simple cases using e.g. onto-chan

bronsa23:02:23

i'm uploading a fixed patch that makes the test work fine

bronsa23:02:32

i'm aware it's a very complex patch with tons of subtelties

bronsa23:02:49

but after 2 years I don't have any better ideas

bronsa23:02:02

conceptually the transformation is simple tho

tbaldridge23:02:42

someday maybe I'll get the energy to go rewrite this all as a modification to Compiler.java...someday

bronsa23:02:00

if you or @alexmiller need help understanding what's happening in that patch feel free to ping me

bronsa23:02:31

I've added a brief description of the approach in the ticket