poica
A programming language on top of C macros, supporting many modern concepts: ADTs, pattern matching, type introspection, algebraic effects, tuples.
Table of contents
ADTs
Using sum types (aka tagged unions) together with pattern matching, we can naturally map the problem domain to the actual code. Simply put:
- A sum type is a type that is either a dog, a cat, or an elephant.
- Pattern matching is doing something depending on the matching value (of a sum type). If a value is a dog, walk with it, if a cat, feed it, or if an elephant - ride it.
Now the statements above can be encoded directly in C:
typedef struct {
unsigned speed;
} Dog;
typedef struct {
const char *eye_colour;
} Cat;
typedef struct {
float ears_size;
} Elephant;
SUM(
Animal,
VARIANT(MkDog OF Dog)
VARIANT(MkCat OF Cat)
VARIANT(MkElephant OF Elephant)
);
void process_animal(Animal animal) {
MATCH(&animal) {
CASE(MkDog, dog) {
printf("Dog\n");
printf("Speed = %u km/hour\n", dog->speed);
printf("Walking...\n");
}
CASE(MkCat, cat) {
printf("Cat\n");
printf("Eye colour = %s\n", cat->eye_colour);
printf("Feeding...\n");
}
CASE(MkElephant, elephant) {
printf("Elephant\n");
printf("Ears size = %f meters\n", elephant->ears_size);
printf("Riding...\n");
}
}
puts("");
}
int main(void) {
Animal dog = MkDog((Dog){.speed = 12});
Animal cat = MkCat((Cat){.eye_colour = "green"});
Animal elephant = MkElephant((Elephant){.ears_size = .5});
process_animal(dog);
process_animal(cat);
process_animal(elephant);
}
Output
Dog
Speed = 12 km/hour
Walking...
Cat
Eye colour = green
Feeding...
Elephant
Ears size = 0.500000 meters
Riding...
Practical examples of sum types include AST evaluation and error handling.
Tuples
A tuple is just a structure with fields named _0
, _1
, ..., _N
. You can define it both outside and inside procedures (aka in-place), like this:
#include "../include/tuple.h"
#include <stdio.h>
int main(void) {
TUPLE(const char *, int, double) tuple = {"Hello, tuples!", 123, 1885.1191};
printf("('%s', %d, %f)\n", tuple._0, tuple._1, tuple._2);
}
Output
('Hello, tuples!', 123, 1885.119100)