Name: Anonymous 2011-12-12 12:06
is it possible to write C in a functional manner?
debian:~/host/prog$ cat lambda.c
#include <stdio.h>
#define lambda(return_type, function) \
({ \
return_type __fn__ function __fn__; \
})
int main()
{
int (*max)(int,int) = lambda(int, (int x,int y) { return x > y ? x : y; });
printf("max of 2,6: %d | max of 4,2: %d\n",max(2,6),max(4,2));
return 0;
}
debian:~/host/prog$ gcc lambda.c
debian:~/host/prog$ ./a.out
max of 2,6: 6 | max of 4,2: 4
#include <stdio.h>
int t1(char* string, FILE* out) {
return (*string == '\0') ? 0
: (((out == stdout) ? t1(string + 1, stderr)
: t1(string + 1, stdout)),
fputc(*string, out));
}
int main(int argc, char** argv) {
return (argc == 0) ? 0
: ((t1(*argv, stdout), fputc('\n', stdout)),
main(argc - 1, argv + 1));
}
#include <malloc.h>
#include <stdio.h>
#include <assert.h>
typedef struct exception_vtable* exception_header;
typedef exception_header* exception;
struct exception_vtable {
void (*print)(FILE* output, exception self);
};
struct invalid_int_argument_exception {
exception_header header;
int argument;
};
void print_invalid_int_argument_exception(FILE* output, exception self) {
fprintf(output, "invalid_argument_exception: arg: %d\n", ((struct invalid_int_argument_exception*)*self)->argument);
}
struct exception_vtable invalid_int_argument_exception_vtable = {
print_invalid_int_argument_exception
};
exception invalid_int_argument_exception(int argument) {
struct invalid_int_argument_exception* x = malloc(sizeof(struct invalid_int_argument_exception));
assert(x);
x->header = &invalid_int_argument_exception_vtable;
x->argument = argument;
return (exception)x;
}
#define NO_EXCEPTION ((void*)0)
exception factorial_loop(int n, int accumulation, int* ret) {
return (n == 0) ? (*ret = accumulation, NO_EXCEPTION)
: factorial_loop(n - 1, accumulation * n, ret);
}
exception factorial(int n, int* ret) {
return (n < 0) ? invalid_int_argument_exception(n)
: factorial_loop(n, 1, ret);
}
exception print_factorial_of_string(char* string) {
int n_fact; // This explicit stack allocation might not be all that functional. It is always better to allocate shit on the heap.
return factorial(atoi(string), &n_fact) ||
(printf("%s! is %d\n", string, n_fact),
NO_EXCEPTION);
}
exception print_factorial_of_args(int arg_count, char** arg_array);
exception print_factorial_of_args(int arg_count, char** arg_array) {
return (arg_count == 0) ? NO_EXCEPTION
: (print_factorial_of_string(*arg_array) ||
print_factorial_of_args(arg_count - 1, arg_array + 1));
}
int exit_with_exception(exception e) {
return (e == NO_EXCEPTION) ? 0
: (fprintf(stderr, "Uncaught Exception: "),
(*e)->print(stderr, e),
fprintf(stderr, "\n"),
free(e),
1);
}
int main(int argc, char** argv) {
return exit_with_exception(print_factorial_of_args(argc - 1, argv + 1));
}