The Functional Machine Calculus

This paper presents the Functional Machine Calculus (FMC) as a simple model of higher-order computation with"reader/writer"effects: higher-order mutable store, input/output, and probabilistic and non-deterministic computation. The FMC derives from the lambda-calculus by taking the standard operational perspective of a call-by-name stack machine as primary, and introducing two natural generalizations. One,"locations", introduces multiple stacks, which each may represent an effect and so enable effect operators to be encoded into the abstraction and application constructs of the calculus. The second,"sequencing", is known from kappa-calculus and concatenative programming languages, and introduces the imperative notions of"skip"and"sequence". This enables the encoding of reduction strategies, including call-by-value lambda-calculus and monadic constructs. The encoding of effects into generalized abstraction and application means that standard results from the lambda-calculus may carry over to effects. The main result is confluence, which is possible because encoded effects reduce algebraically rather than operationally. Reduction generates the familiar algebraic laws for state, and unlike in the monadic setting, reader/writer effects combine seamlessly. A system of simple types confers termination of the machine.


Introduction
Higher-order programming and computational effects are ubiquitous in modern programs.Understanding them, and in particular their potent combination, is therefore an important challenge to computer science.Higher-order functional programming enjoys an elegant foundational theory in the λ-calculus, where βreduction gives rise not only to operational semantics-by imposing an evaluation strategy-but also to an equational theory which may be regarded as definitive for higher-order functions.For computational effects, however, there are many approaches and, as yet, no single definitive theory.Such a theory would ideally include a convenient syntax, expressing a natural and convincing semantics, and supporting reasoning tools and methods such as type-systems and compile-time optimizations, while remaining amenable to refinement, extension and variation.
The rich history of approaches to the problem of computational effects in a higher-order setting includes Landin's pioneering work [17], which cemented the central position of λ-calculus, and highlighted the difficulty of reconciling the drive for a complete theory with the practice of programming: Landin focussed on a call-by-value strategy and used thunks to delay evaluation where necessary.A more modular and

Locations
The main objective of this work has been to preserve confluence, following the recent presentation of a confluent probabilistic λ-calculus by Dal Lago, Guerrieri, and Heijltjes [4].This is perhaps surprising, as λcalculi with effects are known to be non-confluent.The apparent contradiction disappears by disentangling the operational and the algebraic aspects of evaluation.In λ-calculus, β-reduction is algebraic (or more precisely, β-equivalence is), while stack machines such as Krivine's [15] give an operational semantics.For effects, looking up a global variable or generating a random value is operational, while effect operators may interact algebraically via the laws of Plotkin and Power [27].

global, operational local, algebraic
λ-calculus stack machines β-reduction effects update, lookup, read, write, random algebraic effect equations Our starting point is the observation that for both the λ-calculus and reader/writer effects, the operational side can be given by push and pop actions on global stacks or streams.In a simple stack machine for the λ-calculus, application M N pushes its argument N to the stack and continues as M , and abstraction λx.M pops a term N from the stack and binds it to x, to continue as {N/x}M (the capture-avoiding substitution of N for x in M ).Then, the following effects are also modelled via stacks or streams: • reading from input is a pop from an input stream; • writing to output is a push to an output stream; • a memory cell c is modelled by a stack of depth one, where • update c := N pops from c, discarding the value, then pushes the new value N ; • lookup !c pops the value N from c, pushes N to reinstate c, and then returns N ; • probabilistic and non-deterministic generators can be modelled as separate input streams.This idea is captured in the poly-λ-calculus: we introduce a set of locations to represent independent stacks or streams on the machine, and parameterize abstraction and application in this set to act as pop and push actions on the corresponding stack.Effect operators are then encoded in these constructs according to the above scheme.Beta-reduction, generalized to multiple locations, remains confluent, and for encoded effect operators it gives rise to the expected algebraic laws [27].However, this encoding of effects forces their call-by-name semantics, while programming with effects requires control over when they are called.This is the purpose of the second generalization, sequencing.Heijltjes 6-3

