Hylic - Messaging

Messaging can be performed in many different ways in Hylic and is optionally restrictive.

All objects can be called synchronously, asynchronously, and via a Promise-based interface.

Synchronous Message Passing

When we call an object synchronously, we wait for the response of the object before continuing.

anObject.doThing()

Asynchronous Message Passing

anObject ! doThing

Passes a message and ignores the result.

Promises

myProm : @u8 := anObject ! doThing

Promises can be resolved using the resolution operator:

@ promise-example
    # do something with the returned value, promise-example
    
@ let x : [@] = [more-promises1, more-promises2, more-promises3]
    # Resolve several promises

In this case, each promise variable is shadowed by the resolved version.

Vats

Vats form local object-graphs (think: thread, think: process) - they execute parallel to eachother. Every program starts in its own vat. All objects created within that vat can be accessed via a regular function call, e.g. myObject.doThis(). The function will then run synchronously. To access objects outside of one's own vat, messaging must be used, e.g. myObject ! doThis() - which executes asynchronously. Functions of objects within a vat can also be called asynchronously - but calls will not run parallely, only concurrently. When a vat gets a message, it goes into a queue. Each message is processed one by one. One can think of a vat like a thread.

Use the following syntax to construct an object in a new vat:

$anObject(1)

Constructing a new vat always returns the type @ far object-type, e.g.:

myProm : @far anObject := $anObject()

@ myProm
    # The promise is resolved to a far anObject, we can send messages now
    myProm ! doThing

Alternatively, messages can be sent directly to the promise before resolution. The messages will be preloaded in the message queue during vat formation.

myProm : @far anObject := $anObject()

myProm ! doThing

Message Processing

One of the key features of Pleroma is the ability to mix async and synchronous code. It is important to understand this feature, as it is enabled by default: all code must yield or the vat will never receive messages.

To implement an infinite loop within a vat, one must use self-messaging:

ε HelloWorld
	δ loop() -> ()
        do-something()
        ! loop

Each entity also contains a variable self, which returns a reference to the current entity self ! loop.

Pure Objects

Pure objects contain only pure functions and no data members. They cannot be instantiated and are accessed via the Entity name.

Ɵ HelloWorld
    λ add-world(hello-string: str)
        ↵ hello-string + ", world!"

And to call it from another entity, just use HelloWorld.add-world("Hello"). No need to instantiate it.