The Self Language is a descendant of Smalltalk, and is the language that introduced the concept of prototype inheritance. To get a historical perspective, I wanted to try it out, and luckily, it is still available online despite Sun killing the project in '95.
Install
To install Self, go to its download page and follow the instructions. In short, first, you need to install the VM by running the installer. Next, you need to download a snapshot image. There are two to choose from: the clean(spic 'n span) and the demo(kitchen sink). Next, double click on the image that you downloaded, and you should be good to go.
I am going to do a walkthrough using the clean image because I just want to try out some basic language features. When the environment - or "world" - finishes launching, you are greeted with a large gray space with a shell window on the top left, and a trash can on the top right.
So, let's play around and see how prototype inheritance works in Self. To create a new empty object, type
()
into the shell window and then click the "Get it" button. You should see a new expandable window that says "a slots object". If you expand it, it should look like
This is an empty object, the equivalent of {} in Javascript.
Slots
Now let's add some attributes to it, except in Self, we call them slots. Right-click on the header of this window and select "Add Slot". You should see this
This textarea is where you would write the code for either a value slot or a method slot. The textarea preloads with some examples of what you can write here.
We are going to just add a read-only slot
Just so you know, a read/write value slot would be written as
name <- 'Thelonious'
When you are done, click on the thin green vertical bar on the left side of the window, and it should except the code. If your code has a syntax error, it will complain, and you'll need to try again. If you got it right, you should see this
For fun, let's make a few more slots. Repeat the "Add Slot" procedure, but this time add a hair slot and set it to 'dark and curly', add a plays slot and set it to 'piano'. If things go right you should see
Now, click on the "E" button to get an evaluation console. If you type
plays
into it and click "Get it", you should get the string 'piano' to come out
Okay, so it gets the value correctly.
Inheritance
Cool. Next we are going to create the inheritance link. First, we create an empty object again to represent the child.
Now, we add a special slot and call it parent*.
We don't set it to a value so that it defaults to nil
Next, we need to link it to Thelonious. First click on the little button with two small dots just to the right of the nil. The nil object will come out and you'll see a link from your parent* slot to it.
In Self, any slot that ends in * is a parent link. So, in fact, it supports multiple inheritance! Anyway, we are close to completing the inheritance. Now just drag the link to Thelonious. If you got it, you'll see this
Now, to test that it worked, click on "E" in the child object and type
hair
Sweet! Now, we can override slots in the child, right?
Yup. While we are at it, we'll change the name to 'Thelonious Jr.' too.
Methods
Next, let's create a method. Let's create a greet method on the parent. The greet method will simply popup an alert dialog with the message. It does this using the report: method of userQuery.
userQuery report: 'Hi, I am ', name, ', I have ', hair,
' hair and I play the ', plays, '.'
But, this won't work. Try running it - by clicking "Do it" will give you
It couldn't find the userQuery object within its slots. In Self, the normal convention is to have your object inherit the lobby object in order to have access to all the global variables(this is like the global object in Javascript, aka the public restroom). So okay, we have 'Thelonious' inherit lobby using a link called lobby*. To do this, we first get hold of the lobby object by typing in the shell
lobby
and clicking "Get it". Then, create a slot on 'Thelonious' called lobby* and like to it. You should end up with this
Now, if you try "Do it" on greet it should give you
And 'Thelonious Jr.' should also be able to do this
Sweet!
Comparison With Javascript
With a cursory look at the language Self, here are some of the differences between it and Javascript:
- It supports multiple inheritance, name clashes will result in a runtime error.
- Implicit self. No need to write "this." within the method body like Javascript.
- It differentiates between methods and blocks(in Javascript they are both functions). For this reason, you won't have the ugly Javascript problem of having to manually store a reference to this when you want to use it in inner blocks within a method.
- There's no constructor. You construct object using literals or by cloning another object.
- Reflection is done with a special mirror object attached each object's _Mirror slot.
- There is support for referencing a super method using a special resend syntax.