Programming Language for Old Timers

by David A. Moon
February 2006 .. September 2008

Comments and criticisms to dave underscore moon atsign alum dot mit dot edu.

Previous page   Table of Contents   Next page

Executable Code Model

All executable code is packaged into methods, which accept arguments that can be restricted to specific types or can be anything. A function is composed from one or more methods. When a function is called, it dispatches to the most specific main method that accepts the supplied number of arguments and the supplied keyword arguments and is applicable to the actual types of the arguments. If there is no applicable main method, the function signals an error.

Function call also dispatches to applicable first and last methods, and the most specific applicable main method can invoke a less specific applicable main method, as explained earlier.

Methods have zero or more required parameters and can also have optional parameters and either an indefinite number of arguments or keyword parameters that are identified by name in the call. All parameters can have type restrictions. Optional and keyword parameters can have default values. A method's parameter list can also declare the number and types of its return values.

A method is only applicable to a call if the number of arguments in that call is acceptable to its parameter list. This allows unary and binary - operators to be the same function. It also allows [ to have a rest parameter in some methods while other methods take exactly 2 arguments. There are no restrictions on compatibility of the parameter lists of two methods that are part of the same function, unlike in Common Lisp.

As noted above, a type is a class, a protocol, a range of integers, or a union of types. (There is nothing like Common Lisp's EQL type.)

A method can reference definitions in any scope enclosing the method. Thus all methods are closures in the Lisp sense of closure.

An expression can produce multiple values. The values are not packaged in a tuple; the extra values are optional to the user of the expression, as in Common Lisp.

Non-local transfers of control are possible by calling an exit function, which forces control to return from the place where the exit function was created. The arguments to the exit function become the values returned. Calling an exit function destroys the intervening state; this is not like Scheme continuations.

Previous page   Table of Contents   Next page