Sequencing
The literature offers several ways to control reduction behaviour in higher-order languages, including continuation encodings between cbv and cbn [28], and call-by-push-value (cbpv) [18] which encodes both.To complement locations, our approach takes the stack machine as primary.Viewing the λ-calculus as a language of machine instruction sequences, the sequencing generalization extends it with composition and the empty sequence, analogous to imperative "sequence" and "skip"; not by introducing these as primitives, but again by generalizing the calculus in a subtle way so that they arise naturally.Such designs have arisen several times before: in the first-order κ-calculus of Hasegawa [11], generalized to higher-order in the context of premonoidal categories [30]; as the Λ s -calculus in an analysis of compilers [7]; and in higher-order stack programming languages, also called concatenative languages [12], such as Joy [36], λ-FORTH [21], Cat [6], and closest to our design, Factor [26].
Douence and Fradet demonstrate how their Λ s encodes Plotkin's cbv λ-calculus [28] as well as Moggi's monadic constructs [24,25], illustrating how this design gives control over reduction.We will recall these encodings in Sections 3.2 and 3.3, and demonstrate the encoding of cbpv and Arrows [14].

The Functional Machine Calculus
The FMC combines both generalisations, locations and sequencing, in a simple model of higher-order computation with multiple effects.Its design and solid foundations in semantics mean that several important properties of the λ-calculus are preserved.The aim of this paper is introductory: it presents the syntax, operational semantics, and fundamental ideas and results with an emphasis on explanation and examples.In a forthcoming paper we will deepen these results with a strong normalization theorem, a domain-theoretic semantics of the untyped calculus, and semantics of the typed calculus in premonoidal and in Cartesian closed categories.The main results for the FMC as presented here are the following: Confluence Beta-reduction is confluent, with evaluation behaviour expressed in syntax.Algebraic effects The algebraic laws for reader/writer effects arise from reduction.Compositionality Reader/writer effects combine seamlessly, due to the use of independent locations.Types Simple types cover (higher-order) effect operations and confer termination of the machine.

The poly-lambda-calculus
We introduce a set of locations A, ranged over by a, b, c, . . ., to indicate the different stacks or streams for each effect.Abstraction and application are parameterized in A to give the corresponding pop and push actions.We write application M N as [N ].M to emphasize the operational reading (push N and continue as M ), to easily attach a location a, and to give unique parsing-cf.De Bruijn [5].Abstraction λx.N is written x .N to emphasize the duality with application.

Definition 2.1
The poly-λ-calculus is given by the grammar with from left to right a variable, an application or push action on location a with function M and argument N , and an abstraction or pop action on location a that binds x in M .Terms are considered modulo α-equivalence.The regular λ-calculus embeds via a dedicated main location λ ∈ A, omitted from terms for brevity; so we may write λx.M or x .M for λ x .M , and The poly-stack machine is given by the following data.A stack of terms S is written with the top element to the right; we define them inductively below left, but they should better be considered as coinductive, to include streams.A memory S A is a family of stacks or streams in A, defined below left.We write S A ; S a to identify the stack for a in S A .A state is a pair (S A , M ), and the transitions or steps are given as top-to-bottom rules below centre.A run of the machine is a sequence of steps, written as

6-4
Functional Machine Calculus (S A , M )⇓ (T A , N ) or with a double line as below right.

