ponyc
ponyc copied to clipboard
Should object literals be lifted to actors when their subtyping includes behaviors?
Should object literals resulting in an anonymous class or primitive be promoted to actor literals when they are sub-typed with an interface or trait including a behavior? As it is now, the literal must also include a behavior to be considered an actor literal. Note that it does not matter whether the trait or interface includes a default implementation for such behaviors.
I would expect such literals to be lifted to an actor, given any trait or interface requiring any behaviors also intends to categorize an actor. Then again, I'm unsure what kind of consequences this entails with union or intersected sub-typing.
ponyc version:
0.24.4 [release]
compiled with: llvm 3.9.1 -- cc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
Defaults: pic=false ssl=openssl_0.9.0
source (run in playground):
trait WithBehavior
be bar() => None
actor Main
new create(env: Env) =>
let actor_literal =
object is WithBehavior
// Inclusion of behavior lifts to actor literal
be other() => None
end
// Error: cannot add a behaviour (bar) to a primitive
let primitive_literal =
object is WithBehavior end
// Error: cannot add a behaviour (bar) to a class
let class_literal =
object is WithBehavior
var some: String = "field"
end
The straightforward solution is to look in all declared interfaces and traits for behaviours when deciding whether the literal should be an actor/object/primitive.
However I do find it surprising that the kind of "entity" being created is implicit. I would prefer if a different keyword was used, eg:
actor Main
new create(env: Env) =>
let actor_literal = actor is WithBehavior end
let primitive_literal = primitive is WithBehavior end
This unfortunately makes parsing ambiguous, since the actor keyword could be either a literal, or the start of a new actor definition. It can be disambiguated by looking at the next token (if it's an identifier then it's a definition, if it's is/let/var/fun/be/end
it's a literal, but that might be too confusing.
(I've always disliked how "actor" refers to both the definition and the runtime entity, unlike the existing distinction between class/object, but I was never able to come up with a better name for either).
The straightforward solution is to look in all declared interfaces and traits for behaviours when deciding whether the literal should be an actor/object/primitive.
Yeah, I think that's what we should do for now.
Regarding other syntax suggestions, I think stuff like that would have to be tackled in a separate RFC outside this scope.