123
Principles of Programming Languages Asynchronous Programming 1/123

Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

  • Upload
    others

  • View
    12

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Principles of Programming LanguagesAsynchronous Programming

1/123

Page 2: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Function Invocation - Call Stack

When a function f calls a function g, g needs toknow where to return to (inside f) after it is

done. This information is usually managed witha stack, the call stack. Let’s look at an example:

2/123

Page 3: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Function Invocation - Call Stack

function h(z) {// Print stack traceconsole.log(new Error().stack); // (A)

}function g(y) {h(y + 1); // (B)

}function f(x) {g(x + 1); // (C)

}f(3); // (D)

3/123

Page 4: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Function Invocation - Call Stack

Initially, when the program is started, the callstack is empty.

4/123

Page 5: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Function Invocation - Call Stack

After the function call f(3) in line D, the stackhas one entry:

Location in global scope

5/123

Page 6: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Function Invocation - Call Stack

After the function call g(x + 1) in line C, thestack has two entries:

Location in fLocation in global scope

6/123

Page 7: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Function Invocation - Call Stack

After the function call h(y + 1) in line B, thestack has three entries:

Location in gLocation in f

Location in global scope

7/123

Page 8: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Function Invocation - Call Stack

The stack trace printed in line A shows youwhat the call stack looks like:

Errorat h (...:3:15)at g (...:6:3)at f (...:9:3)

8/123

Page 9: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Function Invocation - Call Stack

Next, each of the functions terminates andeach time the top entry is removed from thestack. After function f is done, we are back in

global scope and the call stack is empty.

9/123

Page 10: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Function Invocation - Call Stack

The mechanism of a call stack to managefunction calls and their return is present in all

languages.

10/123

Page 11: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Function Invocation - Call Stack

The call stack is managed implicitly at runtime,and is usually not exposed to the programmer.

11/123

Page 12: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Function Invocation - Call Stack

In JavaScript, as demonstrated above, theError() object provides access to the currentstate of the call stack - so that we can inspect it(this is mostly useful when debugging errors atruntime). A similar facility exists in Java with

the methodThread.currentThread().getStackTrace().

12/123

Page 13: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Interpreters and Control Flow: Asynchronous Programming andContinuation Passing Style

In the interpreters we have designed in Chapter2, we did not explicitly model the call stack. The

reason is that we relied on the call stackmechanism of the meta-language to providethe proper control of function calls and the

return to their calling location.

13/123

Page 14: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Interpreters and Control Flow: Asynchronous Programming andContinuation Passing Style

In this chapter, we investigate the mechanismsthrough which programming languages providecontrol flow, and variants of control flow acrossdifferent programming paradigms. In particular,we present practical issues in AsynchronousProgramming, and techniques allowing propermanagement of asynchronous tasks: callbacks,

promises, and co-routines.

14/123

Page 15: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Interpreters and Control Flow: Asynchronous Programming andContinuation Passing Style

We review these topics in TypeScript - wherethey practically fill an important role both inthe domains of client user interface (to deal

with User Interface events in a reactive manner)and of backend servers (to deal with protocol

implementation which are IO-bound in aresource efficient manner).

15/123

Page 16: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Interpreters and Control Flow: Asynchronous Programming andContinuation Passing Style

We then introduce a technique calledcontinuation passing style (CPS), investigate its

properties and relate it to the way ourinterpreters model control flow, recursion and

iteration.

16/123

Page 17: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Interpreters and Control Flow: Asynchronous Programming andContinuation Passing Style

We switch back to Scheme and to ourInterpreter models and demonstrate a

systematic transformation from recursive toCPS and introduce techniques which elucidatethe way asynchronous and lazy programming

techniques are designed.

17/123

Page 18: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops

JavaScript as a programming language is usedin two contexts:

• Inside Web browsers to implement userinterface client code

• Inside Node processes on the backend toperform protocol handling code - usually,exposing access to resources as a REST API.

18/123

Page 19: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops

In both of these application domains, it isuseful to think of the task of the JavaScriptinterpreter as processing an event loop.

19/123

Page 20: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops

The following 25 minute presentation: PhilipRoberts: What the heck is the event loop

anyway? | JSConf EU 2014 provides a usefulexplanation of what is the event loop in the

