This is a quick dump of a rough design sketch for Value objects in Newspeak, which builds upon section 3.1.1 of the current version of the Newspeak language specification.
- Value classes allow explicit intent. The class declaration is automatically annotated with metadata that expresses the intent for instances to be value objects.
- Value classes use special syntax that introduces the said metadata annotation (e.g. valueclass X instead of class X).
- Value classes can only be mixed in with other Value classes.
- Value classes can only have immutable slots.
- The root of the value classes is Value, which extends from Object. The Value class overrides the == method and delegates it to =. The Value class overrides = to compare all the slots recursively using =. The Value class overrides the asString method to give a neat stringified representation of the Value object in a JSON-like format. Value class computations for =, asString bottom out on built-in Value classes, like Number, Character, String etc. (overriding = and asString is explicitly inspired by the behavior of case classes in Scala).
- The Value class overrides the identityHash method to delegate to the hash method, and overrides the hash methods with some simple, yet-to-be-determined, recursive hashing algorithm (e.g. XOR-ing the hashes of all the slots).
- Value objects can only point to other Value objects.
- Value class declarations can only be nested inside other Value class declarations.
- This implies the enclosing object of a Value class is always a value object.
- Simply annotating a class declaration as “<Value>” is not enough. Syntax is required for valueclass declarations in order to ensure that Value classes always extend other Value classes. This allows a Value class with no explicit superclass clause to implicitly extend the built-in Value class, instead of Object, which is the default superclass for regular classes.
- The constraints on Value objects and Value classes are verified at mixin application time (the superclass is a Value class), and object construction time (all slots contain other Value objects).
- The enclosing object does not need to be verified at mixin application time, because the enclosing scope of a Value class declaration can be verified at compile time.
- Value classes are also Value objects.
- nil is a Value object.
- Value class declarations can contain nested non-value (regular) class declarations. More generally speaking, Value objects can produce (act as factories for) non-value objects.
- Value objects are awesome! They are containers for data and the unit of data transfer between Actors in Newspeak, and also the building block for immutable data structures.
- Update 11/24:
- Every class whose enclosing object is a value object is also a value object (but not necessarily a value class!).
Update 11/27:
Justification for the above is: if multiple equivalent instances of a value class are indistinguishable, then all of the instances’ constituent parts, nested classes included, must be indistinguishable as well. Think (a == b), but (a NestedClass == b NestedClass) not – this is unacceptable! - We must determine rules for when closure and activation objects are value objects, so we can safely deal with simultaneous slots in value classes (at construction time, the closure object that captures each simultaneous slot initializer must be a value object, at lazy evaluation time, the result must be a value object, otherwise an exception is thrown and the simultaneous slot is not resolved).
In E, references are distinct from the objects they designate. This might seem apparent, but it is not necessarily so. In traditional languages like Java, first-class references are almost indistinguishable from the objects they designate. They are internally represented as 4- to 8-byte pointers and while there is a distinction between reference equality (two references pointing to the same object) and object equality (two distinct objects with identical/indistinguishable contents and behavior), there is not much else to worry about.
In E, however, the rabbit hole goes deeper. There are multiple *types* of references. The word type might be a misnomer but I find it as one good way to think about references. In the E thesis, there is no discussion of types of references, but rather states that a reference can be in:
- Local Promise
- Remote Promise
- Near Reference
- Far Reference
- Broken Reference
In this discussion reference type is a synonym for reference state. The reason the term state seems more appropriate is that a single reference goes through several transitions between states in the course of its lifetime. In other words, a reference can switch types.
The problem this poses for an implementation is that references in different states hold different information. A near reference is the simplest case, the familiar reference from Java – it holds the address of an object within the current VM’s heap. A promise however, holds an unbounded list of pending messages and whenResolved listeners. A far reference holds whatever information is necessary to transmit messages to its target object, including potentially a distinct queue of messages pending delivery. A broken reference holds exception information regarding the reason for the reference breakage.
Classes are a natural way to think about implementing each different state of a promise – the information and behavior for each state of a reference is represented by a distinct class. The problem arises when the reference needs to switch states, therefore the need arises for an object to change its class dynamically, which is not traditionally available functionality in object-oriented programming languages.
Another problem is the possibility that references might chain. In other words, the possibility that a reference might point to another reference, instead of directly pointing to an object. A promise might get resolved to another promise. Or, even more disturbingly, a far reference might point to a promise reference. This possibility of chaining is actually excluded in the reference states model presented by Miller. Instead of a promise resolving to another promise, the promise reference simply makes a state transition, or in other words, the reference becomes the other promise, instead of pointing to it. In a similar fashion, a promise will get deserialized as a promise for the same result as the original promise, instead of being deserialized as a far reference to a promise (which would introduce chaining of references).
This, in essence, leads to an important conclusion. The serialization/deserialization implementation must include special handling logic for references in different states. For instance:
- Near reference might have to be deserialized as a far reference
- Near promise is deserialized as a remote promise linked to the same resolver as the original near promise
etc.
Furthermore, the resolution logic must handle the distinct cases as well, in order to handle the different state transitions possible that originate from the promise states:
- Become another promise (for a new result)
- Resolve to and become a far or near reference
As already discussed, the most natural way to implement the different reference states is as classes. At this point the notion of reference states as types comes into the picture. References are objects in our runtime VM but they are a distinct type of proxy objects that provide special services and require distinct treatment from regular application objects. As explained above, for deserialization and resolution purposes, we need to be able to distinguish between a near reference to an application object and a near reference to a reference object (since fundamentally the runtime VM only provides primitive support for near references, and the other reference states are reified as regular objects). Furthermore, it is clear from the examples above that we also need to be able to distinguish between the different *types* of reference states (Local Promise vs Remote Promise vs Far Reference etc).
Since in Newspeak, there is no global namespace for classes, and at runtime all classes are simply a dynamic aggregation of mixin applications, we cannot test the class names of objects. Conceptually this would be equivalent to having some sort of type system anyway. But this is exactly what we need – to be able to distinguish between different types of objects (one per reference state), albeit a very restricted set.
Since the Past and Actors libraries are a core part of the language, I propose to meet the need for type checking using the following idiom, which is slightly different from the is* message idiom for arbitrary objects, already implemented in the NewseakObject doesNotUnderstand: protocol. The idea is that since the Past and Actors libraries are singleton modules and the sole managers of instances of objects that represent reference states, and not likely candidates for extension by applications, we can simply test for class equality like this:
(obj class = Promise)
where obj is an object whose type is being tested and Promise is a reference to the class instance local to the current singleton module instance. Naturally,
Promise new
is exclusively used to construct Promises from within the Past module, for example.
I am a firm believer in openness. That is the reason I believe open source has such great value. The way I see it, the word open in “open source” does not just refer to the source code: it also means open communication, open structure, open management… openness in every aspect of a project.
Yet, in one of my own projects I failed to abide by my own principle. Two years ago, at the end of the summer of 2008, I left my small GSoC project – a split editor for Eclipse, in the state of a working prototype to begin a full-time job and join a master’s program. For two years now I have neglected the split editor project and kept in complete silence to the point that people have even forgotten that there was ever anyone involved in this effort.
I am now nearing the end of my master’s program and with all classwork completed am getting ready to begin work on a thesis. Before I do that, however, I wanted to clarify the state of affairs of my split editor work. I have not forgotten about it, and I am determined to complete it eventually. Although I will not have any time to dedicate to this work for another year, it is first on my queue of side projects after completing my master’s.
Actually, if anyone is willing to pick up the work now, I will be more than willing to provide whatever support I can. Here are the patches with my latest work, updated against the current Eclipse release as of the time of writing – 3.6.1 (R3_6_1 label in CVS):
The file contains four separate patches for the four Eclipse plugin projects involved in the split editor implementation:
- org.eclipse.ui.workbench – this project contains the bulk of the split editor work.
- org.eclipse.ui,
- org.eclipse.ui.editors,
- org.eclipse.jdt.ui – the above three projects contain mostly configuration changes to activate the split editor for Java and Text editors.
To see the split editor in action, check out these four projects from the Eclipse CVS repo (at label R3_6_1), apply the patches and start up an Eclipse launch configuration. If you want to try this but get lost or none of this makes sense, post a comment here and I will be happy to provide more detail.
I have always wanted to make it very easy for people to try out and experience the split editor at the earliest possible stage of its development (at which it stands currently – there are quite a few known bugs). The best way I see for this would be to share a custom build of Eclipse with the split editor work compiled in. Unfortunately, I have never been able to successfully build Eclipse from source. I gave it a shot two years ago, and more recently, I spent the last two months frantically trying to build the Eclipse 3.6/3.5/3.7 SDKs, without any success. It seems like I am not alone in this. If at any point fortune strikes me, you can be certain that Eclipse packages with split editor support will appear here immediately. If anyone is willing and able to help with this, please get in touch!
Peace
A new split editor prototype that is integrated into the Eclipse workbench API has been available as a patch on the Eclipse Bugzilla for some time now. Unfortunately, I have not able to create an easily deployable plugin that can be installed easily in any Eclipse 3.4 distribution (by copying to the dropins or plugins directories). Even if I did I would probably have to worry about the legal aspects of redistributing Eclipse code, since the plugin will no longer only contain my code.
That said, you can test out the latest split editor by checking out the o.e.ui.workbench project in Eclipse, applying the patch from bugzilla, and debuggin Eclipse from Eclipse. There are no immediately visible changes, but it would be very helpful to have as many people as possible test the split editor in everyday use. I do not expect a lot of users to go through the above procedure, however, and so I will keep trying to get an easily installable package out.
Next time I will talk about the internal integration design of the split editor because I believe this is the most interesting part of all. This will be of particular interest to Eclipse plugin developers who want to know how to enable editor splitting for their custom editors.
There is no new Java split editor yet.
I got overwhelmed by new issues that I discovered while testing last week’s prototype including the fact that most preference changes do not propagate to both editors or cause exceptions.
I am looking into the alternative MultiEditor-based approach and this is leading me to some interesting ideas that I am about to try out… so there should be interesting split-editor-related stuff coming soon.
The first working prototype of a working split editor is here. You can download it and play with it in Eclipse 3.4.
Basic functions like text cursor, current line highlight (these did not work in the first prototype), undo/redo, cut/copy/paste, status bar items (insert mode, line and column numbers) work fine and stay in sync when switching between the top and bottom half of the split editor.
There are also some known issues:
- Ctrl+Left/Right/Home/End keyboard shortcuts always operate on the top part of the split editor, even if the cursor is (blinking) in the bottom half.
- Navigating back and forth using the Alt-Left/Right keys browser-style does not remember the correct editor along with the location and doe not move between the top/bottom half of the editor. I actually have no plans of fixing this. This problem also occurs when opening multiple editor tabs.
Here are some images that demonstrate how to open and use the split editor.
First select the Open With dialog…

