#include <stdlib.h>
#include <stdio.h>


typedef float (*linear)(float, void* closure);


typedef struct {
	linear fun;
	void* closure;
} linear_lambda;

void linear_lambda_free(linear_lambda* ln) {
	free(ln->closure);
}


typedef struct {
	float a;
	float b;
} make_linear_closure;

static float make_linear_inner(float x, void* closure) {
	make_linear_closure* cl = closure;
	return x*cl->a + cl->b;
}

linear_lambda make_linear(float a, float b) {
	make_linear_closure* cl = malloc(sizeof(make_linear_closure));
	cl->a = a;
	cl->b = b;
	linear_lambda res = { make_linear_inner, cl };
	return res;
}


void takes_a_linear(float x, linear ln, void* opaque) {
	float p1 = ln(x, opaque);
	float p2 = ln(2*x, opaque);
	printf("Two points on a line: (%f, %f), (%f, %f)\n", x, p1, 2*x, p2);
}


int main() {
	linear_lambda l1 = make_linear(2.0, 1.0);
	linear_lambda l2 = make_linear(2.0, 3.0);
	takes_a_linear(3.0, l1.fun, l1.closure);
	takes_a_linear(2.0, l2.fun, l2.closure);
	linear_lambda_free(&l2);
	linear_lambda_free(&l1);
}
