Hello Javascript Promises!
Wierd that I’d write a “hello” post on promises after I wrote [Bye Bye Javascript Promises!][bbjsp]. This post has a two fold agenda. One is to point out that I’m not against promises per se, and the other is to introduce something new in the JS world - well, the same old new - data flow variables, which was what promises used to be called.
cspjs has an experimental branch dfvars branch that introduces a syntactically simpler way to work with promises. cspjs could interop with callbacks, but ignored APIs being written using promises. Now it can also interop with promises in the dfvars branch and I’d like some feedback from the JS community on this.
What are data flow variables - dfvars?
Mozart/Oz takes a different stance to what happens when an unbound variable is encountered when evaluating an expression. When most languages will raise an error or assume some default value silently, Oz blocks the current thread until the variable gets bound somwhere else. This is in essence a “promise”, where the variable’s value is promised to be set elsewhere.
Declaring dfvars in cspjs
In cspjs, var
declarations must have initializers. This makes it
convenient to assume that a var
declaration with no initializers for the
variable is declaring such a dfvar. Here is a silly example that waits
forever -
1 2 3 4 5 6 |
|
Binding a dfvar
The :=
assignment operator binds a dfvar to a ground value. Here is an even
sillier example -
1 2 3 4 5 6 7 |
|
We use the “uninitialized var” declaration to create a dfvar and the :=
operator to bind a dfvar to a ground value. The RHS of a :=
bind statement
can evaluate to a normal value or turn out to be a “thenable”, in which case
its outcome will be bound to the outcome of the dfvar.
dfvars within data structures
You can store dfvars within arrays and objects. No special declaration is necessary
in this case. You only need to use x[y] := expr;
kind of statements to perform the
bind, and cspjs will take care of the test. Keeping to the tradition of silly examples -
1 2 3 4 5 6 7 |
|
A more involved example
When I started this section, I started with the doxbee sequential
example. Soon, I realized that the regular await
based code is more succinct
and clearer than the promise or dfvar based code, especially given that we have
to await on dfvars explicitly. [Doxbee parallel][doxpar] is more elegant
though.
The key is that if you’re immediately going to wait on a promise returned from
an operation before doing anything else, await
based code is way more
elegant. If you’re going to make many dfvars before waiting on a subset of
them, then dfvar based code can be elegant. In either case, dfvar-based code
looks more elegant than promise based code in JS.