Then select the [Split Text Editor] option…

Split the Editor by clicking and dragging on the narrow line that runs all the way across above the first line.

And there you go… long live the split editor!

You can try different commands out and see if they work when you move between the two sides (top and bottom) of the editor…

That’s it for now. Enjoy!
Bonus The plugin now includes source code so you can see the kind of monster that lurks in the background to make editor splitting work.
Up Next Next up is a java code splitter, after I resolve the remaining known issues with basic editing functionality. I will also put up an update site for faster/easier delivery of future updates.
In the true spirit of “release early, release often” I am making my first prototype of a split editor available now as an Eclipse plugin. The plugin works in the new Eclipse 3.4 Ganymede. Download, place in your Eclipse dropins directory and you’re set to go.
Instructions on how to test the plugin are available on the wiki.
Keep in mind that this is a very early prototype and it barely works. There are a lot of issues. If you do download it, please feel free to share your experience with me by posting your (encouraging/bashful/hateful/frustrated/…) comment to this blog or the wiki.
There will be lots more in the coming weeks, so stay tuned!
Welcome! I am working on implementing a split editor for Eclipse as part of Google Summer of Code 2008.
I will track my progress on the project in this blog and on the Eclipse Wiki page dedicated to my project.
Stay tuned!
-
Categories
-
Calendar
January 2012 M T W T F S S « Nov 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 -
Meta
