Re: Michael Lucas-Smith: Symbolic Instance Variables
Michael-Lucas Smith has been dabbling in language design and prototype-basis, which is always good, since as people dive into unexplored areas, they learn more and become better informed. He updated it with some more infomration. I like various points, but want to correct various fallacies as well:
...So given that we're blue skying, one thing we can try and do is give our systems more meaning. What does that mean? Well generally, it means less data and more information.
To quibble, information is built on and higher-order than data. It's a meta-transition, and it's better for the audience if they learn this.
The Metaclass structure is one example where we get information from our system. By having it, we get tremendous reflection. Without it, we have no way of reflecting on our information and new organisation. One cry that arose out of my last post was that I was dumping classes which were really useful.
And there are other ways to have meta-object protocols than classes and meta-classes.
Okay, so instead of classes, let's say we have Prototype's. Prototype's are prototypical objects for something.. eg: a Cup. One interesting thing about Prototype's is that the "deep" hierarchies problem you get with classes doesn't exist. The structure to get to a Prototype is artificial and only meaningful when you want to see how code is inherited.
The use of prototypes does not eliminate or elide any idioms from class-based languages, including inheritance. It just removes restrictions and generalizes a bit - the object-class or object-meta relation just becomes a slot. A lot of prototype-enthused quacks think that because there are no classes, that the old patterns will/should/might be thrown out, but this is simply a fallacy, usually generated by undue enthusiasm or reaction to it.
So how do you recognise a Prototype? In Smalltalk you recognise a Class because it subclasses form.. well.. Class. I think this is a bit of a waste personally. Why force something to "subclass" just to give it a symbolic identity.
In Self and Slate, you ask an object if it isWellKnown, which checks for a conventional path from the root object which acts as a global namespace to the given one via name-oriented paths. Regardless of how "cool" prototypes are, well-known-ness is a useful property since you can think of it as something that has been published (by the definer) and subscribed to (by each user).
While I'm on the subject of symbolic identity - why is it we name instance variables? Presumeably it's so we know what they are - right? Well, interesting you should say that (even if you didn't ;>). A name is only useful to a human. Computers need something more for it to be useful - take the Metaclass hierarchy - it's complex, but not too much. It's just complex enough that a computer can use it.
Sure, and Smalltalk-80 traditionally throws out the names at run-time already. The names are for the programmers, and for identifiability per se.
So what if I say that I think instance variables are crime against programming? - Instead, we should be describing relationships and associations. When I say "children" do I mean tree nodes, literally the children of a person, or something else entirely. If it's on a Person, a human can assert that it's literally the children of a person. But that's not good enough - our machine should be able to know this too. So instead of having names, let's have relationships. I'll say that Person has children "the kind that are actual children" and a TreeNode has children "the kind that is a structure".
This is a good idea, but you have to remember that these relationships you describe still must be identifiable. This is very significant, as you can create multiple relationship descriptions which mean the same thing to a person. This sort of problem is just like using synonyms for various slot-names which mean the same thing. Synonym or equivalent phrase/formula... it amounts to the same thing on a different level. And, if you use Smalltalk object-identity for this identification, or introduce a canonicalization, it is the same thing as a Symbol only not based on the String datatype! Common Lisp's symbol design has acknowledged this for years; its symbol design is abstracted from mere byte-string tossing. So you wind up emulating the same design pattern as the original Symbol pattern on a different level - and without the integration, something is lost.
Now to go back around on myself, if I want to identify a Prototype, I relate to it from my Package that "said object" is a Prototype by having a prototype "the language concept" relationship to it.
Ah, and if a package has multiple prototypes, it will have multiple relationships labeled such. Congratulations! You have re-discovered frames, an old (and still quite useful) information-structuring concept born in the AI field! (Made by this obscure guy who goes by the name of "Marvin Minsky"! (sic)) But frames and the notion of an object in a prototype system are different concepts with different resulting philosophies, and you should be aware of that and use the label usefully.
This has a lot of implications. I can now write components that traverse known relationships. I can allow any object to have structure:children relationships and I can then make a widget that knows how to render a Tree from structure:children relationships. Now -any- object structure in the system that uses that kind of relationship can use my relationship!
Yes, and this is a nice generalization of a pattern we have been cooking up for Slate, although we have been using block parameters so far. I will keep this in mind when our syntax has been abstracted as well (this has been planned for a while, but depends on our particular UI framework working).
In fact, code browsers would be following various kinds of relationships, such as "prototype" or "package" or "method". We are now modeling information in our system. Instead of having method names and instance variables, we have relationships that end at some data or a method. On my Person I can now have genealogy:children, security:children, genealogy:parents, security:parents and they know the difference. I can now render my Person in a security editor and also render my Person in a genealogy editor!
And you can also use RDF to describe all of this in a serialized public format; I wouldn't doubt that that's your inspirations, and it's no coincidence that RDF was made by people well-informed of frame systems.
Now that we're unconstrained by the kinds of relationships we can make in the system, we can also extend the system at infinitum. If I wanted to add a comment to each method in the system, I'd simply write a comment editor which used and made metadata:comment relationships to methods in the code browser.
Ok, so you want to make a language directly oriented to dealing with RDF. What does this have to do with Smalltalk? Will you keep some of the syntax and semantics around just for sentimentality's sake (you'll have to justify it, as you'll discover)? If you don't, you have very little reason to relate a frame language design to Smalltalk.
Remember - I dumped instance variable declaration? Here's the implication - I could attach my comment editor (hell, metadata editor) to any object in any subsystem of my application.
If your language (let alone the editor) is that powerful, then generating the instance slot declaration is trivial by comparison. You abstract the syntax away, and then claim that variable declarations being inferable is an extra gain? I don't see the point here, except as a rhetorical device to obscure your actual intent and design goal, especially since the actual semantics require knowledge of where the somewhere is that some relationship's object points to.
Pretty powerful eh?
Yes, but you spend too much time off by yourself not checking out the relevant projects, and not knowing the lessons of those who have gone before.