context of Web browsers.

The companion tool to this presentationvisualizes the mechanism of the event loop:

http://latentflip.com/loupe/.

20/123

Page 21: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in the Browser

Consider first a browser context. The browserevent loop executes browser-related tasks that

are fed into the browser task queue.

21/123

Page 22: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in the Browser

Typical browser tasks are generated when anHTML page is loaded into a browser tab, and

they include:

• Parsing HTML• Executing JavaScript code in script elements• Reacting to user input (mouse clicks, keypresses, etc.)

• Processing the result of asynchronousnetwork requests (calls to HTTP server)

22/123

Page 23: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in the Browser

The last 3 are tasks that run JavaScript code, inthe JavaScript interpreter embedded in the

browser. These tasks terminate when the codeterminates. Then the next task from the queue

can be executed.

23/123

Page 24: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in the Browser

For example, browsers offer a timer facility:setTimeout() creates a timer, waits until itfires and then adds a task to the queue. It has

the signature:

setTimeout(callback, ms)

24/123

Page 25: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in the Browser

After ms milliseconds, callback is added tothe task queue. It is important to understandthat ms only specifies when the callback isadded, not when it actually is executed. Thatmay happen much later, especially if the event

loop is heavily loaded.

25/123

Page 26: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in the Browser

Practically, the setTimeout primitive is a wayto submit a task to the event loop for later

execution.

26/123

Page 27: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in the Browser

setTimeout(() => console.log("Later..."), 1000);console.log("Immediately");

/*Immediately// after ~1 secondLater...

*/

27/123

Page 28: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in the Browser

In the setTimeout example, the firstparameter is a function passed as an argument(taking advantage of the support for closures in

the JavaScript language). The task that isposted to the event queue is called a callback(because it is called back by the event loopwhen it can instead of being called by the

programmer directly).

28/123

Page 29: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in the Browser

Note how the task is represented: it is aprocedure of no parameters. What we submitto the task queue is a closure. The idiom:

() => { ... } indicates we “package” codeto be executed later. When and who executes itlater can be decided by the programmer or by

the runtime environment.

29/123

Page 30: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in the Browser

Another typical example of callbacks in thebrowser context is to associate callbacks to

User Interface widgets. A typical example wouldbe:

$("#btn_1").click(() => alert("Btn 1 Clicked"));

The anonymous function passed as anargument to the click() method defines a

callback which is invoked by the Browser eventloop whenever the button is clicked.

30/123

Page 31: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in Node

In the Node.js context, the event loop is drivenby events related to asynchronous I/O calls. Forexample, when invoking the file system, to opena file, the time taken by the operating system

(OS) system call is extremely large compared tothe time it takes to execute a function call.

31/123

Page 32: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in Node

Instead of making the interpreter block andwait for this system call to complete, the Nodeinterpreter submits a task to the event loop,which consists of invoking the callback of the

system call when it has completed.

32/123

Page 33: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in Node

This strategy requires the programmer tochange fundamentally the way I/O calls areorganized. All the primitive calls to the FileSystem (fs) module take a function as an

argument - which is called the callback whichis invoked when the slow FS operation has

completed.

33/123

Page 34: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in Node

Compare the synchronous and asynchronousversions of a file system call:

34/123

Page 35: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in Node

// Synchronous (blocking) call to readFileSync// The return value of the readFileSync procedure// can be passed directly to the JSON.parse function.const readJSONSync = (filename) => {return JSON.parse(fs.readFileSync(filename, 'utf8'));

}

const writeJSONSync = (filename, map) => {return fs.writeFileSync(filename,

JSON.stringify(map),'utf8');

}

writeJSONSync("test", {id:1, text:'hello'});console.log(readJSONSync("test"));

35/123

Page 36: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in Node

// Asynchronous version using callbacksconst fs = require('fs');

const readJSON = (filename, callback) => {fs.readFile(filename, 'utf8', (err, res) => {

if (err) callback(err, undefined);else callback(undefined, JSON.parse(res));

});}

const writeJSON = (filename, map) => {fs.writeFile(filename, JSON.stringify(map), (err) => {if (err) console.error(err);else console.log("The file was saved: ", filename);

});console.log("This is invoked before the callback is invoked.");

}

