Egg
=========
.. |ss| raw:: html
.. |se| raw:: html
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.
..
Egg allows class methods, but does not have metaclasses. Instead, it adds
class methods as instance methods of the classes.
A similar approach can be taken to remove class methods, and metaclasses altogether,
by replacing them with module methods: instead of defining :code:`Time>>#current`
we define :code:`Time>>#currentTime` (Time corresponds to the module not the class).
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, :code:`anObject js::asJson` sends :code:`asJson` to :code:`anObject`
filtering lookup through :code:`js` module. :code:`anObject asJson` results in a
:code:`doesNotUnderstand` (unless :code:`asJson` was also defined in the class of :code:`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 :code:`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 :code:`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?).
.. toctree::
:maxdepth: 2
:hidden: