<commit_before># Actor Language Design

This document describes considerations for the design of a language for actor-oriented programming.

## What is actor-oriented programming?

The [Actor Model](https://en.wikipedia.org/wiki/Actor_model) describes computation by passing asynchronous messages between opaque computational elements (actors).
In response to a message that it receives, an actor can make local decisions, create more actors, send more messages, and designate how to respond to the next message received.
Since actor implementations are opaque, the "state" of an actor may only be inferred from its response to messages.

## Where are actors most useful?

### Actors in-the-large

### Actors in-the-small

## Why a new language?

## Primary language goals

## Key Questions

### How is an actor's state/behavior represented?
### What are the semantics of actor message-passing?

## Minimalism

The Actor Model is defined in terms of three primitive actions: **send**, **create**, and **become**.
A **send** action adds a pending _event_ to the configuration, consisting of a _message_ and a target actor _address_.
A **create** action adds a new actor to the configuration, with a uniquely defined _address_ and an initial _behavior_.
A **become** action, executed as part of an actor's _behavior_, designates a new _behavior_ for handling subsequent _messages_ to this actor.
Actor computation consists of taking an _event_ from the set of pending events 
and invoking the _behavior_ of the target actor to process the _message_.

### Actor Semantics

An actor _configuration_ consists of a set of pending _events_ **Q**, 
and a set of actors **A** mapping each actor's _address_ to its current _behavior_.
Note that **send** generates a unique _event_, even if it duplicates an existing target _address_ and _message_ pair.

    Action                       | Effect
    -----------------------------|------------------------------------------
    **send** _address_ _message_ | **Q** + <_address_, _message_>
    **create** _behavior_        | **A** + (_address_ -> _behavior_)
    **become** _behavior_        | **A** \| (`SELF` -> _behavior_)

The unique _address_ generated by **create** (designating the newly created actor) is made available to the currently executing actor.
The keyword `SELF` designates the address of the currently executing actor.

An actor _address_ is a unique opaque unforgable token that represents the capability to send a message to the actor.
An actor may come to know the address of another actor in three ways:

1. Provided as part of an actor's behavior (including access to `SELF`)
2. Generated when a new actor is created
3. Received as part of a message

The _behavior_ of an actor describes a set of _actions_ (which cause _effects_) taken by the actor when it receives a _message_.
The behavior has access to the contents of the message.
You can think of the behavior as being parameterized by the message.

A _message_ is an immutable data structure, which must be able to communicate (at least) an actor address.

### Send is Universal

The **send** action schedules work to be done in an actor system.
At any given time, the set of pending _events_ represents all the requested (but not completed) work.
It may be possible to describe both **create** and **become** in terms of **send**
by modeling execution of an meta-actor's behavior as a flurry of messages within a configuration of more basic machine-actors.
A meta-**create** would be accomplished by sending a _behavior_ to a machine-level _sponsor_ (ambient authority),
which would send the _address_ of the new actor as a response.
A meta-**become** would be accomplished by sending a _behavior_ to a machine-actor responsible for making the meta-actor ready to handle another message.

It may also be possible to represent all _messages_ and _behaviors_ as machine-actors.
This would lead to a universal actor representation (everything is an actor),
but raises the issue of "grounding out".
As some level, it must be possible to complete an action without generating additional events.
A meta-level message delivery could trigger a series of machine-level events,
and when there are no more machine-level events the meta-level message processing would be complete.

Ground-level machine-actors can be described as if they were meta-level actors,
in order to understand their intended behavior.
However, they may be implemented directly by the run-time machinery,
thus avoiding the generation of additional events.

#### _Message_ machine-actors

A meta-actor message is represented as a machine-level input stream.
The meta-actor receiving the message uses machine-level pattern matching 
to "parse" the message, understanding is structure and contents.

An input-stream machine-actor represents a position in the input source.
When given a _customer_, the stream responds with 
the _value_ at the current position and a machine-actor representing the _next_ position.
If the end of the input source is reached, the response is 
a distinguish actor representing the stream _end_.

#### _Behavior_ machine-actors

A meta-actor behavior is represented as a collection of machine-level primitive actions.
Primitive actions execute within a _context_.
The _context_ provides access to the machine-level _sponsor_ for creating new actors.
It also contains the results of pattern-matching the meta-_message_,
and the meta-_effects_ caused by machine-actions.

The most basic action is, of course, **send**.
A **send** takes an actor representing the _message_ and an actor representing the _target_.
From these, a meta-_event_ is added to the pending events in the _context_.
The _sponsor_ controls (and potentially limits) the resources required to deliver/process _events_.

#### Useful Equivalences

Partial functions and dictionaries/maps are both ways of defining an output value in terms of an input value.

    square(x) = \x.(x * x) = { [0 0] [1 1] [2 4] [3 9] [4 16] [5 25] ... }

Pattern-matching grammars can be used in both directions. 
Either to recognize and instance of a pattern (bind variables to parts),
or to generate a composite value from a template via variable substitution.

#### Fundamental Data Types

* Address: An opaque value representing the capability to send a message to an actor. Address equality implies actor identity
* Boolean/Bit: Either `TRUE` (1) or `FALSE` (0)
* Null: The unique value `UNDEFINED` is available when no value can be determined

#### Composite Data Types

* Dictionary/Map/Function: Given an input value, produce a corresponding output value (or `UNDEFINED`).
* List/Sequence/Stream: An ordered collection of values. May be empty.

#### Extended Data Types

* Integer: Arbitrary precision signed numbers (Sequence of Bits)
* String: Arbitrary length sequence of characters (Sequence of Integer)
* Symbol: Atomic constants (Sequence of Integer/Bits)

#### Basic Patterns

* Nothing: Matches without consuming a value
* Anything: Matches (and consumes) any single value
* Predicate: Matches (and consumes) a value if a condition holds
* Sequence: Matches a sequence of patterns in order
* Choice: Find first match in a sequence of patterns
* Elimination: Fails if pattern matches, while consuming nothing

#### Extended Patterns

* Equal: Matches a specific value (`Predicate:equal`)
* Class: Matches any of a class/type of values (`Predicate:type-of` or `Choice:set-of-values`)
* Optional: Matches 0 or 1 occurance of a pattern (`Choice:[pattern Nothing]`)
* Repeat: Matches 0 or more occurances of a pattern (`Choice:[Sequence:[pattern recurse] Nothing]`)
* Some: Matches 1 or more occurances of a pattern (`Sequence[pattern Repeat:pattern]`)

### Object/Functional Hybrid

How about if we isolate state-change to the message-dispatch machinery?
To dispatch a message:

1. Find the behavior associated with the actor address
2. Invoke the behavior with the message as a parameter
3. The behavior is a pure (no side-effects) function producing a deterministic result
4. The result describes the new actors created, new message-events, and replacement behavior
5. The message dispatch transaction completes by releasing the message-events and updating the actor behavior

The message is an immutable object.
The behavior is a deterministic pure-function.
The result is an immutable object.<commit_msg>Sketch out object/functional actor primitives<commit_after># Actor Language Design

This document describes considerations for the design of a language for actor-oriented programming.

## What is actor-oriented programming?

The [Actor Model](https://en.wikipedia.org/wiki/Actor_model) describes computation by passing asynchronous messages between opaque computational elements (actors).
In response to a message that it receives, an actor can make local decisions, create more actors, send more messages, and designate how to respond to the next message received.
Since actor implementations are opaque, the "state" of an actor may only be inferred from its response to messages.

## Where are actors most useful?

### Actors in-the-large

### Actors in-the-small

## Why a new language?

## Primary language goals

## Key Questions

### How is an actor's state/behavior represented?
### What are the semantics of actor message-passing?

## Minimalism

The Actor Model is defined in terms of three primitive actions: **send**, **create**, and **become**.
A **send** action adds a pending _event_ to the configuration, consisting of a _message_ and a target actor _address_.
A **create** action adds a new actor to the configuration, with a uniquely defined _address_ and an initial _behavior_.
A **become** action, executed as part of an actor's _behavior_, designates a new _behavior_ for handling subsequent _messages_ to this actor.
Actor computation consists of taking an _event_ from the set of pending events 
and invoking the _behavior_ of the target actor to process the _message_.

### Actor Semantics

An actor _configuration_ consists of a set of pending _events_ **Q**, 
and a set of actors **A** mapping each actor's _address_ to its current _behavior_.
Note that **send** generates a unique _event_, even if it duplicates an existing target _address_ and _message_ pair.

    Action                       | Effect
    -----------------------------|------------------------------------------
    **send** _address_ _message_ | **Q** + <_address_, _message_>
    **create** _behavior_        | **A** + (_address_ -> _behavior_)
    **become** _behavior_        | **A** \| (`SELF` -> _behavior_)

The unique _address_ generated by **create** (designating the newly created actor) is made available to the currently executing actor.
The keyword `SELF` designates the address of the currently executing actor.

An actor _address_ is a unique opaque unforgable token that represents the capability to send a message to the actor.
An actor may come to know the address of another actor in three ways:

1. Provided as part of an actor's behavior (including access to `SELF`)
2. Generated when a new actor is created
3. Received as part of a message

The _behavior_ of an actor describes a set of _actions_ (which cause _effects_) taken by the actor when it receives a _message_.
The behavior has access to the contents of the message.
You can think of the behavior as being parameterized by the message.

A _message_ is an immutable data structure, which must be able to communicate (at least) an actor address.

### Send is Universal

The **send** action schedules work to be done in an actor system.
At any given time, the set of pending _events_ represents all the requested (but not completed) work.
It may be possible to describe both **create** and **become** in terms of **send**
by modeling execution of an meta-actor's behavior as a flurry of messages within a configuration of more basic machine-actors.
A meta-**create** would be accomplished by sending a _behavior_ to a machine-level _sponsor_ (ambient authority),
which would send the _address_ of the new actor as a response.
A meta-**become** would be accomplished by sending a _behavior_ to a machine-actor responsible for making the meta-actor ready to handle another message.

It may also be possible to represent all _messages_ and _behaviors_ as machine-actors.
This would lead to a universal actor representation (everything is an actor),
but raises the issue of "grounding out".
As some level, it must be possible to complete an action without generating additional events.
A meta-level message delivery could trigger a series of machine-level events,
and when there are no more machine-level events the meta-level message processing would be complete.

Ground-level machine-actors can be described as if they were meta-level actors,
in order to understand their intended behavior.
However, they may be implemented directly by the run-time machinery,
thus avoiding the generation of additional events.

#### _Message_ machine-actors

A meta-actor message is represented as a machine-level input stream.
The meta-actor receiving the message uses machine-level pattern matching 
to "parse" the message, understanding is structure and contents.

An input-stream machine-actor represents a position in the input source.
When given a _customer_, the stream responds with 
the _value_ at the current position and a machine-actor representing the _next_ position.
If the end of the input source is reached, the response is 
a distinguish actor representing the stream _end_.

#### _Behavior_ machine-actors

A meta-actor behavior is represented as a collection of machine-level primitive actions.
Primitive actions execute within a _context_.
The _context_ provides access to the machine-level _sponsor_ for creating new actors.
It also contains the results of pattern-matching the meta-_message_,
and the meta-_effects_ caused by machine-actions.

The most basic action is, of course, **send**.
A **send** takes an actor representing the _message_ and an actor representing the _target_.
From these, a meta-_event_ is added to the pending events in the _context_.
The _sponsor_ controls (and potentially limits) the resources required to deliver/process _events_.

#### Useful Equivalences

Partial functions and dictionaries/maps are both ways of defining an output value in terms of an input value.

    square(x) = \x.(x * x) = { [0 0] [1 1] [2 4] [3 9] [4 16] [5 25] ... }

Pattern-matching grammars can be used in both directions. 
Either to recognize and instance of a pattern (bind variables to parts),
or to generate a composite value from a template via variable substitution.

#### Fundamental Data Types

* Address: An opaque value representing the capability to send a message to an actor. Address equality implies actor identity
* Boolean/Bit: Either `TRUE` (1) or `FALSE` (0)
* Null: The unique value `UNDEFINED` is available when no value can be determined

#### Composite Data Types

* Dictionary/Map/Function: Given an input value, produce a corresponding output value (or `UNDEFINED`).
* List/Sequence/Stream: An ordered collection of values. May be empty.

#### Extended Data Types

* Integer: Arbitrary precision signed numbers (Sequence of Bits)
* String: Arbitrary length sequence of characters (Sequence of Integer)
* Symbol: Atomic constants (Sequence of Integer/Bits)

#### Basic Patterns

* Nothing: Matches without consuming a value
* Anything: Matches (and consumes) any single value
* Predicate: Matches (and consumes) a value if a condition holds
* Sequence: Matches a sequence of patterns in order
* Choice: Find first match in a sequence of patterns
* Elimination: Fails if pattern matches, while consuming nothing

#### Extended Patterns

* Equal: Matches a specific value (`Predicate:equal`)
* Class: Matches any of a class/type of values (`Predicate:type-of` or `Choice:set-of-values`)
* Optional: Matches 0 or 1 occurance of a pattern (`Choice:[pattern Nothing]`)
* Repeat: Matches 0 or more occurances of a pattern (`Choice:[Sequence:[pattern recurse] Nothing]`)
* Some: Matches 1 or more occurances of a pattern (`Sequence[pattern Repeat:pattern]`)

### Object/Functional Hybrid

How about if we isolate state-change to the message-dispatch machinery?
To dispatch a message:

1. Find the behavior associated with the actor address
2. Invoke the behavior with the message as a parameter
3. The behavior is a pure (no side-effects) function producing a deterministic result
4. The result describes the new actors created, new message-events, and replacement behavior
5. The message dispatch transaction completes by releasing the message-events and updating the actor behavior

The message is an immutable object.
The behavior is a deterministic pure-function.
The result is an immutable object.

#### Immutable Objects (ala JSON)

Imagine that all message-passing, method invocation, and function calling 
involved JSON serialization by the caller
and deserialization by the receiver
(as if a network boundry was crossed).
In effect,
this would force all interfaces
to work with immutable pass-by-value parameters.
For efficiency,
values may share information by reference
within a memory domain,
but this optimization is not observable,
since all values are immutable.

#### Primitive Behaviors

An actor behavior is a function that takes a message and returns a result object.
The result has the following fields:

  * `actors`: _List_ The addresses of newly-created actors.
  * `messages`: _List_ The message-events (target-actor and message) for each `send`.
  * `behavior`: _Function_ The function used to process subsequent messages.

If the `behavior` is `undefined`, the current behavior will be used to process the next message.

The following primitives are provided to help construct the _result_ object:

  * `create`: _Function_ `function (behavior) {}`
    Returns _address_ of a new actor with the specified initial _behavior_.
  * `send`: _Function_ `function (address, message) {}`
    Returns a message-event that will deliver the _message_ to the target actor _address_.
{'fraction_non_alphanumeric': 0.0702627939142462, 'fraction_numerical': 0.00309820193637621, 'mean_word_length': 4.3942106833780965, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1729250', 'n_tokens_mistral': 4592, 'n_tokens_neox': 4351, 'n_words': 2545}