Dodo is a programming language based on prototypes, continuations and capabilities.
Of course Javascript is prototype-based, but Javascript is a mess. Besides I feel that Javascript doesn't take the prototype idea far enough. On the opposite, there is a popular variant called Typescript that denatures the prototype-oriented nature of Javascript. In Dodo classes and objects are built on top of prototypes, they don't displace them.
Scheme is considered the pioneer of continuation-based programming but it uses the wrong primitives for them. There has not been successful continuation-based languages after that. All we get is yield, async and await.
Capabilities are something most language designers wish for, but where are they used? I would say Monte is the closest to my ideal language since it has capabilities baked in. You probably never heard about it.
You may expect a one-liner "Hello, World!" program to demonstrate the Dodo syntax. However that doesn't exist. To get code to run and produce an output you will need to pull some capabilities in your program (see what I did here?). Then you need to tell the compiler the instructions to run. It may all sound unworthy of your time but I believe in being explicit about what is being used.
helloworld.doo:
use modules use console def name = "World" def Run() { *Stdout out console!out.Puts("Hello, "(name)"!") }
In this example, Stdout is a capability from the console service.
Next let's look at prototypes.
def pair = new struct { int first, second }
In this example struct is used as prototype with two added attributes (extension).
def a_pair = new pair(first: 11, second: 7)
The definition of a_pair sets values for the two attributes of its prototype pair (instantiation).
Types are similar to prototypes.
def Figure: double x, y. def Circle = new Figure { def radius = 1.0 make withRadius(double x, y, r) { *self.x = x *self.y = y *self.radius = r } }
A type has a default instance (T.instance) and can have constructors (make) and methods (method).
What about continuations? Actually, continuations are a little hidden. You may not notice them at all.
def half(int n) -> return(int) { return(n / 2) }
In this example return is a continuation name. You could replace it with anything you like however I recommend sticking to "return" and "throw" most of the time.