pocmatos
2019-9-18 12:49:32

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?


ryanc
2019-9-18 13:16:04

@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.


pocmatos
2019-9-18 13:25:17

What you say makes sense but it only fits my view of things until you say: where the place expression *statically* occurs


pocmatos
2019-9-18 13:26:39

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.


mflatt
2019-9-18 13:40:27

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…


pocmatos
2019-9-18 13:58:37

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.


pocmatos
2019-9-18 13:59:54

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?


mflatt
2019-9-18 14:13:03

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.


pocmatos
2019-9-18 14:14:26

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
2019-9-18 16:42:02

@heymatthewoden has joined the channel


samth
2019-9-18 18:05:24

@pocmatos maybe there could be a protocol where place or place/context sends an initial message to conditionally avoid running itself?


samth
2019-9-18 18:05:38

place/context might be better since it already sends an initial message


pocmatos
2019-9-18 18:34:15

Maybe under a new name place/safe? That could be something interesting to try.


pocmatos
2019-9-18 18:34:41

Might be a bad name, giving the impression the other place is unsafe… in any case the idea is interesting.


smartmakerfest
2019-9-18 19:27:45

@smartmakerfest has joined the channel


pocmatos
2019-9-18 20:28:46

Can someone block smartmakerfest?


samth
2019-9-18 20:32:26

done