Should the first thing we teach students be
prompt? That's terrible - prompt
is unlike anything else in Javascript. It blocks the thread
and pops up a window. You cannot customize it to make, say,
a "nubmers only" input, and when it pops up, it prevents
students from interacting with the page, invariably covering
up messages like "bigger" or "smaller" that the student
has printed on the screen. Try using
it, pretending to be a student. It's OK, but not great.

But if we create a custom readnum function with
a better UI for students to use, we cannot block the UI thread,
so to wait for the user to finish entering an answer,
readnum must use a callback argument. With a
callback, Guess My Number would look like this:

This program is obviously much harder to understand and write.
Using a callback means the programmer needs to plan and
create two or three functions that call each other. It is totally
out of reach of a first-time programmer.

And await solves this.

Using Iced Coffeescript

The Coffeescript world currently has an implementation of
await that addresses this problem, and it is close,
but not quite simple enough for classroom use. The implementation
was done by Max Krohn in his fork Iced Coffeescript (ICS), and
it lets the program look like this:

The ICS compiler automatically pivots Program 3 so that it
turns in to Program 2. This transformation is called the
"Continuation Passing Style" transformation; it is a classical
functional programming concept.

Unfortunately, the ICS syntax confuses beginners. In our attempts
to teach with it, we have found that beginners do not understand that
defer g creates a continuation function that is being
passed. For example, they cannot figure out "why they need a comma"
before the word defer if it's a second argument.

A Simpler Syntax for Beginners

Teachers have suggested that a better syntax would be to eliminate
defer and use this:

Interestingly, this syntax is exactly what is being proposed for
the next version of Javascript in the ECMAScript 7 committee. In ES7,
await will be an operator that causes flow to wait for
a promise to finish.

In order to use an ES7 await, you cannot use
a regular function that hakes a callback function as an argument.
Instead, you need to use a standard callback convention: you need
to return an ES6 Promise. Promises are the future of asynchronous code;
both ES6 and ES7 encourage everybody to use the same pattern.

Another interesting fact is that the proposed syntax can coeexist
with existing Iced Coffeescript syntax: if an await block
does not contain a defer expression, then we can safely
assume that it is an ES7-Promise-style await. A very rough prototype
showing a working syntax that is unabmiguous for Coffeescript's LALR(1)
parser has been
done
in a branch of ICS here. It limits Promise-style awaits to
be used in top-level assigments.

The Project

This project is to implement the ES7-style await syntax in ICS
for use by begnning students. The branch above has a rough start
at an implementation. Several things are needed beyond
the code above:

Learn the ICS codebase and improve the prototype fork:
wrap the use of promises to provide understandable run-time
errors when a Promise-style await is misused (for example if
a student uses await on a non-asynchronous function).

Add async function support.
When a promise-await is used in a function, the function should be
made to be an ES7-style async function, returning a
Promise instead of an immediate result. This is analogous
to the ICS autocb feature, and could be implemented as an
adaptation of that existing code. You might decide to do this
transformation automatically, or alternately introduce new operators
for async functions, for example ==> or -->.

Add support for async exceptions.
When an async function is generated, it should catch and propagate
exceptions by resolving the returned promise as an error.

Productionize the implementation. Tests are needed;
an interface to the parser is needed that doesn't mutilate the
parse tree during parsing. (The prototype messes up the parse tree
during parsing, and it should done in a separate phase.) The
diff to mainline ICS should be minimized, so the patch can be
maintained.

Finally, if all goes well, we would
work with Max Krohn to merge the new syntax with mainline ICS.