What is CoMingle?

CoMingle is a programming language designed to enable programmers to seamlessly create distributed and decentralized applications over Android-based devices.

Why CoMingle?

Traditionally, distributed applications are implemented by writing a separate program for each (class of) device(s). Each program manages communication with other programs and handles concurrency. This node-centric approach is tedious to use and extremely error-prone.

Instead, CoMingle allows the programmer to write a single declarative program that describe what the entire distributed application is doing. This ensemble-centric approach eliminates the hassle of dealing with communication and concurrency. Ensemble-centric programs are compiled automatically into the node-centric code that runs on the actual devices.

Heterogenous system!

Need more than just Android? Want a Mac client? Windows is your cup of tea? Say no more! We've developed a Java x86 compatible runtime, so you can now make a CoMingle client on Mac or Windows that can communicate seamlessly with your Android phones using our supported middlewares!

Multiple Middlewares!

Comingle supports multiple networking middlewares, and soon will also support heterogeneity across middlewares! You will be able to have in one group, different networks on different devices, but they will still be able to communicate!


Want to learn more, go through our tutorial to programming distributed applications using CoMingle.


Check out some of our apps (source code on Github)


Source code, examples and more on Github.

A light dip in multiset rewriting

CoMingle is based on a linear logic concept called multiset rewriting, in this page we will give a short preview of how a multiset rewrite rule would work on two devices.

Take the following predicates and rewrite rule as an example

predicate natPass ::(int,loc)->trigger.
predicate natTake ::(int,loc)->actuator.
rule pass:: [A]natPass(N,B) --o [B]natTake(N,A).

In CoMingle, there are 3 types of predicates, normal ones, triggers, and actuators. Normal predicates exist simply as tokens, while triggers are used to interact with your multiset, and actuators notify apps of a multiset interaction.

In this example, we have the predicate "natPass" that functions as a trigger, and the predicate "natTake" that functions as an actuator.

When a device "A" adds the predicate "natPass(N,B)" to his multiset from his app, the rule "pass" will consume the predicate "natPass(N,B)" from "A"'s multiset and add the predicate "natTake(N,A)" to "B"'s multiset, thus notifying "B"'s app.

This is a simple example of how an exchange of a simple integer can happen using multiset rewrite, as you can see, there is no networking code what-so-ever, as that bit is handled by the CoMingle runtime library. For a more complex and detailed example, check out our tutorial page.