Encoding effects
Consider the following λ-calculus with effects.We will encode it in the poly-λ-calculus, with its lazy or cbn semantics.At the end of this section we will consider what would be needed to encode its eager or cbv semantics.(We assume familiarity with the operational semantics of λ-calculus and of effects; for an introduction see e.g.Winskel [37].)The cbn-encoding will follow the description in the introduction.The constructs of the above language are introduced as defined constructs ("sugar") into the poly-λ-calculus.Input/output: Input uses a dedicated input location in ∈ A and is encoded by read x where the underscore ( ) represents a variable that does not occur in M or N .In the machine, the stack for each cell is initialized with a (dummy) value, and the transitions then give the expected operational semantics.
Probabilistic and non-deterministic sums: Following the probabilistic case [4], probabilistic and non-deterministic sums are included via dedicated locations rnd, nd ∈ A by N ⊕ M ∆ = rnd x .x M N and N + M ∆ = nd x .x M N .The machine is initialized with the corresponding streams of Church-encoded Booleans λx.λy.x and λx.λy.y, generated probabilistically for rnd and non-deterministically for nd.The machine steps are as expected.

Beta-reduction
In the λ-calculus, β-reduction lets successive push-and pop-actions interact.Generalizing to multiple locations, these must be actions on the same stack, while other stacks may be accessed in-between.Analogous to β-reduction, η-reduction is as below, where each X i is an abstraction or application not on location a, and x does not occur free in any of the X i nor in M .
As an alternative to these rule schemes, terms may be taken modulo an equivalence ∼ generated by the permutations below left, and β-and η-reduction defined only on adjacent operators, as below right.
Observe that the machine semantics immediately validates these equivalences.We will use the below formulation to consider the relation with algebraic effects, but otherwise use the above formulation.
Beta-reduction is confluent, as will be shown more generally for the FMC in Section 4. This is possible because it follows the algebraic laws for effects [27] instead of their operational semantics.For instance, laws for the interaction of lookup and update correspond to the following reductions.
The seven algebraic laws for global state of Plotkin and Power [27, p. 348] arise in our setting from β/ηreduction and ∼.Their notation has update u loc,v (M ) of location loc with value v in M , and lookup l loc (M ) v of the value v at location loc using the value v as a parameter in M .These are encoded in the poly-λ-calculus as below, using abstraction with x instead of parametrization in v in the lookup case.
Values v may be taken as arbitrary poly-λ-terms.
Functional Machine Calculus Proposition 2.4 The poly-λ-calculus with βη ∪ ∼ generates the algebraic laws for state.
Proof.By the following equations, where a = b and in equation 7, x / ∈ fv(v).

Poly-types
A simple type for a poly-term represents its expected inputs, taken from multiple independent locations.Correspondingly, the antecedent of an implication is parameterized in a location, and implications on distinct locations may permute.
Definition 2.5 Simple poly-types are given by the grammar below left, where o (omicron) is a base type and a(σ)→ τ an arrow type, and considered modulo the congruence ∼ given below right.
ρ, σ, τ The typing rules are as follows, where a context Γ is a finite function from variables to types.
Observe that the congruence ∼ means that a term M : a(ρ)→ b(σ)→ τ may be prefixed by a push action [N ]a where N : ρ or by one [P ]b where P : σ (or both, in either order).

Towards encoding call-by-value semantics
The poly-λ-calculus gives control over when effects are called, as we demonstrate by the following example.
Example 2.6 Consider the following example term, which is a normal form with cbn semantics.
With cbv, the arguments may be evaluated left to right, reducing to f 0 2 1, or right to left, which gives f 0 3 1.The two readings are encoded as follows (using regular applications to f for readability).
The encodings rely on repositioning an update c := 1 as a prefix, and for a lookup !c, on separating the global actions c x .[x]c from the variable x where the value is used.(The latter idea gives the cbv semantics in the probabilistic case [4].)However, it is unlikely that an encoding that only repositions effect operations can encode the cbv semantics of λ-calculus with effects.Consider the following example.To obtain this semantics in the poly-λ-calculus by manipulaton of effect operations would require lifting b := 1 out of a redex-a process which is likely undecidable in general.
The poly-λ-calculus thus gives control over effects, but not evaluation behaviour in general.It is an open question whether this is sufficient for practical purposes-one we cannot answer here.Instead, we will consider sequencing as a natural way to include cbv semantics.

