I was thinking of the rules for isolation as laid out here: 
<https://github.com/nim-lang/RFCs/issues/244>. According to that `f(...)` is 
isolated if it can't have side effects and the return type can't alias the 
input types. In my example I return a `Tree` type which can only alias `Branch` 
types, and I pass in a `Test` type. So according to those rules I should be 
good, but apparently I'm not, and I'm not sure why, partially because it 
doesn't tell me which of the rules of isolation that I break.

The scenarios where I want to use `isolate` are fairly simple. One of them is 
even mentioned in the RFC itself. Essentially I want to avoid using expensive 
copying between threads, and I want to avoid using atomic refs when I'm not 
passing stuff between threads. Atomic refs are fine if you want threads to be 
able to access the same memory, but they don't really do all that much for 
moving data from one thread to another (of course it would help solve the 
problem, but now you're paying for atomic refs everywhere and only ever using 
them once in a while). Consider the two following use-cases:

Work balancer: I want to have one thread read data from a file, then create 
"work objects" and pass them to a pool of worker threads, these threads then 
pass "result objects" back to a final thread which computes the end result.

This is maybe the simplest of scenarios, and similar to the one from the RFC 
(where a string is turned into a `JsonNode` to be passed over a channel). 
Basically the data is always transformed from one thing to another and it 
should be easier to prove that X can't alias Y and that isolation is valid. I 
feel like the current situation is almost there, and in fact if the code I 
shared above had worked I believe it would already be here.

Computation pipeline: This is the more complex scenario. Basically passing an 
object along a chain of worker threads which perform some computation. In this 
case one object would only be in use by one thread at a time, with each thread 
moving it to another thread over a channel. This would require a more complex 
check as a thread could theoretically keep an alias to this object, or to 
anything that it adds a reference to inside the object. I'm not sure if there 
is any way to do this apart from performing the kind of check Zevv was talking 
about, but it would be great if we could have some way of doing that properly. 
This would require quite a bit of work to get right, but it would allow pretty 
much any usecase involving channels and moving memory around.

All in all I'd say that having some more (preferably compile-time) guarantees 
that memory is cleanly moved between threads would really allow a lot of neat 
multithreading systems to be built which in turn would allow Nim with its 
amazing macros system to really have some ergonomic multithreading. If we just 
got better primitives for moving memory around I am sure we will see some 
really cool stuff in this space which would really elevate the language.

Reply via email to