lchannels
is a Scala library for
type-safe session programming. It
provides linear I/O channels, which allow to transfer
data locally, or over a network. Its API allows
to (1) define
protocols, represented as a set
of continuation-passing style classes,
and (2) easily write programs that interact according
to such protocols. The Scala type checker can examine the
resulting code and spot many protocol violations at
compile time.
An example
Consider a simple ATM, which is supposed to implement the following session protocol:
-
the user provides his/her card number and PIN;
- if the card number or pin are wrong, the ATM notifies the failure and quits the session;
-
otherwise, the user can choose between:
- checking the account balance. In this case, the ATM answers accordingly, and quits;
- quitting the session.
Such a protocol can be represented with the
following continuation-passing style classes
(where Out[A]
is an output channel
endpoint carrying an A
-typed message, and
the cont
fields describe how the session
continues):
case class Authenticate(card: String, pin: String)(val cont: Out[Response])
sealed abstract class Response // Authentication response from the ATM
case class Failure() extends Response
case class Success()(val cont: Out[Menu]) extends Response
sealed abstract class Menu // Choices available to authenticated user
case class CheckBalance()(val cont: Out[Balance]) extends Menu
case class Quit() extends Menu
case class Balance(amount: Int) // User account balance
Then, the ATM can be implemented with the following Scala code
(where the method In[A].?
allows to receive
an A
-typed message,
while Out[A].!
and Out[A].!!
allow to send an A
-typed message):
def atm(c: In[Authenticate]) = {
c ? { auth =>
if (!authenticated(auth.card, auth.pin)) {
auth.cont ! Failure()
} else {
( auth.cont !! Success()_ ) ? {
case m @ CheckBalance() => m.cont ! Balance(42)
case Quit() => ()
} } } }
The Scala compiler will ensure that the ATM program does not
send the wrong type of message
(e.g., trying to send Balance
when Success
/Failure
are expected),
and that it does not forget to handle some valid user requests
(e.g., it will warn if the Quit
case is missing).
This way, many protocol violations are detected at compile
time; other protocol safety errors (e.g., duplicate
outputs) are detected
at runtime --- and in this case, lchannels
raises errors and prevents out-of-protocol messages to be sent.
Notably, In[A]
and Out[A]
abstract the underlying message transport:
the atm()
method above can interact with an user
process e.g. via local data queues, or through a TCP/IP
socket. As a result, the protocol logic and its
low-level details are decoupled.
Documentation and publications
The theory and practice of session programming
with lchannels
is presented in the following
papers: they explain how protocols
(formalised as session types) can be
represented in Scala using lchannels
with
continuation-passing style classes, and discusses
the main features of the library.
-
Alceste Scalas and Nobuko Yoshida.
“Lightweight
Session Programming in Scala”. Proceedings of
the 30th European
Conference on Object-Oriented Programming (ECOOP 2016).
A previous version of
lchannels
is also published as the companion artifact of the paper. - Alceste Scalas and Nobuko Yoshida. “Lightweight Session Programming in Scala (extended version)”. Technical Report 2015/7, Imperial College London (updated in May 2016).
NOTE: newer versions
of lchannels
available on GitHub
have some differences and
improvements.
Downloading, compiling and testing
You can download lchannels
from its
GitHub repository.
To compile an test the code, you can follow these instructions.