The sequential lambda-calculus
As an instruction sequence for a stack machine, a λ-term is a string of push and pop actions that must end in a variable.But the machine would naturally accept any sequence of actions and variables.Relaxing the variable restriction would further enable composition of sequences.This design of λ-calculus with sequential composition appears several times in the literature and in practice: as the calculus Λ s [7], as the higher-order κ-calculus [30], and in concatenative programming languages such as Factor [26].We call this generalization of the λ-calculus sequencing, and implement it by introducing a skip (or nil) construct and making the variable a prefix.Beta-reduction is otherwise standard, by closing the rule below left under all contexts.The abstract machine has states (S, M ) of a stack and a term, and the transitions below right.
Example 3.2 Consider the following example terms.
The first duplicates the top item on the stack; the second removes two items; the third pushes the term x .
[x] (which picks up and returns an item), pops it as f , and runs it three times.
Observe that the changes to evaluation are absorbed by substitution and composition, while β-reduction and machine evaluation remain unchanged.There is nevertheless a change in perspective from the λcalculus, in that the return values or outputs of a computation are pushed to the stack, rather than left as

6-8
Functional Machine Calculus the remainder of the term.Machine evaluation for a term M with input stack S is expected to terminate in ⋆ (just as imperative computation successfully terminates in a skip command) with an output stack T , i.e. (S, M )⇓ (T, ⋆).Then ⋆ gives the identity run (of zero steps), and M ; N gives composition of runs.

Sequential types
The type system for the sequential λ-calculus follows that of the κ-calculus [30]; similar type systems have also been studied for stack languages [33].The type of a term describes the input/output behaviour of its machine evaluation: it consists of an implication between a vector of input types, one for each element consumed from the stack, and a vector of output types, one for each item returned to the stack.Definition 3.4 Sequential types are defined by: ρ, σ, τ , υ :: Vector concatenation is by juxtaposition, ⇀ σ ⇀ τ , and the reverse of a vector Typing rules for the sequential λ-calculus are given below.A stack is typed by a type vector, where The terms in Example 3.2 can be typed as follows.
Observe that because stacks are last-in first-out, the identity function on the top two stack items is the term x .y .x returns the stack consisting of x prepended to T .The type derivation is below.Note that the term (λx.xx)(λy.yy) is not typeable: the argument λy.yy needs a type that takes input, and then so should x.
x : Observe that all sequential types τ are inhabited by at least the element ⊥ τ : τ , defined below (note that the base case n = m = 0 gives ⋆ : (⇒)).This is in contrast with the simply-typed λ-calculus, where not all types are inhabited due to the presence of the uninhabited base type o.

Encodings of call-by-name calculi
The (regular, call-by-name) λ-calculus is included as a fragment of the sequential λ-calculus.We extend this embedding with types and with products, and to Moggi's computational metalanguage [25] following Heijltjes 6-9 Douence and Fradet [7].The main observation is that implications embed as input-only sequential types, and products as output-only types, below left.The formal, inductive encoding is then below right.
Following the types, product terms encode as follows.
(M, N ) The computational metalanguage extends the λ-calculus with monadic type formers T (σ), and a return construct [M ] T and a let construct let T parameterized in T .In the interpretation in the sequential λcalculus, the return value of a monadic function is pushed to the stack.A monadic function type is then interpreted as one with a single output, as below left.The language constructs are encoded as below right.
It is easily verified that this extends correctly to type derivations and reductions.

Encodings of call-by-value calculi
The cbv λ-calculus [28] and the computational λ-calculus λ c [24], which extends the former with a monadic type constructor T and with the term constructs return and let, have an encoding in the κ-calculus [7,30].We recall this for the sequential λ-calculus, and observe that it naturally extends to types.The cbvinterpretion of types is naturally viewed in two stages.First, types in isolation are translated as follows.
Evaluation of a λ c -term returns a value, which in the encoding is pushed to the stack.A typed term M : τ will then translate as M v : ⇒ τ v , with a single output type.Terms of the computational λ-calculus are then interpreted as below.Again it is easily verified that this extends correctly to type derivations and reduction.The machine behaviour of encoded terms can be seen to follow the SECD-machine [16].

