Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Not because it is good, but because we can...
C C++
branch: master

This branch is 10 commits behind cioc:master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
README.md
closure.c
closure.h
functional.c
functional.h
list.c
list.h
main.c
makefile

README.md

functionalC

Not because it is good, but because we can...

e.g. Don't you always wish that you could write like this when you are programming in C?

int
main(int argc, char **argv) {
  //LET THE MEMORY LEAKING BEGIN!!!
  iter(map(range(0, 10), dbl,NULL), printint, NULL);
  iter(filter(range(0, 10), odd, NULL), printint, NULL); 

  //Darker magic?  Not really...
  closure *addtwo = bind(NULL, add, liftint(2));
  closure *addten = bind(NULL, add, liftint(10));

  printf("%d\n", *(int *)call(addtwo, liftint(3)));
  printf("%d\n", *(int *)call(addten, liftint(3)));

  //all together now, with pseudo types everywhere woopie!!!
  list *vars = liftlist(range(0, 10), sizeof(int));
  list *res = lmap(vars, addtwo);
  iter(res, printint, NULL);

  exit(0);
}

No? Neither did I. This is horrible.

Functional C Programming Doc

The Basics

Our basic type is the list.

struct list {
  void *val;
  list *next;
};

All of our functions use this type. There are helper functions to work with lists like newitem, copyitem, and append. Look at the code.

Some standard functional programming functions:

//iterates through a list calling fn
void
iter(list *l, void (*fn)(void *, void *), void *args)
//yeah, it's map
list *
map(list *l, void *(*fn)(void *, void *), void *args)
//lifted map is so that you can map closures; maybe we'll unify the type system later...
list *
lmap(list *l, closure *cl)
//yup, and filter too
list *
filter(list *l, bool (*fn)(void *, void *), void *args)
//for fun
list *
range(int start, int end)

Closures

Closures are built around two types: a closure and an environment variable

struct closure {
  void *(*fn)(list *);
  list *env;
};

struct envobj {
  void *val;
  ssize_t size;
};

A closure is a function that is bound to an environment. To bind an environment variable to a closure, use the bind function.

closure *
bind(closure *c, void *(*fn)(list *), envobj *env);

To call this closed function, we use the call function:

void *
call(closure *c, envobj *env);

To make environment variables, we need to lift our types into the environment.

//returns a lifted integer
envobj *
liftint(int a);
//this transforms a list into an environment
list *
liftlist(list *l, ssize_t s) 
Something went wrong with that request. Please try again.