1 Introduction

Session types [5], from their origins in the \(\pi \)-calculus [17], serve as rigorous specifications for coordinating link mobility in the sense that a communication link can move among participants, while ensuring type safety. In session type systems such mobility is called delegation. Once the ownership of a session is delegated (transferred) to another participant, it cannot be used anymore at the sender side. This property is called linearity of sessions and appears indispensable for all session type systems.

Linearity of session channels, however, is a major obstacle to adopt session type disciplines in mainstream languages, as it requires special syntax extensions for session communications [9], or depends on specific language features, such as type-level functions in Haskell [11, 16, 20, 26], and affine types in Rust [13], or even falling back on run-time and dynamic checking [7, 8, 22, 27]. For instance, a common way in Haskell implementations is to track linear channels using an extra symbol table which denotes types of each resource conveyed by a parameterised monad. A Haskell type for a session-typed function is roughly of the form:

$$\begin{aligned} t_1 \rightarrow \cdots \rightarrow \mathtt{M}\, \{c_1 \mapsto s_1, c_2 \mapsto s_2, \cdots \} \, \{c_1 \mapsto s'_1, c_2 \mapsto s'_2, \cdots \}\,\alpha \end{aligned}$$

where M is a monad type constructor of arity three, \(\alpha \) is a result type and the two \(\{\cdots \}\) are symbol tables before (and after) evaluation which assign each channel \(c_i\) to its session type \(s_i\) (and \(s'_i\) respectively). This symbol table is represented at the type level, hence the channel \(c_i\) is not a value, but a type which reflects an identity of a channel. Since this static encoding is Haskell-specific using type-level functions, it is not directly extendable to other languages.

This paper proposes the session-ocaml library, which provides a fully static implementation of session types in OCaml without any extra mechanisms or tools (i.e. sessions are checked at compile-time). We extend the technique posted to the OCaml mailing list by Garrigue [4] where linear usage of resources is enforced solely by the parametric polymorphism mechanism. According to [4], the type of a file handle guarantees linear access to multiple resources using a symbol table in a monad-like structures. Adapting this technique to session types, in session-ocaml, multiple simultaneous sessions are statically encoded in a parameterised monad. More specifically, we extend the monad structure to a slot monad and the file handles to lenses. The slot monad is based on a type \(\mathtt{(}p,\,q,\,a)\,\mathsf{monad}\) (hereafter we use postfix type constructor of OCaml) where p and q are called slots which act like a symbol table. Slots are represented as a sequence of types represented by nested pair types . Lenses [15] are combinators that provide access to a particular element in nested tuples and are used to manipulate a symbol table in the slot monad. These mechanisms can provide an idiomatic way (i.e. code does not require interposing combinators to replace standard syntactic elements of functional languages) to declare session delegations and labelled session branching/selections with the static guarantee of type safety and linearity (unlike FuSe [22] which combines static and dynamic checking for linearity, see Sect. 5).

To enable session-type inference solely by unification in OCaml, session-ocaml is equipped with polarised session types which give an alternative formulation of duality (binary relation over types which ensures reciprocal use of sessions). In a polarised session type sess, the polarity q is either (server) or (client). The usage of a session is prescribed in the protocol type p which provides an objective view of a communication based on a communication direction of (request; client to server) and (response; server to client). For example, the protocol type for sending of a message type ’v from client to server is and the opposite is . Duality is not necessary for protocol types as it shows a protocol common to both ends of a session rather than biased by either end. Then the session type inference can be driven solely by type unification which checks whether a protocol matches its counterpart or not. For instance, the dual of is and vice versa. When a session is being initiated, polarities are assigned to each end of a session according to the primitives used, namely for the proactive peer and for the passive peer. The protocol types also provide a usual prefixing declaration of session types, which is more human-readable than FuSe types [22] (see Sect. 5).

figure a

The rest of the paper is as follows. Section 2 outlines programming with session-ocaml. Section 3 shows the library design with the polarised session type and the slot monads. In Sect. 4, we present two examples, a travel agency usecase and SMTP protocol implementations. Section 5 discusses comparisons with session type implementations in functional languages. Section 6 concludes and discusses further application of our technique. Technical report [10] includes the implementation of session-ocaml modules and additional examples. Session-ocaml is available at https://github.com/keigoi/session-ocaml.

2 Programming with session-ocaml

In this section, we overview session-typed programming with session-ocaml and summarise communication primitives in the library.

Send and receive primitives. Listing 1 shows a server and client which communicate boolean values. The module Footnote 1 introduces functions of session-ocaml in the scope. (line 2) is a service channel (or shared channel) that is used to start communication by a client connecting to the server waiting at it.Footnote 2 The server (lines 3–7) receives a pair of booleans, then calculates the exclusive-or of these values, transmits back the resulting boolean, and finishes the session . These communication primitives communicate on an implicit session endpoint (or session channel) which is connected to the other endpoint. For inferring session types by OCaml, communication primitives are concatenated by the bind operations

figure b

of a parameterised monad [1] which conveys session endpoints. The syntax binds the value returned by \(e_1\) to the pattern pat and executes \(e_2\), which is shorthand for (the \(\small {\texttt {\%}}\) symbol indicates a syntax extension point in an OCaml program). The client (lines 8–12) sends a pair of boolean, receives from the server and finishes the session, as prescribed in the following type. These server and client behaviours are captured by the protocol type argument of the channel type inferred at as follows:

figure c
figure d

The protocol type is the primary language of communication specification in session-ocaml. Here, is a protocol that represents communication of a message of type v before continuing to p. indicates a communication direction from client to server and vice versa, respectively. is the end of a session. Thus the above type indicates that by a session established at , (1) the server receives a request of type bool * bool and then (2) sends a response of type bool back to the client.

Branching and recursion. A combination of branching and recursion provides various useful idioms such as exception handling. As an example, Listing 2 shows a logical operation server. The protocol type inferred for is:

figure e

represents a protocol that branches to \(p_i\) when label lab \(_i\) is communicated. Here r is a communication direction. is an equi-recursive type [24] of OCaml that represents recursive structure of a session where in t is instantiated by . Lines 8–14 describe the body of the server. It receives one of the labels bin or fin, and branches to a different protocol. is the syntax for branching to the expression \(e_i\) after label \({ lab}_i\) is received. Upon receipt of bin, the server receives requests for a logical operation from the client (type binop and bool * bool), sends back a response and returns to the branch (note that the server is recursively defined by ). In the case of fin, the session is terminated. is a syntax to select one of branches with a label lab.Footnote 3 A client using selection is shown in lines 18–25: it selects the label bin, requests conjunction, and selects fin; then the session ends.

figure f

For the branching primitive on arbitrary labels, session-ocaml uses OCaml polymorphic variants and syntax extensions. By using equi-recursive types, recursive protocols are also directly encoded into OCaml types.

Link mobility with delegation. Link mobility with session delegation enables one to describe a protocol where the communication counterpart dynamically changes during a session. A typical pattern utilising delegation incorporates a main thread accepting a connection and worker threads doing the actual work to increase responsiveness of a service.

In session-ocaml, a program using delegation handles multiple sessions simultaneously. We explicitly assign each session endpoint to a slot using slot specifiers , , \(\cdots \) which gives an idiomatic way to use linear channels. Listing 3 shows an example of a highly responsive server using delegation. The server receives repeated connection requests on channel consisting of the main thread and six worker threads. The module SessionN provides slot specifiers and accompanying communication primitives, where the suffix N means that it can handle on arbitrary number of sessions. The main thread (lines 3–7) accepts a connection from a client with and assigns the established session to slot 0 .Footnote 4 Next, it connects to a worker waiting for delegation at channel (line 2) and assigns the session to slot 1 . Finally it delegates the session with the client to the worker , then ends the session with the worker and accepts the next connection. The worker thread (lines 8–12) receives the delegated session from the main thread and assigns the session to slot 0, then continues to (Listing 2). Here, module used by implicitly allocates the session type to slot 0, hence can be used with SessionN module. Line 14 starts the main thread and workers. Here is a function that executes session-ocaml threads.

The protocol type of is inferred as follows:

figure g

Here is the protocol type of and is the delegation type. r is a communication direction, s is a polarised session type (a type with protocol and polarity which we explain next) for the delegated session and p is a continuation. By inferring the protocol types, session-ocaml can statically guarantee safety of higher-order protocols including delegations.

The polarised session types. Communication safety is checked by matching each protocol type inferred at both ends. The polarised session type given to each endpoint plays a key role for protocol type inference. Here p is a protocol type, and is the polarity determined at session initiation. is assigned to the side and to the side. and are dual to each other.

The polarised session type gives a simple way to let the type checker infer a uniform protocol type according to a communication direction and a polarity assigned to the endpoint. For example, as we have seen, we deduce (response) from server transmission and client reception . Table 1 shows correspondences between polarities and communication directions.

Table 1. Correspondence between polarities and communication directions
Fig. 1.
figure 1

Session type changes in

To track the entire session, a polarised session type changes in its protocol part as a session progresses. Figure 1 shows changes of the session type in slot 0 of the xor server (here we use the SessionN module). The server first accepts a connection and assigns the session type to slot 0, where the type before acceptance is . After the subsequent reception of the pair of booleans and transmission of the xor values of those booleans, and are consumed, and becomes again at the end of the session. Similar type changes occur on both and and their types would be:

figure h

Here the type specifies that it expects slot sequence s at the beginning, and returns another slot sequence t and a value of type a. The type denotes that slot 0 and 1 are empty at the beginning, and since they never return the answer (i.e. the recursion runs infinitely), the rest of types and are left as variables.

The type of in Listing 2 has a session type:

figure i

Here expects a session assigned at slot 0 before it is called, hence it expects the session type in its pre-type. A difference from and above is that since each of them establishes or receives sessions by their own (by using ), they expect that slots 0 and 1 are .

Table 2. session-ocaml primitives and protocol types

Table 2 shows the type and communication behaviour before and after the execution of each session-ocaml communication primitive. Each row has a pre-type (the type required before execution) and post-type (the type guaranteed after execution). The protocol type at is obtained by replacing with and with . For example, the session has pre-type at and at where \(\small {\texttt {\_}}n\) is a slot specifier, e is an expression, v is a value type and p is a protocol type. Selection has open polymorphic variant type in pre-type to simulate subtyping of the labelled branches.

3 Design and Implementation of session-ocaml

In this section, we first show the design of polarised session types associated with communication primitives (Sect. 3.1); then introduce the slot monad which conveys multiple session endpoints in a sequence of slots and constructs the whole session type for a session (Sect. 3.2). In Sect. 3.3, we introduce the slot specifier to look up a particular slot in a slot sequence with lenses which are a polymorphic data manipulation technique known in functional programming languages. We present the syntax extension for branching and selection, and explain a restriction on the polarised session types. This section mainly explains the type signatures of the communication primitives. Implementation of the communication behaviours is left to [10].

3.1 Polarity Polymorphism

The polarity polymorphism is accompanied within all session primitives in that the appropriate direction type is assigned according to the polarity. This resolves a trade-off of having two polarised session types for one transmission. For instance, a transmission of a value could have two candidates, and but they are chosen according to the polarity from which the message is sent. In order to relate the polarities to the directions, and are defined by type aliases as follows:

figure j

For each communication primitive, we introduce fresh type variables \(r_{ req} \) and \(r_{ resp}\) representing the communication direction, and put \(r_{ req}*r_{ resp}\) as the polarity in its session type. When its polarity is , we put \(r_{ req}\) for and \(r_{ resp}\) for , while when it is , we put \(r_{ req}\) for and \(r_{ resp}\) for . For example, the pre-type of is and that of is . The same discipline applies to branching and delegation. The actual typing is deferred to the following subsections.

3.2 The Slot Monad Carrying Multiple Sessions

The key factor to achieve linearity is to keep session endpoints securely inside a monad. In session-ocaml, multiple sessions are conveyed in slots using the slot monad of type

figure k
figure l

which denotes a computation of a value of type \(\alpha \), turning each pre-type \(s_i\) of slot i to post-type \(t_i\). We refer to slots before and after computation as pre- and post-slots, respectively. The type signature of the slot monad is shown in Listing 4. The operators >>= and >> (lines 3–4) compose computation sequentially while propagating type changes on each slot by demanding the same type in the post-slots on the left-hand side and the pre-slots on the right-hand side. Usually they construct compound session types via unification. For example, in (from Listing 2 the left hand side has the following type:

figure m

While the type of the right hand side is:

figure n

By unifying the post-type in the preceding monad with the pre-type in the following monad (and the rest of slots with ), the bind operation produces a chain of protocol type in the pre-slots as follows:

figure o

In line 5, executes the slot monad and requires all slots being before and after execution, thus it precludes use of unallocated slots, and mandates that all sessions are finally closed (which corresponds to the absence of contraction in linear type systems). The type (line 1) is a type alias for OCaml equi-recursive type ,Footnote 5 enabling use of arbitrarily many slots.

Table 3. Types for slot specifiers
figure p

3.3 Lenses Focusing on Linear Channels

In order to provide access to session endpoints conveyed inside a slot monad, we apply lenses [15] to slot specifiers which are combinators to manipulate a polymorphic data structure. The following shows the type of a slot specifier which modifies slot n of a slot sequence:

figure q

The type says that it replaces the type of slot n in the slot sequence with and the resulting sequence type becomes to . The type of each slot specifier (, , \(\cdots \)) is shown in Table 3.

Listing 5 exhibits type signatures of which are compiled from lenses, the polarised session types (Sect. 3.1), slot monads (Sect. 3.2), and pre- and post-types in Table 2 (Sect. 2). Note that are named parameters of a primitive.

and (lines 1–4) assign a new session channel to the slot, whereas (lines 5–6) finishes the session and leave the slot again. and (lines 7–10) proceed the protocol type by removing a prefix.

and (lines 11–16) update a pair of slots; one is for the transmission/reception and the other is for the delegated session. To update the slots twice, they take a pair of slot specifiers which share an intermediate slot sequence . They embody an aspect of linearity: releases the ownership of the delegated session by replacing the slot type to , while allocates another slot to the acquired session.

The primitives for binary selection and branching (lines 17–25) communicate labels. takes a pair of continuations as well as a pair of slot specifiers. According to the received label, one of the continuations is invoked after the pre-type of the invoked continuation is assigned to the corresponding slot.

Finally, we present how to embed slot type changes into a pair of slot sequences in a slot monad where the position of the slot is specified by applying a slot specifier. In each type signature, the first and second type arguments of type prescribes how a slot type changes. The third and fourth arguments do not specify a slot in the slot sequence conveyed by the slot monad. For example, the type of function application is given by the following type substitution:

figure r

And the type completing the session at slot 1 is:

figure s

A note on delegation and slot assignment. The delegation distinguishes polarity in the delegated session s. This results in a situation where two sessions exhibiting the same communicating behaviour cannot be delegated at a single point in a protocol, if they have different polarities from each other. It is illustrated by the following (untypeable) example.

figure t

Recall that yields a endpoint while gives a . Due to the different polarities in the delegated session types, the types of and clause conflict with each other, even if they have the identical behaviour. In [32], where polarity is not a type but a syntactic construct, such a restriction does not exist. A similar restriction exists in GV [30] which has polarity in end (\(\mathtt{end}_{!}\) and \(\mathtt{end}_{?}\)).

In principle, it is possible to automatically assign numbers to slot specifiers locally in a function instead of writing them explicitly. However, since sequential composition of the monad requires each post- and pre-type to match with each other, the global assignment of slot specifiers would require a considerable amount of work and can be hard to predict its behaviour. As shown in Listing 3, one can handle two sessions by just using two slot specifiers.

figure u
figure v

Syntax extension for arbitrarily labelled branch. Since the OCaml type system does not allow to parameterise type labels (polymorphic variants), we provide macros for arbitrarily-labelled branching. Listing 6 provides helper functions for the macros. For selection, the macro is expanded to , where the helper function transmits label \({ lab_i}\) on the slot n. is expanded to:

figure w

The helper functions and have the type shown in Listing 6. The anonymous function will have type

figure x

where q is the polarity and \(p_i\) is the protocol type in the pre-type at slot n in \(e_i\). When a label (\(i \in \{1\ldots k\}\)) is received, passes a pair of witness and of a polarised session type to the function f. The anonymous function extracts the witness and by it rebuilds the session type and passes the session to the continuation \(e_i\) as the pre-type. The type annotation erases the row type variable generated by the anonymous function. The annotation is necessary because the row type variable turns into a useless monomorphic row type variable in the inferred protocol type. This may cause a problem while compiling since the compiler requires monomorphic type variables to not escape from compilation units.

4 Applications

4.1 Travel Agency

We demonstrate programming in session-ocaml using the Travel agency scenario from [9], which consists of typical patterns found in business and financial protocols. The scenario is played by three participants: , and (Listing 7). initially do not know each other, and mediates a deal between them by session delegation.

begins an order session with and binds it to their own slot 0 (each process has a separate slot sequence). Then requests and receives the price for the desired journey after sending the label. In our scenario, requests and replies with a fixed price .

Then might send the agree label to proceed the transaction with the current price. Or if does not agree with the price, can cancel the transaction by sending the reject label. Or, can send quote again and this will be repeated an arbitrary number of times for different journeys (we omit this branch from the code). In our program, agrees with at a price less than , or otherwise rejects it and terminates the transaction.

Next, if agrees with the price, opens the session with and binds it to slot 1. Then it delegates to , through slot 1, the interactions with remaining for slot 0. then sends the billing address (unaware that he/she is now talking to ), and replies with the dispatch date () for the purchased tickets. The transaction is complete.

The protocol type between and is inferred as:

figure y

Delegation from to is inferred in the channel of as:

figure z

The delegated type is polymorphic on the polarity and communication directions (Sect. 3.1), hence the can handle both polarities. It reflects the part after in the protocol above where is and is . Thus delegation with the polarised session types and slots effectively gives a way to coordinate higher order communication incurred by link mobility.

figure aa
figure ab

Static checking of delegation makes it easier to find errors otherwise hard to analyse due to the indirect nature of delegation. Consider a case that changes its behaviour to receive . Now the inferred protocol type at would be:

figure ac

Whereas that of remains same as before, it results in a type error at the moment when a service channel is passed. Without static typing, the run-time error would be deferred until the beginning of actual communication.

4.2 An SMTP Protocol

This section shows an SMTP client implementation by session-ocaml. Listings 8 and 9 shows the protocol type of SMTP and message types representing SMTP commands and replies; and Listing 10 shows the client implementation. Line 2 in Listing 10 generates a service channel for connecting to the SMTP server. Here is an adapter that converts a sequence of session messages to a TCP stream. Its definition is shown in Listing 11 and built using the combinators shown in Listing 12. The functions req and resp accept a function to convert between a message of type ’v and a command string and construct an adapter. bra and sel are branching and selection respectively, and cls is the end of the session. The function with the same name as the message type is a function for converting to a string (or vice versa) and is responsible for actual stream processing. In OCaml, f @@ g means function composition , and means . Since OCaml evaluates eagerly, each function is \(\eta \)-expanded with a parameter ch so that it does not recurse infinitely.

figure ad
figure ae

The adapter for branch bra is asymmetric in its parameters [18]. bra has a parser of type string -> ’v option on the left side since the adapter determines a continuation in a branch according to the parsed result of a received string. The adapter chooses left if the parser succeeds (returns Some(x)), and right if it fails (None). By nesting bra, any nesting of branch can be constructed.

Comparing to the existing Haskell implementation in [11], an advantage is that our OCaml version enjoys equi-recursive session types, so we avoid the manual annotation of repeated operations needed to unfold iso-recursive types in Haskell. A shortcoming of the OCaml version is the explicit nature of adapter. However, since the adapter and the protocol type have the same structure, it can be generated semi-automatically from the type declaration in Listing 8 when OCaml gains ad hoc polymorphism such as type classes. We expect this to be possible with modular-implicits [31], which will be introduced in a future version of OCaml. On the other hand, it is also possible to omit the protocol type declaration in Listing 8 by inferring the type of the adapter.

figure af

5 Related Work

We discuss related work focusing on the functional programming languages. For other related work, see Sect. 1.

Implementations in Haskell. The first work done by Neubauer and Thiemann [18] implements the first-order single-channel session types with recursions. Using parameterised monads, Pucella and Tov [26] provide multiple sessions, but manual reordering of symbol tables is required. Imai et al. [11] extend [26] with delegation, handling multiple sessions in a user-friendly manner by using type-level functions. Orchard and Yoshida [20] use an embedding of effect systems in Haskell via graded monads based on a formal encoding of session-typed \(\pi \)-calculus into PCF with an effect system. Lindley and Morris [16] provide an embedding of the GV session-typed functional calculus [30] into Haskell, building on a linear \(\lambda \)-calculus embedding by Polakow [25]. Duality inference is mostly represented by a multi-parameter type class with functional dependencies [14]; For instance, class Dual t t’| t -> t’, t’ -> t declares that t can be inferred from its dual t’ and vice versa. However, all of the above works depend on type-level features in Haskell, hence they are not directly applicable to other programming languages including OCaml. See [21] for a detailed survey. session-ocaml generalises the authors’ previous work in Haskell [11] by replacing type-level functions with lenses, leading to wider applicability to other programming languages.

Implementations in OCaml. Padovani [22] introduces FuSe, which implements multiple sessions with dynamic linearity checking and its single-session version with static checking in OCaml. Our session-ocaml achieves static typing for multiple sessions with delegation by introducing session manipulations based on lenses; and provides an idiomatic way to declare branching with arbitrary labels; while FuSe combines static and dynamic approach to achieve them.

The following example shows that session-ocaml can avoid linearity violation, while FuSe dynamically checks it at the runtime.

figure ag

sends repeatedly until it receives label . Although the endpoint should be used linearly, the condition is violated at the beginning of the second iteration since the endpoint is disposed by using the wildcard at the end of the . In FuSe 0.7, is well-typed and terminates in error InvalidEndpoint at runtime. In session-ocaml, this error inherently does not occur since each endpoint is implicit inside the monad and indirectly accessed by lenses.

[22] gives a micro-benchmark which measures run-time performance between the static and dynamic versions of FuSe. Based on the benchmark, it is shown that the overhead incurred by dynamic checking is negligible when implemented with a fast communication library such as Core [12], and concludes that the static version of FuSe performs well enough in spite of numerous closure creations in a monad. The FuSe implementation has been recently extended to context free session types [29] by adding an endpoint attribute to session types [23].

On duality inference, a simple approach in OCaml is firstly introduced by Pucella and Tov [26]. The idea in [26] is to keep a pair of the current session and its dual at every step; therefore the notational size of a session type is twice as big as that in [5]. FuSe [22] reduces its size by almost half using the encoding technique in [3] by modelling binary session types as a chain of linear channel types as follows. A session type in FuSe (’a, ’b) t prescribes input (’a) and output (’b) capabilities. A transmission and a reception of a value ’v followed by a session (’a, ’b) t are represented as and respectively, where means “no message”; then the dual of a session type is obtained by swapping the top pair of the type. A drawback of these FuSe notations is it becomes less readable when multiple nestings are present. For example, in a simplified variant of the logic operation server in Listing 2 with no recursion nor branch, the protocol type of becomes:

figure ah

In FuSe, at server’s side, the channel should be inferred as:

figure ai

Due to a sequence of flipping capability pairs, more effort is needed to understand the protocol. To recover the readability, FuSe supplies the translator Rosetta which compiles FuSe types into session type notation with the prefixing style and vice versa. Our polarised session types are directly represented in a prefixing manner with the slight restriction shown in Sect. 3.3.

6 Conclusion

We have shown session-ocaml, a library for session-typed communication which supports multiple simultaneous sessions with delegation in OCaml. The contributions of this paper are summarised as follows. (1) Based on lenses and the slot monad, we achieved a fully static checking of session types by the OCaml type system without adding any substantial extension to the language. Previously, a few implementations were known for a single session [22, 26], but the one that allows statically-checked multiple sessions is new and shown to be useful. To the authors’ knowledge, this is the first implementation which combines lenses and a parameterised monad. (2) On top of (1), we proposed macros for arbitrarily labelled branches. The macros “patch up” only the branching and selection parts where linear variables are inevitably exposed due to limitation on polymorphic variants. (3) We proposed a session type inference framework solely based on the OCaml built-in type unification. Communication safety is guaranteed by checking equivalence of protocol types inferred at both ends with different polarities.

Type inference plays a key role in using lenses without the burden of writing any type annotations. Functional programming languages such as Standard ML, F# and Haskell have a nearly complete type inference, hence it is relatively easy to apply the method presented in this paper. On the other hand, languages such as Scala, Java and C# have a limited type inference system. However, by a recent extension with Lambda expressions in Java 8, lenses became available without type annotations in many cases (see a proof-of-concept at https://github.com/keigoi/slotjava). The main difficulty for implementing session types is selection primitives since they require type annotations for non-selected branches. Development of such techniques is future work.

Our approach which uses slots for simultaneous multiple sessions resembles parameterised session types [2, 19], and it is smoothly extendable to the multiparty session type framework [6]. We plan to investigate code generations from Scribble [28] (a protocol description language for the multiparty session types) along the line of [7, 8] integrating with parameterised features [2, 19].