Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The Scheme and Python versions both return the derivative function. The C version is significantly less cool. I'd want to do something like:

    func cube_3rd_deriv = NthDeriv(3, &Cube); /* returns a function */
    double result = cube_3rd_derive(5.0);


You can still do this in C, with the same implementation Lisp uses under the hood. C being C, there is a bit of syntax boilerplate. I also omitted some details which may have been relevant at the time such as ensuring no cast from function pointers to data pointers (not hard to handle, but makes the code a bit longer).

    #include<stdio.h>
    #define DX 0.0001
    typedef double (*function)(double);
    typedef double (*closure_body)(void*, double);
    struct deriv_env { function f; };
    struct closure { void* env; closure_body body; };
    #define CALL(c, x) ((c)->body((c)->env, (x)))
    double deriv_body(void *env, double x) {
        function f = (deriv_env *)env->f;
        return (f(x + DX) - f(x)) / DX;
    }
    void deriv(function f, struct closure *out) {
        out->env = (void *)f;
        out->body = deriv_body;
    }
    double cube(double x) { return x * x * x; }

    int main(void) {
        struct closure cube_deriv;
        deriv(&cube, &cube_deriv);

        printf("%f\n", CALL(&cube_deriv, 2.));
        printf("%f\n", CALL(&cube_deriv, 3.));
        printf("%f\n", CALL(&cube_deriv, 4.));

        return 0;
    }


Maybe not as theoretically cool (doesn't happen at runtime) but isn't this pretty much the same in practice?

    double Cube3rdDeriv(double x) {
        return NthDeriv(3, &Cube, x);
    }
&Cube3rdDeriv can now be passed around in a higher-order way.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: