Sandbox/Elm Programming Language
- First-class event management model for threading, co-routines, IPC, and messaging
- Full reflection for maximal self-validation and simplicity of adding productivity tools
- Collaboration functionality: versioning, meta-programming, self-verification, etc. to ensure disparate parts work together
Table of Contents
- Contexts and Closures
- Functions and Methods
- Modules : collections of objects, classes, methods
- Unit tests
- Pre-conditions, post-conditions
- API Documentation
- RTTI - needed for self-validation and consistency checking (e.g. enumerate all the function parameters to ensure all have associated unit tests and documentation)
Functions are Meta-Functions
All functions are essentially meta-functions, or that is to say, template functions.
Elm defines concepts which are like class definitions that define the signatures of methods as well as template preconditions and postconditions on each method. Any discrete type that meets the requirement of the concept can be passed to a function.
A discrete type as used by a function implicitly defines a concept by the methods it uses. If another type is passed to a function accepting a different type, an concept-adapter is search for that will map one type operation to the other: this is not a conversion or copy, this is a new instantiation of the function for that new type.
A function call is roughly structured as
- symbol table
- return value
Every function has a prologue and an epilogue (as well as a body). Other functions with the same parameters can be attached dynamically to/from the prologue and epilogue.
An empty function therefore can act a manner similar to a slot/signal or C# delegate.
The VM is responsible for optimizing functions without attached prologue or epilogues into efficient, bare functions.
- Mimic slot/signal mechanism of Qt
- Add instrumentation for profiling and code coverage
- How is the call order determined?
- Can a prologue function abort the call to the body of the function?
- Can this same mechanism be used to override methods?
Attach a lambda function to the mouseClick event.
A concept defines:
- A set of required properties (i.e. functions) on a object
- A set of zero or more pre-conditions and post-conditions on each method when calling each object function
- A set of invariants that apply as pre-conditions and post-conditions to all functions on the object
When a symbol is created, it refers to a piece of data. This reference has one of several types.
Special value that says the symbol has a name and a type but does not actually refer to any underlying data object.
In C# there is a concept of Nullable objects: in Elm all objects are effectively nullable (performance note: the VM assumes objects are non-nullable until they are assigned null, at which point the internal storage mechanism for the object may change; in other words, the performance penalty for nullability should not occur until it is used).
The data referred to by the symbol is cloned. The symbol now references a copy of whatever it was assigned.
The data is reference counted. The symbol refers to the same underlying object it has been assigned.
Same as a shared reference, but when all other references to the object go out of scope, this reference automatically is set to the Null value.
The virtual machine relies on a
import statement to pull in more objects into the current namespace and execution context. The repository is simply a set of modules, each with a specific version.
There is a difference between executing a module and importing a module. The execution will start at the top and only create new objects as they are encountered. The import will pull in a set of names into the current content without executing any of the code associated with those objects. (Note: does this have implications on self-modifying code? Newly introduced symbols?). The virtual machine should also have a cache of names from prior imports to speed up the process.
Need ability to automatically run unit tests on a module
- Each test is pass / fail
- If fail, provide detail log such as input arguments, diff information, etc.
- Code coverage (can the VM be instrumented to do this?)
References vs. Clones
In the above example, there's an imaginary window class that has two properties. One is a shared property on window and the other is an instance property. When "window" is cloned, a reference to the parent/prototype invokeClick will be made, but a copy of onClick will be made.
Therefore, to attach a delegate when any click occurs on any window, the delegate can be attached to
invokeClick.prologue. To attach a delegate to a particular window,
onClick.prologue should be used. window.invokeClick and mywin.invokeClick should be pointing to the same underlying function object.
Note on syntax:
- .property the dot operator means "property of the current function"
- $property the dollar-sign operator means "property of the current execution context"
- Instead of functions having arguments with explicit types, have each argument have a set of preconditions. I.e. need to check that the object type supports the required concepts: i.e. is it a collection object, a decimal object, etc. Rely on the VM to instantiate these templates into native code for each variation.
- Unit test tree: ability to test individual components, the whole tree, or by a set of tags?
Limitations of C++
If C++ can handle a problem elegantly, there is no need for Elm. This section intends to list limitations of C++ that make certain problems awkward to solve. It also attempts to list the reason why C++ includes these limitation (i.e. what would be the trade-off if C++ resolved the issue?).
Lack of garbage collection
Reference counting, specialized heaps, etc. can be used; but the fact is that if it is not on by default, it loses value. However, if it were always on, the certain low-level programs could not longer be written in C++.