Self is an
object-oriented programming
Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code. The data is in the form of fields (often known as attributes or ''properties''), and the code is in the form of pr ...
language
Language is a structured system of communication. The structure of a language is its grammar and the free components are its vocabulary. Languages are the primary means by which humans communicate, and may be conveyed through a variety of met ...
based on the concept of ''
prototypes
A prototype is an early sample, model, or release of a product built to test a concept or process. It is a term used in a variety of contexts, including semantics, design, electronics, and software programming. A prototype is generally used to ...
''. Self began as a dialect of
Smalltalk
Smalltalk is an object-oriented, dynamically typed reflective programming language. It was designed and created in part for educational use, specifically for constructionist learning, at the Learning Research Group (LRG) of Xerox PARC by Alan Ka ...
, being
dynamically typed
In computer programming, a type system is a logical system comprising a set of rules that assigns a property called a type to every "term" (a word, phrase, or other set of symbols). Usually the terms are various constructs of a computer progra ...
and using
just-in-time compilation
In computing, just-in-time (JIT) compilation (also dynamic translation or run-time compilations) is a way of executing computer code that involves compilation during execution of a program (at run time) rather than before execution. This may cons ...
(JIT) as well as the prototype-based approach to objects: it was first used as an experimental test system for language design in the 1980s and 1990s. In 2006, Self was still being developed as part of the Klein project, which was a Self virtual machine written fully in Self. The latest version is 2017.1 released in May 2017.
Several just-in-time compilation techniques were pioneered and improved in Self research as they were required to allow a very high level object oriented language to perform at up to half the speed of optimized C. Much of the development of Self took place at
Sun Microsystems
Sun Microsystems, Inc. (Sun for short) was an American technology company that sold computers, computer components, software, and information technology services and created the Java programming language, the Solaris operating system, ZFS, the ...
, and the techniques they developed were later deployed for
Java
Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's List ...
's
HotSpot virtual machine
In computing, a virtual machine (VM) is the virtualization/emulation of a computer system. Virtual machines are based on computer architectures and provide functionality of a physical computer. Their implementations may involve specialized hardw ...
.
At one point a version of Smalltalk was implemented in Self. Because it was able to use the JIT, this also gave extremely good performance.
History
Self was designed mostly by
David Ungar and Randall Smith in 1986 while working at
Xerox PARC
PARC (Palo Alto Research Center; formerly Xerox PARC) is a research and development company in Palo Alto, California. Founded in 1969 by Jacob E. "Jack" Goldman, chief scientist of Xerox Corporation, the company was originally a division of Xero ...
. Their objective was to push forward the state of the art in object-oriented programming language research, once
Smalltalk-80 was released by the labs and began to be taken seriously by the industry. They moved to
Stanford University
Stanford University, officially Leland Stanford Junior University, is a private research university in Stanford, California. The campus occupies , among the largest in the United States, and enrolls over 17,000 students. Stanford is consider ...
and continued work on the language, building the first working Self compiler in 1987. At that point, focus changed to attempting to bring up an entire system for Self, as opposed to just the language.
The first public release was in 1990, and the next year the team moved to
Sun Microsystems
Sun Microsystems, Inc. (Sun for short) was an American technology company that sold computers, computer components, software, and information technology services and created the Java programming language, the Solaris operating system, ZFS, the ...
where they continued work on the language. Several new releases followed until falling largely dormant in 1995 with the 4.0 version. The 4.3 version was released in 2006 and ran on
Mac OS X
macOS (; previously OS X and originally Mac OS X) is a Unix operating system developed and marketed by Apple Inc. since 2001. It is the primary operating system for Apple's Mac (computer), Mac computers. Within the market of ...
and
Solaris
Solaris may refer to:
Arts and entertainment Literature, television and film
* ''Solaris'' (novel), a 1961 science fiction novel by Stanisław Lem
** ''Solaris'' (1968 film), directed by Boris Nirenburg
** ''Solaris'' (1972 film), directed by ...
. A new release in 2010, version 4.4, has been developed by a group comprising some of the original team and independent programmers and is available for Mac OS X and
Linux
Linux ( or ) is a family of open-source Unix-like operating systems based on the Linux kernel, an operating system kernel first released on September 17, 1991, by Linus Torvalds. Linux is typically packaged as a Linux distribution, which ...
, as are all following versions. The follow-up 4.5 was released in January 2014, and three years later, version 2017.1 was released in May 2017.
The
Morphic user interface construction environment was originally developed by Randy Smith and John Maloney for the Self programming language. Morphic has been ported to other notable programming languages including
Squeak
Squeak is an object-oriented, class-based, and reflective programming language. It was derived from Smalltalk-80 by a group that included some of Smalltalk-80's original developers, initially at Apple Computer, then at Walt Disney Imagineering, ...
,
JavaScript
JavaScript (), often abbreviated as JS, is a programming language that is one of the core technologies of the World Wide Web, alongside HTML and CSS. As of 2022, 98% of Website, websites use JavaScript on the Client (computing), client side ...
,
Python
Python may refer to:
Snakes
* Pythonidae, a family of nonvenomous snakes found in Africa, Asia, and Australia
** ''Python'' (genus), a genus of Pythonidae found in Africa and Asia
* Python (mythology), a mythical serpent
Computing
* Python (pro ...
, and
Objective-C
Objective-C is a general-purpose, object-oriented programming language that adds Smalltalk-style messaging to the C programming language. Originally developed by Brad Cox and Tom Love in the early 1980s, it was selected by NeXT for its NeXTS ...
.
Self also inspired a number of languages based on its concepts. Most notable, perhaps, were
NewtonScript
NewtonScript is a prototype-based programming language created to write programs for the Newton platform. It is heavily influenced by the Self programming language, but modified to be more suited to needs of mobile and embedded devices.
Histo ...
for the
Apple Newton
The Newton is a series of personal digital assistants (PDAs) developed and marketed by Apple Computer, Inc. An early device in the PDA category (the Newton originated the term), it was the first to feature handwriting recognition. Apple started ...
and
JavaScript
JavaScript (), often abbreviated as JS, is a programming language that is one of the core technologies of the World Wide Web, alongside HTML and CSS. As of 2022, 98% of Website, websites use JavaScript on the Client (computing), client side ...
used in all modern browsers. Other examples include
Io,
Lisaac and
Agora
The agora (; grc, ἀγορά, romanized: ', meaning "market" in Modern Greek) was a central public space in ancient Greek city-states. It is the best representation of a city-state's response to accommodate the social and political order of t ...
. The
IBM Tivoli Framework's distributed object system, developed in 1990, was, at the lowest level, a prototype based object system inspired by Self.
Prototype-based programming languages
Traditional class-based OO languages are based on a deep-rooted duality:
#
Classes define the basic qualities and behaviours of objects.
#
Object instances are particular manifestations of a class.
For example, suppose objects of the
Vehicle
class have a ''name'' and the ability to perform various actions, such as ''drive to work'' and ''deliver construction materials''.
Bob's car
is a particular object (instance) of the class
Vehicle
, with the name "Bob's car". In theory one can then send a message to
Bob's car
, telling it to ''deliver construction materials''.
This example shows one of the problems with this approach: Bob's car, which happens to be a sports car, is not able to carry and deliver construction materials (in any meaningful sense), but this is a capability that
Vehicle
s are modelled to have. A more useful model arises from the use of
subclassing to create specializations of
Vehicle
; for example
Sports Car
and
Flatbed Truck
. Only objects of the class
Flatbed Truck
need provide a mechanism to ''deliver construction materials''; sports cars, which are ill-suited to that sort of work, need only ''drive fast''. However, this deeper model requires more insight during design, insight that may only come to light as problems arise.
This issue is one of the motivating factors behind prototypes. Unless one can predict with certainty what qualities a set of objects and classes will have in the distant future, one cannot design a class hierarchy properly. All too often the program would eventually need added behaviours, and sections of the system would need to be re-designed (or
refactored
In computer programming and software design, code refactoring is the process of restructuring existing computer code—changing the '' factoring''—without changing its external behavior. Refactoring is intended to improve the design, structur ...
) to break out the objects in a different way. Experience with early OO languages like
Smalltalk
Smalltalk is an object-oriented, dynamically typed reflective programming language. It was designed and created in part for educational use, specifically for constructionist learning, at the Learning Research Group (LRG) of Xerox PARC by Alan Ka ...
showed that this sort of issue came up again and again. Systems would tend to grow to a point and then become very rigid, as the basic classes deep below the programmer's code grew to be simply "wrong". Without some way to easily change the original class, serious problems could arise.
Dynamic languages such as Smalltalk allowed for this sort of change via well-known methods in the classes; by changing the class, the objects based on it would change their behaviour. However, such changes had to be done very carefully, as other objects based on the same class might be expecting this "wrong" behavior: "wrong" is often dependent on the context. (This is one form of the
fragile base class problem.) Further, in languages like
C++
C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
, where subclasses can be compiled separately from superclasses, a change to a superclass can actually break precompiled subclass methods. (This is another form of the fragile base class problem, and also one form of the
fragile binary interface problem {{Citations missing, date=May 2009
The fragile binary interface problem or FBI is a shortcoming of certain object-oriented programming language compilers, in which internal changes to an underlying class library can cause descendant libraries or pr ...
.)
In Self, and other prototype-based languages, the duality between classes and object instances is eliminated.
Instead of having an "instance" of an object that is based on some "class", in Self one makes a copy of an existing object, and changes it. So
Bob's car
would be created by making a copy of an existing "Vehicle" object, and then adding the ''drive fast'' method, modelling the fact that it happens to be a
Porsche 911
The Porsche 911 (pronounced ''Nine Eleven'' or in german: Neunelfer) is a two-door 2+2 high performance rear-engined sports car introduced in September 1964 by Porsche AG of Stuttgart, Germany. It has a rear-mounted flat-six engine and origin ...
. Basic objects that are used primarily to make copies are known as ''prototypes''. This technique is claimed to greatly simplify dynamism. If an existing object (or set of objects) proves to be an inadequate model, a programmer may simply create a modified object with the correct behavior, and use that instead. Code which uses the existing objects is not changed.
Description
Self objects are a collection of "slots". Slots are accessor methods that return values, and placing a colon after the name of a slot sets the value. For example, for a slot called "name",
myPerson name
returns the value in name, and
myPerson name:'foo'
sets it.
Self, like Smalltalk, uses ''blocks'' for flow control and other duties. Methods are objects containing code in addition to slots (which they use for arguments and temporary values), and can be placed in a Self slot just like any other object: a number for example. The syntax remains the same in either case.
Note that there is no distinction in Self between fields and methods: everything is a slot. Since accessing slots via messages forms the majority of the syntax in Self, many messages are sent to "self", and the "self" can be left off (hence the name).
Basic syntax
The syntax for accessing slots is similar to that of Smalltalk. Three kinds of messages are available:
;unary :
''receiver'' slot_name
;binary :
''receiver'' + ''argument''
;keyword :
''receiver'' keyword: ''arg1'' With: ''arg2''
All messages return results, so the receiver (if present) and arguments can be themselves the result of other messages. Following a message by a period means Self will discard the returned value. For example:
'Hello, World!' print.
This is the Self version of the
hello world
''Hello'' is a salutation or greeting in the English language. It is first attested in writing from 1826. Early uses
''Hello'', with that spelling, was used in publications in the U.S. as early as the 18 October 1826 edition of the '' Norwich ...
program. The
'
syntax indicates a literal string object. Other literals include numbers, blocks and general objects.
Grouping can be forced by using parentheses. In the absence of explicit grouping, the unary messages are considered to have the highest precedence followed by binary (grouping left to right) and the keywords having the lowest. The use of keywords for assignment would lead to some extra parenthesis where expressions also had keyword messages, so to avoid that Self requires that the first part of a keyword message selector start with a lowercase letter, and subsequent parts start with an uppercase letter.
valid: base bottom
between: ligature bottom + height
And: base top / scale factor.
can be parsed unambiguously, and means the same as:
valid: ((base bottom)
between: ((ligature bottom) + height)
And: ((base top) / (scale factor))).
In Smalltalk-80, the same expression would look written as:
valid := self base bottom
between: self ligature bottom + self height
and: self base top / self scale factor.
assuming
base
,
ligature
,
height
and
scale
were not
instance variable
In class-based, object-oriented programming, an instance variable is a variable defined in a class (i.e. a member variable), for which each instantiated object of the class has a separate copy, or instance. An instance variable has similariti ...
s of
self
but were, in fact, methods.
Making new objects
Consider a slightly more complex example:
labelWidget copy label: 'Hello, World!'.
makes a copy of the "labelWidget" object with the copy message (no shortcut this time), then sends it a message to put "Hello, World" into the slot called "label". Now to do something with it:
(desktop activeWindow) draw: (labelWidget copy label: 'Hello, World!').
In this case the
(desktop activeWindow)
is performed first, returning the
active window
A window manager is system software that controls the placement and appearance of windows within a windowing system in a graphical user interface. Most window managers are designed to help provide a desktop environment. They work in conjunction ...
from the list of windows that the desktop object knows about. Next (read inner to outer, left to right) the code we examined earlier returns the labelWidget. Finally the widget is sent into the draw slot of the active window.
Delegation
In theory, every Self object is a stand-alone entity. Self has neither classes nor meta-classes. Changes to a particular object do not affect any other, but in some cases it is desirable if they did. Normally an object can understand only messages corresponding to its local slots, but by having one or more slots indicating ''parent'' objects, an object can delegate any message it does not understand itself to the parent object. Any slot can be made a parent pointer by adding an asterisk as a suffix. In this way Self handles duties that would use
inheritance
Inheritance is the practice of receiving private property, Title (property), titles, debts, entitlements, Privilege (law), privileges, rights, and Law of obligations, obligations upon the death of an individual. The rules of inheritance differ ...
in class-based languages. Delegation can also be used to implement features such as
namespace
In computing, a namespace is a set of signs (''names'') that are used to identify and refer to objects of various kinds. A namespace ensures that all of a given set of objects have unique names so that they can be easily identified.
Namespaces ...
s and
lexical scoping
In computer programming, the scope of a name binding (an association of a name to an entity, such as a variable) is the part of a program where the name binding is valid; that is, where the name can be used to refer to the entity. In other parts ...
.
For example, suppose an object is defined called "bank account", that is used in a simple bookkeeping application. Usually, this object would be created with the methods inside, perhaps "deposit" and "withdraw", and any data slots needed by them. This is a prototype, which is only special in the way it is used since it also happens to be a fully functional bank account.
Traits
Making a clone of this object for "Bob's account" will create a new object which starts out exactly like the prototype. In this case we have copied the slots including the methods and any data. However a more common solution is to first make a more simple object called a
traits object which contains the items that one would normally associate with a class.
In this example the "bank account" object would not have the deposit and withdraw method, but would have as a parent an object that did. In this way many copies of the bank account object can be made, but we can still change the behaviour of them all by changing the slots in that root object.
How is this any different from a traditional class? Well consider the meaning of:
myObject parent: someOtherObject.
This excerpt changes the "class" of myObject at runtime by changing the value associated with the 'parent*' slot (the asterisk is part of the slot name, but not the corresponding messages). Unlike with inheritance or lexical scoping, the delegate object can be modified at runtime.
Adding slots
Objects in Self can be modified to include additional slots. This can be done using the graphical programming environment, or with the primitive '_AddSlots:'. A primitive has the same syntax as a normal keyword message, but its name starts with the underscore character. The _AddSlots primitive should be avoided because it is a left over from early implementations. However, we will show it in the example below because it makes the code shorter.
An earlier example was about refactoring a simple class called Vehicle in order to be able to differentiate the behaviour between cars and trucks. In Self one would accomplish this with something like this:
_AddSlots: (, vehicle <- (, parent* = traits clonable, ) , ).
Since the receiver of the '_AddSlots:' primitive isn't indicated, it is "self". In the case of expressions typed at the prompt, that is an object called the "lobby". The argument for '_AddSlots:' is the object whose slots will be copied over to the receiver. In this case it is a literal object with exactly one slot. The slot's name is 'vehicle' and its value is another literal object. The "<-" notation implies a second slot called 'vehicle:' which can be used to change the first slot's value.
The "=" indicates a constant slot, so there is no corresponding 'parent:'. The literal object that is the initial value of 'vehicle' includes a single slot so it can understand messages related to cloning. A truly empty object, indicated as (, , ) or more simply as (), cannot receive any messages at all.
vehicle _AddSlots: (, name <- 'automobile', ).
Here the receiver is the previous object, which now will include 'name' and 'name:' slots in addition to 'parent*'.
_AddSlots: (, sportsCar <- vehicle copy , ).
sportsCar _AddSlots: (, driveToWork = (''some code, this is a method'') , ).
Though previously 'vehicle' and 'sportsCar' were exactly alike, now the latter includes a new slot with a method that the original doesn't have. Methods can only be included in constant slots.
_AddSlots: (, porsche911 <- sportsCar copy , ).
porsche911 name:'Bobs Porsche'.
The new object 'porsche911' started out exactly like 'sportsCar', but the last message changed the value of its 'name' slot. Note that both still have exactly the same slots even though one of them has a different value.
Environment
One feature of Self is that it is based on the same sort of
virtual machine
In computing, a virtual machine (VM) is the virtualization/emulation of a computer system. Virtual machines are based on computer architectures and provide functionality of a physical computer. Their implementations may involve specialized hardw ...
system that earlier Smalltalk systems used. That is, programs are not
stand-alone entities as they are in languages such as
C, but need their entire memory environment in order to run. This requires that applications be shipped in chunks of saved memory known as ''snapshots'' or ''
images
An image is a visual representation of something. It can be two-dimensional, three-dimensional, or somehow otherwise feed into the visual system to convey information. An image can be an artifact, such as a photograph or other two-dimensiona ...
''. One disadvantage of this approach is that images are sometimes large and unwieldy; however, debugging an image is often simpler than debugging traditional programs because the runtime state is easier to inspect and modify. (The difference between source-based and image-based development is analogous to the difference between class-based and prototypical object-oriented programming.)
In addition, the environment is tailored to the rapid and continual change of the objects in the system. Refactoring a "class" design is as simple as dragging methods out of the existing ancestors into new ones. Simple tasks like test methods can be handled by making a copy, dragging the method into the copy, then changing it. Unlike traditional systems, only the changed object has the new code, and nothing has to be rebuilt in order to test it. If the method works, it can simply be dragged back into the ancestor.
Performance
Self VMs achieved performance of approximately half the speed of optimised C on some benchmarks.
This was achieved by
just-in-time compilation
In computing, just-in-time (JIT) compilation (also dynamic translation or run-time compilations) is a way of executing computer code that involves compilation during execution of a program (at run time) rather than before execution. This may cons ...
techniques which were pioneered and improved in Self research to make a high level language perform this well.
Garbage collection
The
garbage collector
A waste collector, also known as a garbageman, garbage collector, trashman (in the US), binman or (rarely) dustman (in the UK), is a person employed by a public or private enterprise to collect and dispose of municipal solid waste (refuse) and r ...
for Self uses
generational garbage collection which segregates objects by age. By using the memory management system to record page writes a write-barrier can be maintained. This technique gives excellent performance, although after running for some time a full garbage collection can occur, taking considerable time.
Optimizations
The run time system selectively flattens call structures. This gives modest speedups in itself, but allows extensive caching of type information and multiple versions of code for different caller types. This removes the need to do many method lookups and permits conditional branch statements and hard-coded calls to be inserted- often giving C-like performance with no loss of generality at the language level, but on a fully garbage collected system.
See also
* Morphic (software) Morphic is an interface construction environment which uses graphical objects called "Morphs" for simplified GUI-building which allow for flexibility and dynamism. It was originally created for Self, but later, was ported to other programming langua ...
* Cecil (programming language)
Cecil is a pure object-oriented programming language that was developed by Craig Chambers at the University of Washington in 1992 to be part of the Vortex project there. Cecil has many similarities to other object-oriented languages, most notab ...
References
Further reading
Published papers on Self
*
External links
*
*
Former Self Home Page at Sun Microsystems
* ttps://web.archive.org/web/20050427111747/http://www.merlintec.com/lsi/ Merlin Project
Self ported to Linux (without many optimizations)
Automated Refactoring application on sourceforge.net, written for and in Self
Gordon's Page on Self
Prometheus object system on the Community Scheme Wiki
Video demonstrating self
dSelf: distributed extension to the delegation and language Self
{{DEFAULTSORT:Self (Programming Language)
Programming languages
Dynamic programming languages
Dynamically typed programming languages
Object-oriented programming languages
Prototype-based programming languages
Cross-platform free software
Free compilers and interpreters
Programming languages created in 1987
1987 software