Arrows, call-by-push-value, and kappa-calculus
The sequential λ-calculus may encode the related formalisms of Arrows, cbpv, and κ-calculus.For reasons of space, we will not recall these calculi in detail and only provide an outline to the interested reader.Hughes's Arrows [14] take the λ-calculus with products and extend it with a second implication σ τ , which we interpret directly as that of the sequential λ-calculus, σ ⇒ τ .Arrow terms have three constructors, encoded as below.The first lifts a regular term M : ρ→ σ to an arrow term; the second composes two arrow terms P : ρ σ and Q : σ τ ; and the third applies the arrow term P to the first element of a pair.
The perspective that emerges from this encoding is that the arrow calculus corresponds to a version of the sequential λ-calculus with binary products instead of stacks (which may be considered n-ary products).

6-10
Functional Machine Calculus Characteristic of cbpv [18,19], and also featured in κ-calculus, is the separation of computations and values.In the sequential λ-calculus this distinction is present, too, if implicitly: values live on the stack, and computations run the machine.To make it explicit, we may extend the calculus with thunk and force constructs !M and ?V , and their reduction rule, as below left.Term constructs of cbpv (without products or sums) then embed as below right.

V , W
Types for cbpv feature a monadic functor F and a value functor U .The latter could be introduced into sequential types as below left, though the structure of the arrow type ⇒ makes it redundant.Types then further encode as call-by-name types, below right.
σ, τ :: The higher-order κ-calculus [30] is closely related to the sequential λ-calculus.Types are the same as sequential types: an implication between type vectors.Terms omit the unit ⋆ and have composition M ; N as a primitive (rather than prefixing).The remaining constructs encode as follows.

