Skip to content

Instantly share code, notes, and snippets.

@pstephens
Created June 28, 2018 03:31
Show Gist options
  • Save pstephens/dc08296018fa5b620cae8226ffe145b8 to your computer and use it in GitHub Desktop.
Save pstephens/dc08296018fa5b620cae8226ffe145b8 to your computer and use it in GitHub Desktop.
What would transducers look like in C?
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
typedef struct thing thing_t;
struct thing {
long num;
int cnt;
thing_t *children;
};
typedef bool (*pred_thing)(void *context, thing_t *x);
typedef struct lambda_pred_thing {
void *context;
pred_thing fn;
} lambda_pred_thing_t;
typedef void (*transducer_thing)(void *context, thing_t *x);
typedef struct lambda_transducer_thing {
void *context;
transducer_thing fn;
} lambda_transducer_thing_t;
void foreach(thing_t *parent, lambda_transducer_thing_t *next) {
for (int i = 0; i < parent->cnt; ++i) {
next->fn(next->context, parent->children + i);
}
}
typedef struct lambda_filter_thing {
lambda_transducer_thing_t this;
lambda_pred_thing_t pred;
lambda_transducer_thing_t next;
} lambda_filter_thing_t;
void filter(lambda_filter_thing_t *context, thing_t *thing) {
if (context->pred.fn(context->pred.context, thing)) {
context->next.fn(context->next.context, thing);
}
}
void make_filter(lambda_filter_thing_t *context, lambda_pred_thing_t *pred, lambda_transducer_thing_t *next) {
memset(context, 0, sizeof(lambda_filter_thing_t));
context->this.context = context;
context->this.fn = (transducer_thing) filter;
context->pred = *pred;
context->next = *next;
}
void print(char *format, thing_t *thing) {
fprintf(stdout, format, thing->num);
}
void make_print(lambda_transducer_thing_t *lambda, char *format) {
memset(lambda, 0, sizeof(lambda_transducer_thing_t));
lambda->context = format;
lambda->fn = (transducer_thing) print;
}
bool thing_is_even(void* context, thing_t* thing) {
return thing->num % 2 == 0 ? true : false;
}
void lambda_test() {
thing_t x[5] = {
{.num =105, .cnt = 0, .children = NULL},
{.num = 112, .cnt = 0, .children = NULL},
{.num = 201, .cnt = 0, .children = NULL},
{.num = 302, .cnt = 0, .children = NULL},
{.num = 403, .cnt = 0, .children = NULL}
};
thing_t parent = {.num = 0, .cnt = 5, .children = x};
lambda_transducer_thing_t print_lambda;
make_print(&print_lambda, "-- %ld --\n");
lambda_filter_thing_t filter_lambda;
lambda_pred_thing_t filter_pred = {.context = NULL, .fn = thing_is_even};
make_filter(&filter_lambda, &filter_pred, &print_lambda);
foreach(&parent, &filter_lambda.this);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment