Playing With Self

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.

Clean Image

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

New Empty Object

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

Adding a Slot

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

Thelonious

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

Thelonious Success

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

Slots

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

Get Slot Value

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.

Empty Object

Now, we add a special slot and call it parent*

Parent link

We don't set it to a value so that it defaults to nil

Made parent link

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.

nil

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

Linked

Now, to test that it worked, click on "E" in the child object and type

hair
Inheritance at work

Sweet! Now, we can override slots in the child, right?

Slot override

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

Error userQuery

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

link to lobby

Now, if you try "Do it" on greet it should give you

Greet

And 'Thelonious Jr.' should also be able to do this

Jr Greet

Sweet!

Comparison With Javascript

With a cursory look at the language Self, here are some of the differences between it and Javascript:

  1. It supports multiple inheritance, name clashes will result in a runtime error.
  2. Implicit self. No need to write "this." within the method body like Javascript.
  3. 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.
  4. There's no constructor. You construct object using literals or by cloning another object.
  5. Reflection is done with a special mirror object attached each object's _Mirror slot.
  6. There is support for referencing a super method using a special resend syntax.
blog comments powered by Disqus