#1798 Not serializable: |->sys::Void|

SlimerDude Wed 29 Feb 2012

Whilst refactoring my Actor code I find some funcs can be passed as msgs and others throw Errs... It's driving me bonkers!

Here's a simple example that throws an IOErr:

using concurrent

const class Banana : Actor {  
  new make() : super(ActorPool()) {}

  static Void main(Str[] args) {
    Banana().biteMe("Pancakes!").get
  }

  Future biteMe(Obj food) {
    send |->| { 
      echo("I like to eat $food")
    }
  }

  override Obj? receive(Obj? msg) {
    return (msg as Func).call(this)
  }
}

throws

sys::IOErr: Not serializable: |->sys::Void|
  fanx.serial.ObjEncoder.writeObj (ObjEncoder.java:84)
  fan.sys.OutStream.writeObj (OutStream.java:269)
  fan.sys.OutStream.writeObj (OutStream.java:266)
  fan.sys.Sys.safe (Sys.java:534)
  concurrent::Actor._send (Actor.java:137)
  concurrent::Actor.send (Actor.java:91)
  afalife::Banana.biteMe (Banana.fan:11)
  afalife::Banana.main (Banana.fan:7)

But if change biteMe() to:

Void biteMe(Str food) { ... }

I get

I like to eat Pancakes!

Is this right? Because the only way round it (that I can find) is to manually serialise my const Objs (whatever they may be) into a Str, send the msg and then de-serialise on the next line!

Future biteMe(Obj food) {
  Str s := writeObj(food)
  send |->| { 
    Obj f := s.in.read
    echo("I like to eat $f")
  }
}

Ouch!

brian Wed 29 Feb 2012

Well I would highly recommend you stick with simple immutable objects for messages and return values. That is super fast and super simple.

You cannot serialize functions (although you can send type and slot literals). But sometimes functions are immutable in which case it will work. If you really want to try to pass functions, then you might want to take look at this document which describes when functions are immutable and when they aren't docLang::Functions#immutable.

SlimerDude Wed 29 Feb 2012

Hi Brain,

The point I was trying to make was, I am sending simple immutable objects though the closure. In the example above, it was a Str. But when the Str is declared as Obj it throws an Err.

From docLang::Functions#immutable

  • Closure which capture non-final variables which aren't known to be immutable until runtime (such as Obj or List) will return false for isImmutable, but will provide a toImmutable method which attempts to bind to the current variables by calling toImmutable on each one

So that should work right? As Str is immutable.

brian Wed 29 Feb 2012

You might have to call toImmutable explictly then - actor library only checks isImmutable and otherwise tries to seralize

Login or Signup to reply.