writeJSON("test.async", {id:1, test:'async'});readJSON("test.async", (err, res) => { console.log(res); }); 36/123

Page 37: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in Node

In the example above, the fs.writeFileNode method takes 3 arguments:

• The name of the file to create• The string to write into the file• The callback to invoke when thewriteFile operation has completed.

37/123

Page 38: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in Node

This pattern takes advantage of the fact thatJavaScript allows passing functions as

arguments to other functions: the callback is anargument passed to the file system primitive.

38/123

Page 39: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in Node

Programming with callbacks is not easy. Wecannot make the usual time-sequencing

assumptions we make in sequential code. Inthe example above, we know that the

expression immediately after the call tofs.writeFile() is executed before the

callback is invoked. This guarantee is part ofthe semantics of the Node interpreter.

39/123

Page 40: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in Node

But we cannot make any assumption as towhen the callback will be executed. It can take

a very long time. The problem for theprogrammer is to decide where and how to

write code which depends on the completion ofthe file system operation. Answering this

question will be the main topic of this chapter.

40/123

Page 41: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Event Loops in Node

Thinking of the JavaScript engine as a reactiveevent loop instead of an active process whichinvokes procedures is an important change ofperspective - which is related to the designpattern of inversion of control and whichdefines the event-driven programming

paradigm.

41/123

Page 42: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Callbacks and the Call Stack

In asynchronous programming, callbacks arenot invoked in the same call stack as the

procedure that creates the callback. Instead,the function which generates the task (the

asynchronous call) executes, and when it ends,it creates a task (a closure) which is added to

the task queue.

42/123

Page 43: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Callbacks and the Call Stack

When the event loop determines that thecallback is ready to be called, the runtimeenvironment invokes the task with the

appropriate arguments. The signature of thecallback is determined by the asynchronous

function.

43/123

Page 44: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Callbacks and the Call Stack

For example, in the example above, the callbackfor the readFile procedure is a function with2 parameters (err, data) which representeither an error object or the data that was readfrom the file. These arguments are passed to

the callback when the event is signaled.

44/123

Page 45: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Callbacks and the Call Stack

The callback is a closure which is created in thecontext of the asynchronous function. Hence,according to the operational semantics of the

language, we know it has access to theenvironment in which it was created (not to theenvironment which is current when the closure

is invoked). See for example how theenvironment of the callback is used:

45/123

Page 46: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Callbacks and the Call Stack

const readJSONTime = (filename, callback) => {const invoked = new Date(); // Timestamp when the read is invoked.fs.readFile(filename, "utf8", (err, res) => {if (err) {

callback(err, undefined);} else {

// This accesses a variable from the closure env.console.log("Invoked at: ", invoked);console.log("Callback at: ", new Date());callback(undefined, JSON.parse(res));

}});

};

readJSONTime("test.async", (err, res) => console.log(res));/*

Invoked at: 2020-05-23T18:30:37.540ZCallback at: 2020-05-23T18:30:37.548Z{ id: 1, test: 'async' }

*/ 46/123

Page 47: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Callbacks and the Call Stack

Even if the environment is available, thecallback is evaluated in a different controlcontext - that is, in a different call stack.

47/123

Page 48: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Composing Asynchronous Functions

Composing synchronous functions is easy:given a function f(x:Tx):Tf and a functiong(y:Ty):Tx - we can compose the calls bysimply passing the return value of g as a

parameter to f: f(g(y)). As long as the typesare compatible, this composition works (the

return type of g must be the parameter type off).

48/123

Page 49: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Composing Asynchronous Functions

Composing asynchronous functions is morechallenging: we must write a specific callback

each time we compose two functions:

g(y, (gRes) => f(gRes, callback))

49/123

Page 50: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Composing Asynchronous Functions

If we want to compose three functions - thecallbacks must be nested accordingly - instead

of f(g(h(x))) we must write:

h(x, (hRes) => {g(hRes, (gRes) => {

f(gRes, callback);});

});

50/123

Page 51: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Composing Asynchronous Functions

Note how the order of the occurrences haschanged: we read the program in the order inwhich the functions are invoked (first invoked

h, then invoke g, then invoke f).

