The problem is not in my actors or in any other code I wrote, but has to do 
with whatever the user might want to send through a channel. My example would 
be just the same as your example: just two threads and a single channel. No 
different from sending messages to actors through mailboxes.

At this time, we have no way of making sure that what gets sent through a 
channel is safe to be received by a different thread. The user might send data 
structures that are still referenced from elsewhere, but the the Nim type 
system currently has no way to help with this.

Of course we can say "well, just don't do that", but that will not lead to safe 
code.

Currently, `isolate[T]` is not helping; `isolate()` requires data to be 
isolated at construction time, and `unsafeIsolate()` is just that: unsafe: is 
not doing anything at all and gives the user the impression that the data is 
isolated, when it might not be.

Let's make this concrete with the example below. It crashesh. I know it is 
wrong. You know it is wrong. But the language is not protecting us in any way. 
There are no `.gcsafe.` casts going on, or anything indicating that this is 
wrong. Except of course that the only way to do this is by calling the function 
`unsafeIsolate()`, which is unsafe.
    
    
    import std / [json, isolation]
    import threading / channels
    
    type Thing = ref object
      name: string
      kid: Thing
    
    var chan = newChan[Thing]()
    var thr: Thread[void]
    
    proc worker() {.thread.} =
      var x: Thing
      chan.recv(x)
      echo "received ", x.repr
    
    
    proc main() =
      var t1 = Thing(name: "t1")
      var t2 = Thing(name: "t2", kid: t1)
      
      createThread thr, worker
      chan.send unsafeIsolate(t2)
      joinThread thr
      
      echo "main: ", t1.repr
    
    main()
    
    
    Run

Reply via email to