I have a question on places, but most likely it is also related to rackunit and interaction with test submodules. Take a look: #lang racket/base
(module+ test
(require rackunit racket/place)
(define v 2)
(check-= (place-channel-get (place/context ch (place-channel-put v)))
v)) This goes into an infinite loop. I understand that one needs to be careful when putting calls to place in the top-level and why an infinite loop occurs there. However, I can’t seem to figure out why it would occur here. I run it with raco test place-test.rkt and places create places, which in turn create more places. I was expecting raco test in this case to call the test submodule, which does create a the first place, but there’s no reason for the place then to create yet another place since itself should not be executing the test submodule automatically. But somehow, it is. Why is this happening?
@pocmatos I believe that the restriction is that the dynamic evaluation of the place expression must not happen during the initialization of the module (or submodule) where the place expression statically occurs, and your code is doing that. The reason (IIRC) is that place lifts its body as a definition to the top level of the enclosing module and sends the module name and defined name to the new place to execute. The new place fetches the code to run by doing dynamic-require, which initializes the module where the place expression occurred, and if initializing that module means evaluating the place expression again, you get the loop.
What you say makes sense but it only fits my view of things until you say: where the place expression *statically* occurs
Still confuses me, why the dynamic-require would initialize the module where the place expression occurred. I thought it would only initialize the top-level.
In the newly created place, the module containing the place/context expression has to be instantiated. In this case, that’s the test submodule. Instantiating the test submodule runs the body of the submodule, which includes a check-= form that has a place/context subexpression, and evaluating that subexpression creates a new place that instantiates the test submodule…
ah of course. I forgot that in the new place, we need to instantiate the place/context in order to get the place-body-n module to call in the place.
Although this is not a serious issue, it’s quite annoying to have to worry about this. I understand that this is due to the way places are implemented but is there an alternative implementation in which one could minimize or remove this problem?
We never found a different design. FWIW, I usually put the place/context call in a function in the enclosing module, and then call the function from a submodule like main and test.
Thanks. Yes, I do that in practice too. However, I was trying to see the best way to run tests involving place calls. I just noticed from the racket place tests, that test submodules are not used. Instead tests are ran as programs. Makes sense in this case. Thanks.
@heymatthewoden has joined the channel
@pocmatos maybe there could be a protocol where place or place/context sends an initial message to conditionally avoid running itself?
place/context might be better since it already sends an initial message
Maybe under a new name place/safe? That could be something interesting to try.
Might be a bad name, giving the impression the other place is unsafe… in any case the idea is interesting.
@smartmakerfest has joined the channel
Can someone block smartmakerfest?
done