51/123

Page 52: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

The Type of Asynchronous Functions

When we think of composing synchronousfunctions, we check their type - that is, we

verify that the type returned by g matches thetype expected by f in order to enable the

composition f(g(x)).

52/123

Page 53: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

The Type of Asynchronous Functions

Asynchronous functions do not return anyvalue - that is, they are of return type void.Instead, they post a future task which willreceive a parameter of a certain type in the

future.

53/123

Page 54: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

The Type of Asynchronous Functions

That is, if a synchronous function has typef(x: Tx): Tf - the correspondingasynchronous function will have type

asyncF(x: Tx,callback: (Tf -> Tc)): void

54/123

Page 55: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Error Handling with Asynchronous Procedures (Success / FailCallbacks)

In many cases, asynchronous functions can fail- this is the case for most I/O calls (file system,networking calls) which are most likely to be

used in an asynchronous manner.

55/123

Page 56: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Error Handling with Asynchronous Procedures (Success / FailCallbacks)

To process the case of errors - the callbackpassed to the async function must be preparedto deal with either a success outcome, or withan error outcome. Conceptually - this meansthe async function has 2 callbacks: one toprocess success, one to process failure.

56/123

Page 57: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Error Handling with Asynchronous Procedures (Success / FailCallbacks)

In the examples we reviewed above, we workedwith a callback that has two parameters - onefor error and one for the returned data in case

of success.

57/123

Page 58: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Error Handling with Asynchronous Procedures (Success / FailCallbacks)

When composing asynchronous functions withtwo parameters of this type, we introducesystematic complexity - because there is noway to “stop early” the chain of calls when anerror is detected - as we would do by throwingan exception in a synchronous case. We musthandle the error case at all steps of the chain

of calls.

58/123

Page 59: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Error Handling with Asynchronous Procedures (Success / FailCallbacks)

For example, assuming the function f, g and hcan return an error or a success, the

composition of f(g(h(x))) requires thefollowing structure:

59/123

Page 60: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Error Handling with Asynchronous Procedures (Success / FailCallbacks)

h(x, (hErr, hRes) => {if (hErr) {failCallback(hErr);

} else {g(hRes, (gErr, gRes) => {

if (gErr) {failCallback(gErr);

} else {f(gRes, callback);

}});

}}); 60/123

Page 61: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Error Handling with Asynchronous Procedures (Success / FailCallbacks)

The following issues make the usage ofasynchronous functions difficult for the

programmer:

• all calls must deal with error cases• sequence of calls or composed calls mustbe translated into nested callbacks

• the types of the functions are obscure

61/123

Page 62: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using Promises to Simplify Asynchronous Composition

Promises are a general programming patterndesigned to simplify asynchronous

composition, in particular error handling.

62/123

Page 63: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using Promises to Simplify Asynchronous Composition

A promise represents the result of anasynchronous operation - it is an object whichserves as the proxy for a delayed computation

which can be in different states:

• pending – The initial state of a promise -before the computation has completed.

• fulfilled – The state of a promiserepresenting a successful operation.

• rejected – The state of a promiserepresenting a failed operation.

63/123

Page 64: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using Promises to Simplify Asynchronous Composition

Once a promise is fulfilled or rejected, itbecomes immutable (i.e. it can never change

again).

64/123

Page 65: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using Promises to Simplify Asynchronous Composition

Promises allow the client (the programmer) toassociate handlers with an asynchronousaction’s eventual success value or failure

reason.

65/123

Page 66: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using Promises to Simplify Asynchronous Composition

This lets asynchronous methods return valueslike synchronous methods: instead of

immediately returning the final value, theasynchronous method returns a promise tosupply the value at some point in the future.

66/123

Page 67: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using Promises to Simplify Asynchronous Composition

Clients of a promise register with the promiseby submitting the callbacks they want the

promise to execute. Since we want to simplifyerror handling, the client of a promise canregister one callback for success completion

(fulfillment) and one for error handling(rejection handler).

67/123

Page 68: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using Promises to Simplify Asynchronous Composition

The registration is performed using twomethods of the Promise interface:

• Promise.then(successHandler)• Promise.catch(rejectionHandler)

68/123

Page 69: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using Promises to Simplify Asynchronous Composition

