MLud: Feature Summary

MLud is an object-oriented, prototype-based language designed for building on-line collaborative environments and other runtime-extensible systems. Its compiler and runtime environment are both implemented in Standard ML. It possesses a variety of features targeted towards the types of situations in which it is commonly used. These include:

Object-oriented

MLud, like Smalltalk, is a fully object-oriented language. Even the built-in types each delegate to an object, and nearly all operations are implemented as method calls, so that even the most basic behaviour in the system is fully customizable. Because the language is prototype-based, even what would normally be classes are objects which can be manipulated and examined, which constitutes a limited form of reflection.

Prototype-based

Like Self, Cecil, and some other languages, and unlike Java, C++, or Smalltalk, MLud does not have the separate concepts of classes and instances. Instead, there are only objects, which delegate messages to a fixed set of other objects called their parents.

Thus, a class is represented in MLud as an object, complete with state, while the equivalent of its instances delegate to the class object, except that functionality can be added to the "instances", and new objects can, in turn, delegate to them. The resulting structures allow high flexibility at run-time, and foster fast prototyping and better conceptual models of the system.

Dynamic delegation of types

Dynamic delegation, supported in Smalltalk but not in Java, C++, or Cecil, is a mechanism allowing the construction and modification of object delegation hierarchies at runtime. In other words, you can change the parent object of an object, radically changing its behaviour, or add new parents to add new behaviour. When used properly, dynamic delegation provides a powerful mechanism for extending objects in the system.

Runtime-extensible

A MLud program is fully runtime-extensible. What this means is that at any time during the run, you can add new objects, add new methods to objects based on a string containing MLud code, remove methods, change delegation hierarchies, and even modify every detail of the functionality of the runtime system and the MLud compiler itself. Because of this, a system can evolve over a long period of time without ever ceasing to run, crucial in collaborative development environments.

Portable

Being based entirely on vanilla SML/NJ and MLud itself, MLud is as portable as the SML/NJ system, which runs on a variety of platforms, even Windows.

Multiple dispatch

Multiple dispatch is a relatively rare feature, currently most notably found in Cecil, which expands on the polymorphism of method calls found in most object-oriented languages. While these languages allow the runtime to choose which method will be called based on the type of the object the method is called on, multiple dispatch allows the method to be chosen based on this as well as the number and type of all the other arguments. This helps separate the treatment of arguments of various types into a hierarchy of methods for handling them; for example, the integer object has separate methods for adding other integers and reals.

Exceptions

Simple exceptions are supported. Any object can be thrown, and it will be caught by the first handler that handles it or an ancestor of it. An exception object in the system library provides the additional functionality of generating stack traces for debugging purposes which the user who caused the offending exception can view.

Inline ML

A common downfall in building any runtime-extensible language is that users often find themselves wanting features for doing a variety of system-level tasks such as networking, file I/O, and calling out to libraries. MLud, instead of adding support for these and many more such things itself, allows you to create methods that directly include inline Standard ML, an extensive language that already has support for nearly anything one might want to do. All primitives in the standard runtime environment are implemented with this mechanism. Not only is this useful for supporting key features, but it's also useful for optimizing key portions of code for speed.

Several useful built-in datatypes

Between the language itself and the standard library, MLud includes support for all of the following datatypes:

Type Description
array A mutable array of arbitrary objects of a fixed size. A literal syntax is provided, as arrays are used in every method call.
boolean A simple true/false value with several boolean operations.
char A single character, with several testing and manipulation operations such as isAlpha.
closure A closure, like Lisp closures or Smalltalk blocks, representing a computation that carries some of the state of the environment in which it was created, usually by an anonymous function literal.
integer An arbitrary-precision integer, with arithmetic, comparative, and limited bitwise operators.
list A sophisticated list data structure allowing insertion or removal at both ends as well as concatenation in amortized constant time; ideal for building stacks, queues, and lists.
map A tree map data structure, mapping arbitrary key objects to arbitrary value objects, like a hash in Perl. A strict order of the keys is maintained. A literal syntax is provided.
real An IEEE floating-point type, including arithmetic and comparative operators.
string A string of characters, including comparison and common string-manipulation methods.
symbol As in Lisp, a type of string used for identification with fast comparison.

All of the sequence objects can have operations mapped, applied, folded, or filtered over them using closure objects, allowing fast and simple ways of manipulating these containers in user code.

Most of the built-in types also support a variety of conversions, among which are toLiteral, a method used to generate a string describing the contents of the object for debug purposes.

Checkpoint persistence

Using a simple related function of Standard ML, MLud is able to save the entire state of the system to disk, so that it can be reloaded after an intentional or unintentional shutdown.


Important features MLud should have that it does not yet have include:

Persistence

The ideal persistence mechanism would be much more powerful, making incremental updates to the disk at all times, as well as enabling controlled distribution of parts of the system to other MLud systems.

Code Security

On a multiuser collaborative system, it's important to have security at the level of the code, so that people cannot, either intentionally or accidentally, invoke functionality that will have adverse effects on the system. Traditional image-based systems such as Smalltalk fail to address this. Currently, MLud only supports this in the form of supplying contextual information, such as the caller object, to a called method.

Mlud home page

Other code from Moonflare

Moonflare home

All text and images, but not necessarily linked material, on this page ©1998-2006 Derrick Coetzee and Moonflare and may not be reproduced or used for any purpose without prior written permission except where otherwise indicated.