String diagrams
We may view typed sequential λ-terms as string diagrams.A term M : ρ 1 . . .ρ m ⇒ σ n . . .σ 1 is rendered as below.The wires represent the input and output stacks, with the first element at the top.
We will use these diagrams to illustrate how types compose.First, strict composition is the composition of terms M : τ , below left.This does not give the most general form of composition.For that, we combine it with the following notion of expansion.If a term takes an input stack R to an output stack S, then when given a larger stack U R it returns U S, with U untouched.Then if M : These constructions combine to give the general case, where in M ; N the type of M or N may be expanded.Note that in the regular λ-calculus only the first case arises, as the second case requires multiple outputs.( Observe that the first equation in Definition 3.8 corresponds to the left composition diagram above, and the second equation to the right diagram, where in both cases ⇀ σ gives the types of the connecting wires between M and N .The following proposition establishes these basic properties, as well as the familiar subject reduction.Proposition 3.9 Typed terms satisfy the following properties: • Composition: if Γ ⊢ M : σ and Γ ⊢ N : τ and σ •τ is defined, then Γ ⊢ M ; N : σ •τ .

Machine termination
A remarkable aspect of the type system is how it gives a direct connection with termination of the machine.
To expose this, we formalize the intuitive meaning of types as describing the initial and final stack of a run of the machine.
Note that a successful run requires the term to be closed, so a set run(τ ) contains only closed terms.The following lemma shows that run(τ ) is always inhabited by the term ⊥ τ (see Remark 3.7).Lemma 3.11 For any type τ the set run(τ ) is inhabited: If M : τ implies M ∈ run(τ ), then a type derivation is a termination proof of the machine.This is Theorem 3.13, and proving it gives a concrete Tait-style reducibility proof [34], where run(τ ) takes the rôle of the reducibility set for τ .By using the properties of machine runs the proof is then a simple, direct induction on type derivations.
Vector notation is extended to variables, • If the derivation is a ⋆-rule for Γ ⊢ ⋆ : τ then there is a trivial zero-step run (T, ⋆)⇓ (T, ⋆).
• If the derivation ends in the variable rule below left, then for any N ∈ run( Γ, x : • If the derivation ends in the application rule below left, then by the inductive hypothesis for N we have N ′ = {W/ ⇀ w}N ∈ run(ρ), and for M we have a run from M ′ and any stack S ∈ run( ⇀ σ) with N ′

6-12
Functional Machine Calculus added on top, to some T ∈ run( ⇀ τ ).This gives the run for {W/ • If the derivation ends in the abstraction rule below left, then for any N ∈ run(ρ) and S ∈ run( ⇀ σ) the inductive hypothesis gives a run for {N/x}M ′ to some T ∈ run( ⇀ τ ).This gives the run for The following theorem is then immediate.

The functional machine calculus
The combination of both generalizations, locations and sequencing, gives the Functional Machine Calculus.
Definition 4.1 The Functional Machine Calculus (FMC) is given by the below grammar, with from left to right the constructors nil, a (sequential) variable, an application or push action on the location a, and an abstraction or pop action on a which binds x in M .Terms are considered modulo α-equivalence.
M , N , P :: Composition N ; M and substitution {N/x}M are as for the sequential λ-calculus.The machine is as for the poly-λ-calculus: a state is a pair (S A , M ) of a memory and a term, and the transitions are: Beta-reduction is as for the poly-λ-calculus: a redex consists of a successive application and abstraction on the same location, separated by any number of actions on other locations.We will now make this formal.
Head contexts H are defined as below left.The term obtained by replacing the hole {} in H with M is denoted H. M , where a binder a x in H captures in M .The binding variables bv(H) of H are those variables x where H is constructed over a x .The set of locations used in a term or context is denoted loc(M ) respectively loc(H).Then Beta-reduction is defined by the rewrite rule schema below right, where a / ∈ loc(H) and bv(H) ∩ fv(N ) = ∅, and is closed under all contexts.
We will first consider the untyped calculus.We give the cbv encoding of effects and provide an intuition for programming in the FMC, then establish confluence and connect machine evaluation to β-reduction.
We then consider simple types.Constants will be used informally, in examples.

Call-by-value with effects
We extend the encoding (−) v of the computational λ-calculus of Section 3.3 to effects as follows.(The case for N ⊕ M is the same as for cbn, as it expects a Church boolean for x.) Integers are values, and the translation will use An update with an integer then simplifies by: The cbv-translated term, after applying this reduction to the two updates, further reduces as follows.

Programming in the FMC
As in the sequential λ-calculus, programming in the FMC naturally follows the concatenative paradigm.
A term M is viewed as a function taking an input memory S A to an output memory T A by a run of the machine (S A , M )⇓ (T A , ⋆).Functions standardly operate on the main stack λ, and it is then natural to consider effect operators that transfer values between the main stack and other locations, as the cbv translations of effect operators do.We introduce the following operations for input and output, a random generator, and a memory cell c.We further add definitions or let, as a redex.Constant operations such as the conditional if pop the required number of items from the main stack, and reinstate their result, as is standard for stack languages.For example: The FMC then operates similarly to a stack calculus for arithmetic: an expression 1 + ((2 + 3) × 4) is given as a term [4].[3].[2].+ .× .[1].+ which indeed returns 21.This results in an imperative programming style similar to Haskell's do-notation, with the difference that terms may have any number of return values, and consume any number of previously returned values.The term assigns f to be the function that draws a random number, stores it in cell c, and reads the value at c again as its return value.It then executes f twice, sums the results, and sends that to output.The overall actions should be to take two random inputs i and j, to update the cell c with the last value j, and to output i + j.In Figure 1 the term is first interpreted as an FMC-term and reduced to normal form, where each line is a beta-step, and then evaluated on the machine, where the initial memory provides the two expected inputs on rnd and one on c. (For compactness we give locations as a header and show only necessary stack elements.)Heijltjes 6-15

Confluence
In demonstrating confluence for the λ-calculus, the difficulty is reduction inside an argument: duplicating or deleting it creates converging reductions of different length.By contrast, spine reduction, which reduces in every context except argument position, is diamond (peaks converge in one step).
While the two extensions of the FMC, locations and sequencing, do create new configurations of overlapping redexes, the situation is fundamentally the same.Spine reduction, defined analogously as reduction in every context except argument position, is diamond, and the remaining problem is the same as for the λ-calculus.The calculus thus remains confluent, which will be proved by the standard parallel reduction technique of Tait and Martin-Löf (see [2]) and Takahashi [35].
The new configurations are the following.Sequencing introduces terms of the form N ; x. M , with reduction in M or in N , where the latter may induce substitutions in x.M .But reduction in N may not duplicate a redex in M , and vice versa, so a peak of this kind converges immediately.
Locations create two new overlapping configurations, nested: [N ]a.but both resolve immediately: in each case the two reducts will converge in one step to {N/x}{P/y}M .Because of this, the problem of confluence amounts to the problem of reduction in arguments, which may be duplicated or deleted, as it does in the regular λ-calculus.We formalize this observation in the following proposition (which is independent of the confluence result).Spine reduction is given by closing the β-step under all contexts except in argument position.That is, reduction in each of x.M , [N ]a.M , and x .M may take place in M , but not in N .The full confluence proof is a standard application of parallel reduction, and is given in Appendix A.

Simple types for the FMC
As with sequential types, FMC types will represent the input/output behaviour of the machine.Since a memory is a family of stacks, types will use families of type vectors.
Definition 4.7 FMC-types ρ, σ, τ , υ are given by: The typing rules for the FMC are in Figure 2.They use the following notation.Concatenation of two vector families is pointwise,  The third term is only a redex, which pushes and then pops a value, giving it an empty type (⇒).The type of the fourth term is that of f ; f .Separating the self-composition of the type of f for each location exposes how the inputs on rnd and outputs on λ accumulate, while the output and input on c interact: By way of illustration, in Haskell the same example may be written as follows.To combine the effects of I/O, state, and random generation, the Haskell example uses a stack of monad transformers.The effects are then layered in a fixed order, and to access each effect the function lift is used to move to the next layer.Thus, the rand action requires no lifting since the random generator is at the top of the transformer stack; the state actions put and get must be lifted once; and the print action must be lifted twice, since I/O is at the bottom of the transformer stack.
The example highlights the following differences between monad transformers and the FMC.Firstly, reader/writer effects in the FMC combine seamlessly, without requiring their organisation in a stack, and are accessed by their locations instead of a lifting function.Secondly, sequential composition in the FMC is a basic operation, with a close connection between the syntax and its execution, where Haskell do-notation is syntactic sugar for more involved monadic operations.Thirdly, the FMC type system accounts for the effectful operations that a term performs, where monad transformer types indicate which effects may be present, but not which operations they perform.

Heijltjes 6-17
Of course, where monads are universal, the FMC is presently restricted to reader/writer effects.How to broaden the range of effects covered in the FMC is an important direction for future work.

Further work
We have given an exploratory overview of the Functional Machine Calculus with the most essential results: the natural capture of algebraic laws for effects by reductions and permutations; the encoding of related formalisms for controlling execution behaviour such as monadic constructs, cbpv, κ-calculus, and Arrows; confluence; and termination of the machine with simple types.A forthcoming paper will strengthen these results with domain-theoretic and categorical semantics, and strong normalization with simple types.
Present and future work aims to extend the FMC beyond reader/writer effects and with standard features.One direction is to include sum types, datatypes, and error handling, where it looks possible to capture all three in a uniform way.A second direction is to introduce parallel composition and explore the relation with process calculi, where our type system promises to give something closely related to session types.A third direction is local mutable store, by introducing a new construct for locations, and generalizing locations to regions to capture mutable data structures (arrays, graphs), which then leads naturally into an exploration of dependent types for the FMC.A fourth direction is to explore the connection with string diagrams, and to introduce constructs to capture diagrammatic reasoning, for example interaction nets or quantum diagrammatic systems.
An important theoretical challenge is type inference.This appears to be open also for the sequential λ-calculus: existing algorithms for concatenative languages are limited [33,6], and (we believe) unable to find the type for the self-application in Example 3.6.
, N, P ::= x | M N | λx.M λ-calculus | read | write N ; M input/output | c := N ; M | !c state update and lookup | N ⊕ M | N + M probabilistic and non-deterministic sum to the left), and the pop transition gives the expected operational semantics, below left.Writing to output uses a dedicated output location out ∈ A and is encoded by write N ; M ∆ = [N ]out.M .Evaluation then generates an output stream N 1 , N 2 , . . .(finite at any step) by the push machine transition, below right.( S A ; S in • N , in x .x ) ( S A ; S in , N ) ( S A ; S out , [N ]out.M ) ( S A ; S out • N , M ) State: A memory cell is modelled by a location c ∈ A. The associated stack is expected to hold at most one value, which is preserved by the encoding of the operators, and not enforced externally.Update and lookup are encoded by c := N ; M ∆ = c .[N ]c.M and !c ∆ = c x .[x]c.

Definition 3 . 8
Type composition σ •τ is the partial operation given below, and is undefined otherwise.

Definition 3 . 10
The set run( ↼ σ ⇒ ⇀ τ ) is the set of terms M such that for any stack S ∈ run( ⇀ σ) there is a stack T ∈ run( ⇀ τ ) and a run of the machine (S, M )⇓ (T, ⋆), where run(τ 1
the inductive hypothesis gives a run for {N/x}M ′ from any T S ∈ run( ⇀ τ ⇀ σ) to some U ∈ run( ⇀ υ) (second item below).For N there is a run from any R ∈ run( ⇀ ρ) to some S ∈ run( ⇀ σ) (third item below).These runs compose into one for {W/ ⇀ w, N/x}x.M = N ; {N/x}M ′ as below right, expanding the stack on the run for N by T .Note that we may assume x / ∈ fv(W ) (otherwise we rename x).

Fig. 1 .
Fig. 1.Reduction followed by machine evaluation of the term in Example 4.4

Example 4 . 4
Consider the following example, where rnd is taken to randomly sample natural numbers.(f = rand ; set c ; get c) ; f ; f ; + ; print [P ]b.b y .a x .M interleaved: [N ]a.[P ]b. a x .b y .M
τ a restricts τ to a single location a).Composition is slice-wise: σ •τ = {σ| a •τ | a | a ∈ A}.Finally, a singleton a( ⇀ τ ) is a type vector at a single location, with all other locations empty, defined by a( ⇀ τ )| a = ⇀ τ and a( ⇀ τ )| b = ε for a = b.A singleton λ( ⇀ τ ) on the main location λ may be written as ⇀ τ .Poly-types embed as types of the form ↼ τ A ⇒ by the definitions o ∆ = (⇒) and a(σ)→ ( ↼ τ A ⇒ ) ∆ = a(σ) ↼ τ A ⇒ , and sequential types embed directly as types over only the location λ.The properties proved of sequential types in Section 3 carry over straightforwardly: strict composition, expansion, composition, substitution, subject reduction, and termination of the machine.Example 4.8 The singleton construct a( ⇀ τ ) gives a natural way of writing types in practice.The term from Example 4.4 may be typed as follows, where Z is a base type of integers.(f = rand ; set c ; get c) ; f ; f ; + ; print : rnd(Z Z) c(Z)⇒ c(Z) out(Z)

Fig. 2 .
Fig. 2. Typing rules for the Functional Machine Calculus example :: RandT StdGen (StateT Int IO) () example = do let f = do x <-rand; lift (put x); lift get y <-f z <-f lift (lift (print (y+z))) Its cbn reduction gives 2. It evaluates in the machine as follows (where the cell a is initialized with zero).