The handlers are functions which are submittedto be executed in the future, when the promise

is resolved (either fulfilled or rejected).

69/123

Page 70: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using Promises to Simplify Asynchronous Composition

At this point, our understanding of a promise isthat it is an object with the following state:

• task: the asynchronous task to be computed• value: the result of the task when it isresolved

• state: state of the promise (pending,fulfilled or rejected)

• handlers: the handlers for success andfailure

70/123

Page 71: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using Promises to Simplify Asynchronous Composition

The key events in the lifecycle of a promisecorrespond to state transitions:

71/123

Page 72: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using Promises to Simplify Asynchronous Composition

• created in state Pending• pending to fulfilled: triggered when theasync computation completes (usually bythe event loop); triggers the successhandlers.

72/123

Page 73: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using Promises to Simplify Asynchronous Composition

• pending to rejected: triggered when theasync computation ends in error; triggersthe failure handlers.

• attach handlers: if the state is pending, justadd the handlers to the internal state of thepromise, else immediately invoke the newhandler with the stored value of thepromise.

73/123

Page 74: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Making a Promise

To construct a promise from an asynchronousfunction with a callback, we use the Promiseconstructor and abstract the callbacks for

success and failure:const readFilePromise = (filename: string): Promise<string> =>new Promise<string>((resolve, reject) => {fs.readFile(filename, (err, res) => {if (err) {

reject(err);} else {

resolve(res.toString("utf8"));}

});});

74/123

Page 75: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

The Type of a Promise

A promise is a container for a value which maybecome available in the future. A function such

as readFilePromise above returns apromise - in contrast to the original readFile

asynchronous function which had a voidreturn type.

75/123

Page 76: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

The Type of a Promise

This ends up simplifying the type and making itmore similar to the familiar synchronous

version:readFileSync(filename: string): string;

readFile(filename: string,callback: (err, data:string) -> T): void;

readFilePromise(filename: string): Promise<string>;

TypeScript supports generic Promise types todocument this type of return value.

76/123

Page 77: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using a Promise

We use the Promisified version of theasynchronous function according to the

Promise client pattern:

• We decouple the creation of the promisefrom its consumption.

• We separate success and error handling intwo separate concerns.

77/123

Page 78: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using a Promise

To this end, we use the 2 methods of thePromise object: then(successHandler)

and catch(errorHandler):

78/123

Page 79: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using a Promise

const testContent = readFilePromise("test.async");testContent

.then((content: string) =>console.log("Content:", JSON.parse(content)))

.catch((err) => console.error(err));

79/123

Page 80: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Using a Promise

Note the style that the then and catchmethods implement: they return a value of the

same type as the object on which they areinvoked, so that they can be chained. This style

is called the fluent interface pattern.

80/123

Page 81: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Chaining Promises

Using promises, we can achieve 3 main benefitsover the structure that callbacks only would

require:

81/123

Page 82: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Chaining Promises

• The type of functions returning Promises ismore informative and similar to the simpletypes of synchronous versions

• We can chain sequences of asynchronouscalls in a chain of .then() calls.

• We can aggregate error handling in a singlehandler for a chain of calls, in a way similarto exception handling.

82/123

Page 83: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Chaining Promises

The following example illustrates these 3benefits:

• We want to read a file containing a JSONvalue

• Update the content of the JSON• Write back the updated value of the JSON tothe file

83/123

Page 84: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Chaining Promises

This requires a chain of asynchronous calls(reading the file and writing it).

Note that the error handler needs to bespecified only once for the two operations

84/123

Page 85: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Chaining Promises

const readFilePromise = (filename: string): Promise<string> =>new Promise<string>((resolve, reject) => {fs.readFile(filename, (err, res) => {if (err) {

reject(err);} else {

resolve(res.toString("utf8"));}

});});

85/123

Page 86: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Chaining Promises

const writeFilePromise =(filename: string, content: string): Promise<void> =>new Promise((resolve, reject) => {fs.writeFile(filename, content, (err) => {if (err) {

reject(err);} else {

resolve();}

});});

86/123

Page 87: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Chaining Promises

