Egg

Egg is a Smalltalk-like system with late-bound names for improved modularity. The main difference is that resolving names dynamically allows for features that are more difficult to implement in traditional Smalltalk-80 systems.

this is a work in progress documentation, the code in the repos might not yet match what is described hereby

1. Namespaces

A namespace is an object that maps symbols to objects. In the original ST-80, the only “namespace” was Smalltalk object, whereas in Egg different contexts use different namespaces, which allow for the coexistence of independent libraries without the names of one interfering with the names of the other.

2. Modules

A module is a conceptual unit that defines a namespace, a series of dependencies, imported names, classes with methods and extension methods. As names defined in a module do not interfere with names defined in other module, the symbols of each module’s namespace are more tightly coupled than in say Smalltalk dictionary. For that reason, and to simplify, Egg classes do not use class variables: i.e. instead of having a SecondsPerMinute in the Timestamp class, you have SecondsPerMinute in the Kernel::Time module.

1. Module Methods (WIP idea/proposal)

Egg allows modules to define a kind of extension methods. These methods are added to the method dictionary of the class being extended, but are bound to the module in which they are defined. The module methods are accessible only with special syntax, by code that previously imported the module of the module method.

For example, anObject js::asJson sends asJson to anObject filtering lookup through js module. anObject asJson results in a doesNotUnderstand (unless asJson was also defined in the class of anObject).

Extensions methods could allow for some interesting features not available in ST-80. In Egg, reflection could be implemented in terms of module methods. To access the class of an object, you will need to import meta module, and then send anObject meta::class.

aRemoteArray meta::class   -> RemoteObject
aRemoteArray remote::class -> Array

As meta is not just a symbol but actually a late-bound variable name, it is possible to make the module itself be dynamic (for example, fetching the module that implements class from a factory:

module := factory metaModule. "will return some module object like 'meta' or 'remote'"
aRemoteArray module::class    "will send class to the module variable"

This could be used to implement some form of safety: as reflection is accessible through module methods, accessing metaobjects could be disabled by prohibiting access to meta module (and to unsafe modules that could leak metaobjects).

It can also be used to stratify runtime implementation level and application level:

anObject vm::isSmallInteger

works as a barrier that can be implemented differently by different virtual machine implementations.

However, mixing dynamic lookup and primitive-like behavior might not work well (doesn’t vm lookup cause an infinite recursion? should a JIT lookup vm or isSmallInteger statically? is vm::isSmallInteger atomic in any sense?).