Automatically exported from
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

Pattern Matching and Sum types for C

This is a set of macros that provide the ability to declare and pattern match on sum types:

/* declare a sum type and its constructor tags */
SUM(foo) {
/* declare each sum case */
CASE(foo, foo_one) { int i; char c; };
CASE(foo, foo_two) { double d; };

void do_bar(foo f) {
  MATCH(f) {
    AS(foo_one, y) printf("foo_one: %d, %c\n", y->i, y->c);
    AS(foo_two, y) printf("foo_two: %d\n", y->d);
      fprintf(stderr, "No such case!");

int main(int argc, char** argv) {
  foo f;
  LET(f, foo_one, (3, 'g')); /* (3,'g') is an initializer */

Note that each AS branch introduces a new scope, so you can declare new identifiers, unlike C's switch.


  1. A MATCH statement must start in a position where new locals can be declared. In other words, in a new lexical scope, or after other locals have been declared.
  2. MATCHANY is mandatory, and must always come last.
  3. Each LET binding performs a dynamic memory allocation using malloc. The MAKE binding form allows you to specify a custom allocation function matching malloc's signature, but some form of allocation is needed.

Future Work

Allow MATCH to discriminate on user-specified tag field names, eg. to allow matching on existing C unions instead of requiring them to adopt the SUM/CASE structure.


My default license is LGPL v2, but I'm not sure how that interacts with the fact that the "library" consists solely of a header file, and thus has no runtime replaceable binary. I like the LGPL's conditions otherwise, so I'm open to other license suggestions that provide similar freedoms.