With most of my recent programming work being in python, one of the adjustments I’ve had to make when experimenting with goblins is not having access to a “self” or “this” reference from within an object. I can see reasons for and against having these references and I was wondering if this was an intentional choice and whether there are any ocap-specific considerations.
The main difference this has led to is needing to rely more on composition than I’m used to, in order to have references to objects providing specific functionality or capabilities.
@cwebber and I have had lively discussions on this topic, and I think we’ve agreed to disagree, or at least have chosen to pursue opposite defaults. The Goblins code you showed depends on a mutable environment in which you can bind self after you’ve created the actor that refers to itself.
In a pure-functional system (like Humus, for example) that kind of circular reference would require the equivalent of a Y-combinator. I considered that too awkward/ugly, so I prefer to provide a self reference (sometimes as a keyword) within every Actor. One pattern that uses self is lazy-initialization, where the Actor uses become to initialize itself on receipt of its first message-event and resends that message (asynchronously) to itself for handling after initialization.
I don’t have the “risk” associated with “private” methods, partly because I don’t have synchronous method-calls, but mostly because self is not a privileged reference. It is, in fact, the same reference any other collaborator would use to send an asynchronous message to this actor.
I think the distinction comes down to this. Who has a reference to a newly-created actor, the creator only, or the creator and the actor itself? Goblins implements the former, and I prefer the latter.
Hmm. This is interesting. I’ve been working with the Unum/Presence model since the beginning, and lazy initialization has always presented a challenge (especially when some Una want to initialize relative to others…). Thanks!
I also am running into this specific issue with the little project I am currently working on (tic-tac-toe). I certainly would not needself, but it feels lacking just due to the languages I’ve used in the past, for example when using (methods ...) if you want to invoke your own method. I have gotten around this constraint by having defines that the methods are bound to (the defined method is _name and the method is [(name) (_name)]–but it doesn’t feel elegant.
What I really wonder about, is whether it’s possible to use bcom if you have a selfish-spawned object. Can a non-selfish object bcom one, and can you bcom anything (selfish or not) effectively if you are a selfish object? If you pass the same self - does it have the proper debug name and everything. Worth experimenting with but also perhaps I just need to reframe how I design objects!