// Chain the calls togetherconst readUpdateWrite = (filename: string): Promise<void> =>readFilePromise(filename).then((content) => {let j = JSON.parse(content);j.lastModified = new Date();return writeFilePromise(filename, JSON.stringify(j));

}).catch((err) => console.error(err));

87/123

Page 88: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Chaining Promises

writeFilePromise("promiseExample.async",JSON.stringify({ a: 1 }))

.then(() => console.log("File is created"))

.then(() => readFilePromise("promiseExample.async"))

.then((content) => console.log(JSON.parse(content)))

.then(() => readUpdateWrite("promiseExample.async"))

.then(() => console.log("File is updated"))

.then(() => readFilePromise("promiseExample.async"))

.then((content) => console.log(JSON.parse(content)));

88/123

Page 89: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Promises Summary

Promises simplify the usage of asynchronousfunctions on three aspects:

89/123

Page 90: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Promises Summary

• Types of functions that return promises areclearer: for a synchronous functionf(x: T1): T2 the corresponding Promiseversion will have typefp(x: T1): Promise<T2>.This is in contrast with a callback-basedversion which would have typefc(x: T1, (err: Error, res:T2) =>T3): void.

90/123

Page 91: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Promises Summary

• Composition is simplified by chaining.then(handler).

• Error handling can be specified in a singleplace, as errors are cascaded throughpromises in a chain.

91/123

Page 92: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Promises Summary

Promises improve significantly overcallback-based asynchronous functions, butstill cannot be used as simply as synchronousfunctions within simple control flow operations(sequence, conditionals, composition). Instead,we still need to pass the promise to a function

using the .then(handler) mechanism.

92/123

Page 93: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Promises Summary

Promises are made even easier to use throughthe mechanism of async and await syntactic

sugar which was introduced in standardJavaScript around 2017. These two new syntactickeywords introduce syntactic variants of thepattern which consists of building a promiseand then chaining code into the then andcatch methods of the promise. So that for

example:

93/123

Page 94: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Promises Summary

// Chain the calls togetherconst readUpdateWrite = (filename: string): Promise<void> =>readFilePromise(filename).then((content) => {let j = JSON.parse(content);j.lastModified = new Date();return writeFilePromise(filename, JSON.stringify(j));

}).catch((err) => console.error(err));

94/123

Page 95: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Promises Summary

is equivalent to the following syntactic variant:

95/123

Page 96: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Promises Summary

// The async/await versionconst readUpdateWriteAsync =async (filename: string): Promise<void> => {try {const content = await readFilePromise(filename);let j = JSON.parse(content);j.lastModified = new Date();return writeFilePromise(filename, JSON.stringify(j));

} catch (err) {return console.error(err);

}};

96/123

Page 97: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

JavaScript (and other programming languages,including Python and Scheme) offer a

mechanism called generators which can becombined with promises to provide excellent

support for asynchronous programming.

97/123

Page 98: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

Generators are functions which can be exitedand later re-entered. Their context (variable

bindings and current control locations) will besaved across re-entries. A generator is created

with the keyword function*.

98/123

Page 99: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

Calling a generator function does not executeits body immediately; an iterator object for thefunction is returned instead. An iterator is a

map with two fields:{value: any, done: boolean} and that

has a next() method:

99/123

Page 100: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

interface IteratorResult {value: any;done: boolean;

}

interface Iterator {next(): IteratorResult;

}

100/123

Page 101: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

When the iterator’s next() method is called,the generator function’s body is executed untilthe first yield expression, which specifies the

value to be returned from the iterator.

101/123

Page 102: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

The next() method returns an object with avalue property containing the yielded valueand a done property which indicates whetherthe generator has yielded its last value as aboolean. Calling the next() method with anargument will resume the generator functionexecution, replacing the yield statement whereexecution was paused with the argument from

next().

102/123

Page 103: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

A return statement in a generator, whenexecuted, will make the generator’s done fieldtrue. If a value is returned, it will be passedback as the value. A generator which has

returned will not yield any more values. (Thatis, return x is like yield x plus the side

effect that the generator is now done).

103/123

Page 104: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

Let us examine a few examples of usinggenerators:

104/123

Page 105: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

function* idMaker() {let index = 0;while (index < 3) {yield index++;

}}

105/123

Page 106: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

