8.5 KiB
JAVASCRIPT VISION
I see objects as being a sort of combination of a lisp cell and a record: symbols, which are used internally, and are private and non iterable, and record string values, which are iterable, readable, and writable; of course everything becomes locked in when stone.
CELLSCRIPT
Javascript to its core. Objects. What does the language need? It can be quite small, I think. The key is, ANYTHING that we want to be fast and JIT'd, must be present. So, record lookups. These are actually quicker in a jit'd language that have them as a feature. Most things should be libraries. Blobs need to be in the runtime.
Actors and Objects
Actors have a unique memory space and are made up of many objects. Objects are created in the Self style, but with a limitation: only one parent.
Actors only communicate with messages. Messages are a record of data consisting of a few base types: text, numbers, arrays, records, boolean values. There is no RPC, and it is not recommended to build it into your message passing protocol. Messages are very high level things: "do X", which the actor can then go and carry out.
Cell provides a fast way to condense an object for sending.
How is it different from Javascript?
Cell condenses Javascript down into a few core ideas. There are three pillars which cell relies on:
- The idea of actors as a method of communication between parts of a program.
- The idea of objects as a way to organize and encapsulate data.
- The idea of the capability model as security.
Javascript already supplied some of these things; Cell takes the core of Javascript and makes these ideas more explicit, and layers on the actor communication. It removes some goofy suckiness with javascript.
It acts as something like an operating system at the application level. It allows random code to be ran on your machine without worrying it will break something. This is built into the language.
It is completly dynamically typed. In comparison with C, in C, you can treat everything as everything: it is almost not typed at all. If you try to use a type as another type, no error is thrown; it might work, but it mightly silently not work. In Cell, data has a hard type, but if you use it "incorrectly", it will throw, and you can correct it. It's a live system.
Cell is linked very closely with C. It's best to think of cell as a layer for message passing on top of C. It is a way to describe how to translate C tasks from one section of the program to another - or to totally different computers (actors).
As such, cell's primary duty is marshalling data; so it has been designed for that to be as fast as possible. It has a syntax similar to C to make it easy to translate formulae from cell to C (or the other way, if desired).
Unlike many actor languages, Cell does not eschew assignment. You must have some assignment. However, when it comes to actor->actor communication, you do not assign. RPC is too direct: one actor should not care all that much what specific functions another actor has available. It should request it to do something, and get a result, or possibly not get a result. It doesn't care what the actor does as long as that gets done.
But within itself, it will assign; it must. Actors, or cells, are best thought of as computers or nodes within the internet. You request data from a URL by typing it into your browser; that computer you're attempting to reach may not even be on. It very likely has written some other data to disk whenever you contact it. But you're not doing the specific assigning. You just request data with HTTP commands.
Objects and actors
Objects and actors are both similar ideas: they can hold data and respond to messages. Objects, local to an actor, can be thought of more like an RPC idea: they're invoked and return immediately. However, a failed RPC can crash an object; and in that case, the actor halts. It can be corrected.
What does Cell bring you over C?
Programs which are built with C; they're built statically; they're built to not crash; they're built doing extremely low level things, like assignment.
The goal of cell is to thrust your C code into the parallel, actor realm. It lets your code crash and resume it; even rewriting the C code which is butressing your cell code and reloading it live.
There are two primary sorts of Cell modules you create from C code: data and IO. C code like
Where there were two similar things in javscript, one has been deleted and one kept. For example, there is only null now, no undefined. There are not four ways to test for equality; there is one.
The purpose of this is to be a great language for passing messages. So it should be fast at creating records first and foremost, and finding items on them. So it needs first class, jitt'd records.
Finally, it needs to use less memory. Deleting a bunch of this stuff should make that simpler.
What is present? Objects, prototypes, numbers, arrays, strings, true, false, null.
Things to do:
merge typeof and instanceof. Misty has array? stone? number? etc; it needs to be generic. 5 is number returns true.
No new operator. It's the same idea though: simply instead of 'var guy = new sprite({x,y})' you would say 'var guy = sprite({x,y})', and sprite would simply be a function written to return a sprite object.
One number type. Dec64. Numeric stack can be added in later: a bigint library, for example, built inside cell.
Simplify the property attributes stuff. It is simple: objects have text keys and whatever values. Objects can also have objects as values. These work like symbols. You can share them, if desired. No well known symbols exist to eliminate that much misdirection. Obejcts basically work like private keys. If you serialize an object, objects that are keys are not serialized; only textual keys are. You can do something about it with a json() method that is invoked, if you desire. You cannot retrieve
var works like let; use var instead of let
no const
Function closures and _ => all work the same and close over the 'this' variable
Totally delete modules, coroutines, generators, proxy .. this deletes a lot of the big switch statement
Add the 'go' statement for tail calls
Add the 'do' statement
Implementation detail: separate out arrays and objects. They are not the same. Objects no longer need to track if they're fast arrays or not. They're not. Arrays are. Always.
Add the functional proxy idea. Log will be implemented through that.
Remove ===; it's just == now, and !=.
Remove 'continue'; now, break handles both. For a do statement, label it, and break to that label; so
var x = 0 do loop { x++ if (x < 5) break loop // goes back to loop break // exits loop }
rename instanceof to 'is'
remove undefined; all are 'null' now
remove 'delete'; to remove a field, assign it to null
remove with
Remove Object. New records have a prototype of nothing. There are no more 'type prototypes' at all.
Arrays are their own type
Remove property descriptors. Properties are always settable, unless the object as a whole is stone. Stone is an object property instead of a shape property.
Syntax stuff .. would like to invoke functions without (). This can effectively simulate a "getter". Make ? and all other characters usable for names. No reserve words, which are endlessly irritating.
This will all actually come about gradually. Add a few things at a time, fix up code that did not adhere. For a lot of this, no new functions will even need to be written; it's a matter of not calling certain functions that are no longer relevant, or calling different functions when required.
Benchmarks to implement
general speed
binarytrees coro-prime-sieve edigits fannkuch-redux fasta http-server json serialize/deserialize knucleotide lru mandelbrot merkletrees nbody nsieve pidigits regex-redux secp256k1 spectral-norm
function calling and recursion stress - test goto
naive recursive fibonacci [fib(35) or fib(40)] tak ackermann
numeric
sieve of eratosthenes [10^7 bits] spectral norm [5500 x 5500 matrix] n-body sim [50 000 - 100 000 steps] mandelbrot [1600x1200 image, max iter = 50]
memory & gc torture
binary trees [depth 18 (~500 000 nodes)] richards task scheduler fannkuch redux [n=11 or 12]
dynamic object & property access
deltablue constraint solver splay tree [256k nodes] json, wota, nota decode->encode [use 2MB example]
string / regex kernels
regex-DNA fasta word-frequency
concurrency/message passing
ping-pong [two actors exhange a small record N times, 1M messages end to end] chameneos [mating color swap game w/ randezvous]
For all, track memory and time.