Jonathan Worthington wrote:
I like the look of this, but if I wanted to go about implementing it I feel I'm kinda short of what that means implementation wise. I'm happy enough with flattening composition and all that jazz, but a little extra guidance on what you're expecting to compose into the object and where the roles come from would be very helpful to me, and maybe to others who are considering trying to implement some of this. (I hope the question makes sense. If not, I'll try and ask it a better way. Well, a different way at least. :-))
I'm working on defining roles in the objects PDD. So, the short answer is "not defined yet".
The longer answer is that we're probably going to need more than one stage of composition:
- The roles that implement OS-specific behavior can be composed at the time Parrot itself is compiled. There's no need to duplicate the effort of determining which operating system you're running on every time you load a ParrotI/O object.
- Some roles can be composed at the time the object is constructed, such as the network or socket I/O functionality.
- Some roles can be composed into an already instantiated object, such as utf8 or binary file-handling functionality. These might be implemented by changing the object to belong to a lightweight singleton class created on the fly as a subclass of the object's original class.
For a first implementation, before the new objects PDD is finished we have basically two options: Implement the functionality as a simple low-level PMC, with a few subclasses (much like the current Array and Hash PMC sets). Or, implement it as a high-level (PIR) class, with a set of partial classes and simulate composition with '.include' statements. The former gives us better immediate access to low-level C functionality. The latter gives us a better way to play with composition behavior and lightweight embedding mechanisms.
One thing that would be useful is a list of all the currently existing I/O layers, what they do, and where they're used. I'll get to it at some point, if no one else gets there first.
I suspect it's cheaper/easier for a compiler to generate code to check a return value and throw an exception of its own choosing, than it is to emit code to catch the exception and return the error value.
Yeah, I like that perspective. Implement the alternative that's easiest to build on top of.
Allison