-
Notifications
You must be signed in to change notification settings - Fork 16
Abstract Syntax
This document captures a summary of consensus and remaining contention for the OCapN data model and abstract syntax, excluding the concern of concrete representation of these on the wire, but including representation and semantics in implementation languages.
Agoric currently requires all valid JSON documents to be passable over OCapN, so type titles suffixed "(JSON)" participate in this language subset. This itself remains a contended position.
-
Guile:
*unspecified* -
JavaScript:
undefined -
Python:
None
In order for the JSON subset of JavaScript to be passable, Undefined must be
distinguishable from Null.
For this purpose and this purpose alone, we preserve this second empty (or "unit") type.
Consequently, a JavaScript program can parse a JSON file, bounce it off a
remote Guile program, and write equivalent JSON back with the host
implementation of JSON.parse and JSON.stringify.
We presume that a JSON codec implemented in Guile can be implemented to parse
and format the same subset of the OCapN data model.
-
Guile: tentatively
json-null(imported) -
JavaScript and JSON:
null -
Python:
Null(imported)
@erights inisists on the JSON null https://github.com/ocapn/ocapn/issues/5#issuecomment-826029525
-
Guile:
#f,#t -
JavaScript and JSON:
false,true -
Python:
False,True
OCapN supports arbitrary precision signed integers.
-
Guile:
-1,0,1 -
JavaScript:
-1n,0n,1n -
Python:
-1,0,1
We achieved consensus on the name Integer at the November 14, 2023 meeting.
OCapN round trips all double precision floating point numbers as expressible with IEEE 754, except that OCapN considers all IEEE 754 NaNs as equivalent, i.e., as jointly representing a single abstract NaN value. Thus, any concrete NaN representation may validly round trip even if it results in a different concrete representation. However, we encourage concrete representations to use a canonical NaN representation.
Concretely, the canonical NaN is
0x7ff8_0000_0000_0000, though this is not a concern of the abstract syntax and data model.
OCapN preserves the distinction between +0 and -0.
| Language | Negative | Positive |
|---|---|---|
| Guile | -0.0 |
0.0 |
| JavaScript | -0 |
0 |
| Python | -0.0 |
0.0 |
OCapN round trips positive and negative infinity.
| Language | Negative | Positive |
|---|---|---|
| Guile | -inf.0 |
+inf.0 |
| JavaScript | -Infinity |
Infinity |
| Python | float('-inf') |
float('inf') |
OCapN collapses all versions of NaN to a single abstract NaN.
-
JavaScript:
NaN -
Guile:
+nan.0 -
Python:
float('nan')
OCapN provides no support for other floating point precisions.
All real and finite double precision floating point numbers participate in the
JSON subset of OCapN.
We expect OCapN-compatible JSON codecs, including the JavaScript JSON codec,
to round-trip all numbers except NaNs, infinities, and negative zero, but all
other numbers expressible with an IEEE 754 double-precision float to survive a
round trip without loss of precision.
We also do not expect integers expressed with higher precision in JSON to
survive a round-trip through an OCapN-compatible JSON codec.
Consensus on preserving -0:
- As of May 16, @erights insisted that -0 round trip to 0 https://github.com/ocapn/ocapn/issues/5#issuecomment-1550020450
- On May 23, @zenhack proposed preserving -0 https://github.com/ocapn/ocapn/issues/5#issuecomment-1560116857
- We converged out of band and Agoric has committed to preserving -0 https://github.com/endojs/endo/issues/1602
Tracking: https://github.com/ocapn/ocapn/issues/58
OCapN supports strings of unicode code points.
-
Guile:
"" -
JavaScript:
'' -
Python:
''
There remains contention whether OCapN can round trip unpaired surrogates. If OCapN's data model must be a strict superset of JSON, OCapN must be able to round trip unpaired surrogates, which are not expressible in UTF-8. https://github.com/ocapn/ocapn/issues/5#issuecomment-826029525 (per @erights).
Strings participate in the JSON superset.
Contended positions:
- Agoric and Spritely do not agree upon whether OCapn can round-trip unpaired surrogates.
-
unicode code points, as expressible with UTF-8:
- @kriskowal https://github.com/ocapn/ocapn/issues/5#issuecomment-1550370096
- +1 from @dpwiz
- unicode code units, as expressible with UTF-16, preserving unpaired surrogates as expressible in JSON:
- indifference:
- No other recorded positions, but on October 10, Spritely folks expressed they thought there was consensus toward UTF-8.
Tracking: https://github.com/ocapn/ocapn/issues/47
Jan 2024 meeting notes record that we agreed that strings can only be well-formed Unicode, i.e., cannot contain unpaired surrogates. For JavaScript, if a string does not pass the isWellFormed predicate, then it is not a Passable string. Agoric has yet to implement this validation, but will.
OCapN supports arbitrary length byte strings.
-
Guile:
#vu8() -
JavaScript: To be determined, but likely an object with
Symbol.for('passStyle')set tobytesand an API for moving the bytes into a mutable buffer or composing with other immutable byte strings. -
Python:
b''
Tracking: https://github.com/ocapn/ocapn/issues/48 Contention: TBD (byte, octet) x (vector, array, string)
At the November 14, 2023 meeting, we agreed to settle on the prefix “byte” and agreed to decide at the next meeting based on a reactji poll.
Jan 2024 meeting notes record that we agreed on ByteArray because it was the winner of the poll, and we had already agreed to resolve this specific issue by poll among these three choices.
-
Guile: symbol
'name -
JavaScript:
or
{ [Symbol.for('passStyle')]: 'selector', selector: 'name' }`
makeSelector('name')wheremakeSelectoris imported fromocapn. -
Python:
Selector('name')whereSelectoris imported fromocapn.
Tracking: https://github.com/ocapn/ocapn/issues/46
OCapN supports arbitrary length lists of other passable values.
-
Guile:
'() -
JavaScript and JSON:
[] -
Python:
()(We have not discussed whether to use tuple or list. Tuple is less mutable, though enforcing immutability in Python is not likely to be a goal the way it is in hardened JavaScript.)
Sequences participate in the JSON superset.
We achieved consensus to name the type “List” at the November 14, 2023 meeting.
A struct is a dictionary with unique, unordered string keys and passable values.
For the purposes of surviving a round trip, the order of appearance of entries in the struct must not be important for determining equivalence.
Thus, a Struct representation concretely using one key order may validly round-trip into a Struct representation using another key order. However, we encourage concrete representations to use some canonical key order, though this is not a concern of the abstract syntax and data model.
-
Guile:
make-tbd-hasha hash of undecided type -
JavaScript:
{} -
Python:
{}
There are no contended positions.
Non-contended positions held:
- @erights prefers to avoid entraining the weirdness of JavaScript key order in OCapN https://github.com/ocapn/ocapn/issues/5#issuecomment-1550020450
OCapN supports user-extensible tagged values, consisting of a String tagName and a Passable payload.
-
Guile: currently a Guile record labeled
'(syrec ...)(imported) -
JavaScript: an object with the key
Symbol.for('passStyle')and valuetagged, with a string tagName and a single"payload"field carrying the tagged value.{ [Symbol.for('passStyle')]: 'tagged', [Symbol.toStringTag]: tagName, payload }
- Python:
Consensus positions:
- OCapN tagged data will have a single value (not be variadic) November 14, 2023
Contended positions:
- Spritely seems to use symbols as tagNames rather than strings.
Tracking:
- What are tagged values for? https://github.com/ocapn/ocapn/issues/52
A Remotable can be
- An object that can receive remote messages
- A remote presence of such an object, that forwards messages to that object
This taxonomy does not distinguish between these two forms of Remotable, since this taxonomy is intended to be pass-invariant.
- Guile:
-
JavaScript: A far object or a remote presence of that far object.
{ __proto__: { [Symbol.for('passStyle')]: 'remotable', [Symbol.toStringTag]: allegedInterfaceName, }, ...methods }
- Python:
Remotables and Promises are both capabilities for delivering messages to possibly remote objects. Unlike Promises, Remotables have a fresh, stable unforgeable, pass-invariant, comparable identity.
Tracking: https://github.com/ocapn/ocapn/issues/49
- Guile:
- JavaScript: a JavaScript promise
- Python:
Contention:
- fulfills to a single value
- fulfills to multiple values
- hand-off records appear in-band in Goblins, whereas Agoric uses promises
Tracking https://github.com/ocapn/ocapn/issues/55
OCapN can transit errors. We have not yet converged on any particular details about the modeling of errors. The purpose of errors is typically to indicate that some requested operation failed. The purpose of the contents of errors is to preserve and convey diagnostic information, mostly to help debug problems, such as the root cause of a surprising failure. This is a best-efforts obligation, for which we have not yet decided either what contents are required, nor what is allowed, nor what must be preserved as errors are passed from one site to another. Until these details are decided, the only hard requirement is that an error round trip to an error. We avoid any interpretation for now as to whether it is the "same" error.
- Guile:
- JavaScript: a JavaScript Error object
- Python:
This concludes the taxonomy and abstract syntax of the core data model. From here down is the abstract syntax of capability-based message passing, which is built on top of this core data model.
Contended positions:
- @zenhack one argument, one return https://github.com/ocapn/ocapn/issues/16
- @kriskowal normalize method name, effectively a list of ASCII lowercase alphanumeric terms starting with an alphabetic character that get reified and recognized in each implementation language's rustic aesthetic, be it strings or symbols in whatever case convention most closely resembles the prevailing trend.
Tracking: https://github.com/ocapn/ocapn/issues/54 Tracking: https://github.com/ocapn/ocapn/issues/65
Tracking: https://github.com/ocapn/ocapn/issues/62