I’ve run into a definedness error and I’m not sure that it should be an error…and if it is I need a strategy to fix it! I have an instantiation of a class that takes an argument that is a ?func. That func uses the class, but it would never be called before the class was instantiated.
func myfunc(){ myClass.doSomething() };
let myClass = MyClass({onDoSomething = ?myFunc});
definedness error [M0016], cannot use myfunc before myClass has been defined
If I flip things around and do the class first I get two definedness errors! cannot use myFunc before myFunc has been defined and cannot use myFunc before myClass has been defined.
I ended up making the class a var, setting my function to null, and creating an init function that runs at the end of my actor class instantiation to set it back the way I want it. So the questions are, what am I giving up by making it a var? Memory? And should it be an error at all if I’m not calling the function, but just referencing it?
I think you are giving up some safety (you could forget to set the var) and a little perf (you need to dereference the var) but not much else.
The compiler rejects the original code because, like all type systems, it is conservative, and assumes that MyClass could use its argument, and apply myFunc, and thus read myClass, before myClass is actually defined.
Take a look at how I solved it my to_sync and to_async branches. I think we should at least take it to async*/await*, but I know with mops I had to hack in tests with async*/await*. I was thinking sync, but with the IC architecture, it may be nice to know we can interrupt at a particular point and continue on in a future round, we may just need keep track of a lock at the top level so that we don’t allow simultaneous execution. In theory, the scheduler could intermingle calls if they come in on the same round.
I didn’t have to use classes, but instead a function returning the engine.