Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Latest commit

 

History

History
146 lines (125 loc) · 5.97 KB

ROADMAP.org

File metadata and controls

146 lines (125 loc) · 5.97 KB

Siren 1.0 - Seashore

The roadmap for the first release of Mermaid. It should include all of the language’s semantics, plus a working VM based on live objects (like Pharo/Squeak/etc), and a visual IDE for working with those objects.

Eventually the idea is to separate this into a server VM, which takes care of handling the live objects for us, and several clients, which can interact with the server. The IDE would be a client, but the information from the VM could also be used by text editors (like Emacs), external debuggers, etc.

Language

[#C] Don’t inherit from Object.prototype by default

Currently all objects inherit from Object.prototype, implicitly. With the current settings, this isn’t a problem because there aren’t many behaviours set in Object.prototype. This might change in the future, so it’s interesting to require people to explicitly inherit from Object.prototype instead.

If objects inherit from null, they won’t have a send-to:in:with: message defined, however, so we’d need to define that for these objects as well.

[#A] Have global bindings resolve as messages sent to the Global object

We should have Self’s equivalent of Lobby, a global namespace that’s the entrypoint for all objects in the system. Variables that don’t exist in the current namespace should be message sends to the global object.

We can move several things that are currently ad-hoc (e.g.: String, Object, etc.) to this global namespace. It makes sense to have messages go Local Bindings -> Module -> Global as well.

Get rid of = in message definitions

It’s not strictly necessary in the grammar, and we could have a cleaner language overall, but it’s mostly a cosmetic change, and I’m not sure it delivers that much value.

[#A] Implement non-local returns for blocks

For now, this can probably be handled by using try/catch:

extend Array with { empty? = this each: { a | ^false }; true }

Turns into:

Array.prototype[‘empty?’] = function() { try { this.forEach(function(a) { throw false; }); return true; } catch(result) { return result; } }

Add interfaces for structural contracts

Contracts would help with feedback in using objects in the system, and avoid errors from sending incorrect messages to objects. I’m not quite sure how the system could use this information to provide better feedback for the user yet though, so it’s something to think about.

[#B] Allow expressions in extend

The extend construct supports only literal objects for now, because it must construct a mapping of message names to selector values. It would be interesting to support arbitrary expressions that resolve to objects in this construct, but we need to be able to gather all message names for the selector values the object supports.

[#A] Allow rebinding names in using/use

Currently there’s no way of resolving namespacing conflicts when introducing new message resolutions with using/use. Allowing one to remap message names when unpacking a particular trait in the namespace would solve this.

[#B] Define module & language version in modules

Modules should provide their version and the version of the language they use. This could allow migration from older versions of the language, or better error reporting on older/newer compilers.

[#B] Have let a = b propagate a as the name metadata for b

Compiler

Functions only need to be bound if they contain this expressions

Currently all lambda functions compile to (function(...){ ... }).bind(this), which is unnecessary when this doesn’t happen inside that expression. We can avoid the overhead by having a simple pass where we revert the bound state of the lambda if it doesn’t use a this expression inside of it.

Avoid using Function#bind for bound functions

`.bind` handles a lot of cases we don’t care about. We can instead have a separate pass on methods that checks if any function refers to `this`, in which case we add a `$this` binding and have those functions refer to that.

In other cases, we might want to use our own `.bind` implementation.

Have separate `send` functions for different arities

This way we pay less for invoking functions of smaller arities (the common case).

Soft typing

Specialise `send` for known types, IC dynamic sends

This will require bigger file sizes, but will also give us more speed.

Disallow duplicated binding declaration

Libraries

Meta-data and Mirror-based reflection

Should allow people to add meta-data to an object, and query meta-data about that object. Meta-data includes things like “which messages this object responds to?”, and “which objects does this object delegate to?” as well.

IO and concurrency

For handling I/O and concurrency, Mermaid should provide:

  • [ ] CSP channels
  • [ ] Observable streams
  • [ ] Task monad
  • [ ] Future monad (memoised Task)
  • [ ] Transducers
  • [ ] High-level asynchronous combinators

Operating system services

Should wrap the Node libraries for:

  • [ ] Managing the current process and forking new ones;
  • [ ] Dealing with the File System (making paths, files, and directories be plain objects)
  • [ ] The OS library;

Collections

  • [ ] Linked lists
  • [ ] Vectors / Arrays
  • [ ] Queues
  • [ ] Stacks
  • [ ] Maps
  • [ ] Sets

Networking

  • [ ] HTTP / HTTPS
  • [ ] Raw sockets
  • [ ] Dealing with URLs as objects, rather than strings

Graphical User Interface

  • [ ] Component-based interfaces (like React)

Exception handling and other core libraries

  • [ ] Maybe values
  • [ ] Either values
  • [ ] Validation values
  • [ ] Better date handling (maybe wrap Moment.js)
  • [ ] Wrapping all core JS objects