const gen = idMaker();

console.log(gen.next()); // { value: 0, done: false }console.log(gen.next()); // { value: 1, done: false }console.log(gen.next()); // { value: 2, done: false }console.log(gen.next()); // { value: undefined, done: true }

106/123

Page 107: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

We can also pass a parameter back to thegenerator by passing it through the next(val)

call:

107/123

Page 108: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

function* demo() {const res = yield 10;assert(res === 32);return 42;

}

const d = demo();console.log(d.next()); // { value: 10, done: false }console.log(d.next(32)); // { value: 42, done: true }console.log(d.next()); // { value: undefined, done: true }

108/123

Page 109: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

The function* special form is used toconstruct a generator. Within the body of a

generator, the yield special form can be used.

109/123

Page 110: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

Generators are most often consumed insideloops - and as their names indicate theygenerate a sequence of values in a lazy

manner: instead of eagerly constructing a listof values, the generator knows how to generate

the values only when asked to.

110/123

Page 111: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

The for loop of JavaScript is a syntax which isadapted to consume any object which

implements the iterator protocol, and henceworks well with generators:function* foo() {

yield 1;yield 2;return 3;

}

for (let v of foo()) {console.log(v);

}111/123

Page 112: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

Generators can be used to generate computedsequences - which can even be infinite, sincethey are only generated when requested:

function* range(start, end) {for (let i = start; i < end; i++) {yield i;

}}

for (let n of range(1, 5)) {console.log(n);

}

112/123

Page 113: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

A generator can produce a potentially infinitestream of data. Such a generator is useful incase the consumer of the stream can limit the

number of items to actually extract.

113/123

Page 114: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

The following example demonstrates an infinitegenerator and a higher order function calledtake which takes as input a number and a

generator - and returns a new generator whichgenerates less than n items from the generator:

114/123

Page 115: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

function* naturalNumbers() {for (let n = 0; ; n++) {yield n;

}}

function* take(n, generator) {for (let v of generator) {if (n <= 0) return;n--;yield v;

}}

for (let n of take(3, naturalNumbers())) {console.log(n);

}115/123

Page 116: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

Generators are an efficient mechanism tocombine iterations without copying lists of data

at each stage.

Consider the following examples:

116/123

Page 117: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

function* mapGen(generator, f) {for (let v of generator) {yield f(v);

}}

function* filterGen(generator, pred) {for (let v of generator) {if (pred(v)) {yield v;

}}

}

117/123

Page 118: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

Such operators can be combined together -with the advantage that the data is not copiedbetween each stage. Instead, each time an

element of the combination is requested, thechain of functions is evaluated:

118/123

Page 119: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

const evenSquares =filterGen(mapGen(naturalNumbers(), x => x * x),

x => x % 2 === 0);

for (let n of take(4, evenSquares)) {console.log(n);

}

119/123

Page 120: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

const verboseSquare = (x) => {console.log("square", x, "->", x * x);return x * x;

};

const verboseIsEven = (x) => {console.log("even?", x, "->", x % 2 === 0);return x % 2 === 0;

};

const evenSquaresVerbose = filterGen(mapGen(nats(), verboseSquare),verboseIsEven

);

for (let n of take(3, evenSquaresVerbose)) {console.log("evenSquaresVerbose", n);

} 120/123

Page 121: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

The order in which the functions are executed isitem-by-item: map-square / filter-even / take

121/123

Page 122: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

square 0 -> 0even? 0 -> trueevenSquaresVerbose 0square 1 -> 1even? 1 -> falsesquare 2 -> 4even? 4 -> trueevenSquaresVerbose 4square 3 -> 9even? 9 -> falsesquare 4 -> 16even? 16 -> trueevenSquaresVerbose 16square 5 -> 25even? 25 -> falsesquare 6 -> 36even? 36 -> true

122/123

Page 123: Principles of Programming Languages - Asynchronous Programmingppl202/wiki.files/class/presentations/lec16.… · we present practical issues in Asynchronous Programming, and techniques

Generators and Co-routines

In contrast, the traditional map and filterfunctions allocate a list (an array) to store the

intermediary results. The functions areevaluated on all the array at once - square onall the items of the input array first, then even

on all the items of the output array.

123/123