Keywords · REVERSE
REVERSE
A REVERSE is a write-back block describing what happens when a value is written.
Format
The grammar of a single REVERSE line:
REVERSE ::= "REVERSE" type identifier
type ::= name [ "(" type { " " type } ")" ]
name ::= identifier { "." identifier }
identifier ::= letter { letter | digit }
REVERSE keyword is followed by the type of the value written back and an identifier naming the block.Usage
A REVERSE keyword can only live inside a
FUNCTION keyword.
Inside a FUNCTION
In a function body, a reverse pins a write-back rule to the value it names.
FUNCTION Ui.Element SubmitForm
INPUT Ui.Form.Result formData
REVERSE Ui.Form.Result submissionReverse
LET Ui.Form.Result result = Api.Client.ParseFormResult formData
SET formDataState = result
When something writes that value, the reverse runs — its forward body computes from the
incoming value and the closing SET writes the result into outer state.
Can Contain
The indented lines of a REVERSE are its body, in order: a forward body, then a
closing write-back.
Containing a LET
Zero or more LET bindings (and effect calls) make up the body, computing from the
incoming value exactly as in a forward block. They prepare the value that the closing
SET writes back.
REVERSE Maths.Integer countReverse
LET Maths.Integer next = Maths.Integer.Increment countState
Containing a CALL
An effect call on its own line, doing work in the forward body before the closing write-back.
REVERSE Text draftReverse
Analytics.Track "edited"
Containing a SET
SET is the single point where a write actually takes effect, and it must be the
final statement(s) of the block — never before the body is done, and never outside a
REVERSE. It pushes a value
into an outer STATE: it names the state to write and
the value to put there, written SET stateName = value. It carries no body of its
own and opens no further lines. Because it only
ever ends a REVERSE, the renderer lowers it to the reactive setter
Reactive.Set(state, value) (Reactive::set in Rust,
Reactive.set in Zig). Here a retry bumps a reload counter, the whole block ending
in its SET:
REVERSE Logic.Maybe incrementFlag
LET Maths.Integer currentCount = Maths.Integer.Increment refreshCountState
SET refreshCountState = currentCount
SET pushes the result into the outer state it names.Targets
The same example, rendered to each target; the closing SET becomes the reactive
setter on the last line of each block.
JavaScript
// a write-back: runs when submissionReverse is written
function submissionReverse() {
var httpResponse = Network.Web.Client.Post(url, optionalBody, headers);
var result = Api.Client.ParseFormResult(httpResponse);
Reactive.Set(formDataState, result); // SET pushes into outer state
}
TypeScript
Reactive.Reverse(submissionReverse, () => {
const httpResponse = Network.Web.Client.Post(url, optionalBody, headers);
const result = Api.Client.ParseFormResult(httpResponse);
Reactive.Set(formDataState, result); // SET pushes into outer state
});
Dart
Reactive.Reverse(submissionReverse, () {
final httpResponse = Network_Web_Client.Post(url, optionalBody, headers);
final result = Api_Client.ParseFormResult(httpResponse);
Reactive.Set(formDataState, result); // SET
});
Swift
Reactive.Reverse(submissionReverse) {
let httpResponse = Network.Web.Client.Post(url, optionalBody, headers)
let result = Api.Client.ParseFormResult(httpResponse)
Reactive.Set(formDataState, result) // SET
}
Go
Reactive.Reverse(submissionReverse, func() {
httpResponse := Network_Web_Client.Post(url, optionalBody, headers)
result := Api_Client.ParseFormResult(httpResponse)
Reactive.Set(formDataState, result) // SET
})
Rust
Reactive::reverse(submission_reverse, Box::new(move || {
let http_response = network::web::client::Post(url, optional_body, headers);
let result = api::client::ParseFormResult(http_response);
Reactive::set(form_data_state, result); // SET
}));
Zig
Reactive.reverse(submission_reverse, struct { pub fn run() void {
const http_response = network.web.client.post(url, optional_body, headers);
const result = api.client.parse_form_result(http_response);
Reactive.set(form_data_state, result); // SET
} }.run);
JSON
["S", "submissionReverse", "Ui.Form.Result", [
["=", "httpResponse", "Network.Web.Response", ["Network.Web.Client.Post", [], ["url", "optionalBody", "headers"]]],
["=", "result", "Ui.Form.Result", ["Api.Client.ParseFormResult", [], ["httpResponse"]]],
[">", "SET", [], ["formDataState", "result"]]
]]
Related
A two-way parameter is an INPUT in BINDING mode,
usually targeting a STATE — the same STATE a
reverse's closing SET writes into. Bodies are built from
LET bindings, and reversibility is explored in
Context. Back to the language.