Why Smalltalk?

This is a question is occasionally asked by students and here is the answer.

We are not religious. This choice is not dogmatic. We do both research in programming languages and tool support for software evolution. In both cases Smalltalk is handy:

  • Programming language — Smalltalk is extermely uniform. Experimenting with a language change is faster in Smalltak, than say, Java or Ruby. Their syntax and sets of rules are bigger, which implies more work.
  • Tool Support — If you want to extend the environment with more browsers/views/features, you can do it easily. Also, tool support and meta-programming go well together. You don’t have a separation between application code and environment code. This makes the whole system very malleable to experiement with.

There exist other research platforms out there to ease experimentations in either category. They don’t match however with the versatility of Smalltalk, which remains thus a very competitive choice to consider. Usually, we mature our project to Java or Eclipse only after initial success in Smalltalk.

Smalltalk Anthology

  • Smalltalk 80: the Language and its Implementation, by Adele Goldberg
  • Smalltalk-80: Bits of History, Words of Advice, by Glenn Krasner
  • Design Principles Behind Smalltalk, by Daniel H. Ingalls
  • The early history of Smalltalk, by Alan Kay
  • Smalltalk Best Practice Patterns, by Kent Beck
  • Smalltalk: a Reflective Language, by F. Rivard
  • Back to the future: the story of Squeak, a practical Smalltalk written in itself, by Daniel H. Ingalls et al.
  • Special issue on Smalltalk, BYTE magazine 1981

Ownership for Dynamic Languages

Edit: the idea presented in this post was worked out into a consistent language feature and accepted for publication.

Ownership type systems have been designed for statically typed languages to confine and constraint aliasing, which in turn increases security and safety. Ownership type systems are conservative, and can only enforce properties that are known to hold globally and statically.

Rather than taking a static view on ownership, a dynamic view would be more natural–and accurate–and could also be applied to dynamic languages. The pendent of static typing in dynamic languages is testing. Ownership violations would raise run-time errors. The system would need to be tested to ensure it is free of ownership violation. This bears resemblance with contracts, and ownership could be seen as special kind of run-time contracts. Also, similarly to contracts, once the system has been exhaustively tested, run-time ownership checks could be disabled.

The ownership relationship between objects could be changed at run-time. While we can expect that most of the time, the owner of an object remains the same and is known at object creation-time, this must not necessary be the case. Whether an object can have multiple owners or not is an open question. If we restrict the system to one owner per object, the syntax could be as simple as:

anObject := MyClass newOwn. "create a new instance that will be owned by self"
anObject := MyClass new ownedBy: anOwner. "assigned an arbitraty owner"

Of course, only an ower that satifies the ownership constraint can be assigned, not any object. Once assigned an owner, the system would enforce no aliasing happen that would violate the ownership constraint. In practice, this means that assignments, and parameter passing must be checked at run-time. This is not trivial without entailing a high overhead in space and time.

Combined with resumable exceptions, ownership violations might not be fatal, and could be considered as special events one can catch when objects escape their owners. For instance, when an object escapes its threads, it could be adapted to become thread-safe, or objects could be frozen (i.e. made read-only) when then escape their owner. An variant would be be able to specify a treatment block per ownership relationship, that would be executed if the constraint is broken. By default, objects would have flag that indicates if the contraints holds (for sure) or not. Raising exception or other strategies would be built on top of that.

MyClass new ownedBy: anOwner ifViolated: aBlock. "treatment if constraint is violated"
aFlag := anObject isOwnershipEnforced.

There are few interesting questions around this run-time perspective on ownership:

  • Can certains patterns be better expressed with ownership?
  • Does the ownership information help program understanding?
  • Do objects have one natural owner in practice?
  • Do run-time ownership checking help spot bugs or increase safety?
  • How can run-time ownership checking be made practical from point of view of performance?

Ah! As usual, more questions than answers…