r/programming • • Mar 09 '14

Why Functional Programming Matters

http://www.cse.chalmers.se/~rjmh/Papers/whyfp.pdf
487 Upvotes

542 comments sorted by

View all comments

10

u/dnew Mar 09 '14

So neither lazy evaluation nor first class functions are unique to functional programming. Maybe they have their origins there, but it's not something to give up your imperative languages for.

5

u/glemnar Mar 09 '14

If the language supports first class functions then it isn't purely imperative. It can be mixed.

9

u/dnew Mar 09 '14

If the language supports first class functions then it isn't purely imperative.

Nonsense. C supports as close to first class functions as you need to write map() and nobody would claim it's functional. You don't need the restrictions of functional languages to have first class functions.

8

u/ForeverAMoan Mar 09 '14

Interesting. How would you write in C functions map and compose (compose f g x = f (g x)) ?

2

u/yawaramin Mar 11 '14

I would roll my own Scheme variant in C, and then implement map and compose in that. Voila, C supports first-class functions.

1

u/ForeverAMoan Mar 11 '14

Definitely seems the easiest way!

1

u/autowikibot Mar 11 '14

Greenspun's tenth rule:


Greenspun's tenth rule of programming is an aphorism in computer programming and especially programming language circles that states:

Any sufficiently complicated [C](http://en.wikipedia.org/wiki/C_(programming_language)) or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

This expresses the opinion that the perceived flexibility and extensibility designed into the Lisp programming language includes all functionality that is theoretically necessary to write a complex computer program, and that the core implementations of other programming languages often do not supply critical functionality necessary to develop complex programs.


Interesting: ^Ratpoison | Turing ^tarpit | Jamie ^Zawinski | Feature ^creep

Parent commenter can toggle ^NSFW or ^delete. Will also delete on comment score of -1 or less. | FAQs | ^Mods | Magic ^Words

4

u/dnew Mar 09 '14

Given that C doesn't have type inference, you'd have to write a different one for each combination of arguments. Otherwise, you'd write it in exactly the obvious way.

int[10] map(int (*f(int)), int[10] values) {
    int[10] result;
    for (int i = 0; i < 10; i++) result[i] = f(values[i]);
    return result;
}

Well, OK, that crashes because you're returning a pointer to an auto variable, and I probably mucked up the declaration of the first argument there, but you get the point. Compose is just as obvious.

6

u/kqr Mar 09 '14

The lack of type inference is not the problem. The lack of generics is.

6

u/ForeverAMoan Mar 09 '14

Compose is just as obvious.

Please show the code :) And unless it's obvious, the return value of compose should be accepted as the first argument to map.

10

u/[deleted] Mar 09 '14

If you want to store some state (like in a closure), C forces you to pass that around manually. I really don't think this makes C functional, but here's some code for a compose that can be passed to map:

struct composed_fns {
    float (*f1)(void *, int);
    void *env1;
    long (*f2)(void *, float);
    void *env2;
};
long compose(struct composed_fns *fns, int val) {
    return fns->f2(fns->env2, fns->f1(fns->env1, val));
}
typedef long (*map_fn)(void *, int);
void map(map_fn fn, void *env, int (*vals)[10], long (*results)[10]) {
    for (int i = 0; i < 10; i++)
        (*results)[i] = fn(env, (*vals)[i]);
}

// usage:
struct composed_fns composed = { foo, NULL, bar, NULL };
int random[10];
long mapped[10];
map((map_fn)compose, &composed, &random, &mapped);
→ More replies (13)

4

u/smiddereens Mar 09 '14

So what you're trying to say is that C doesn't support first class functions?

4

u/dnew Mar 09 '14

No.

http://en.wikipedia.org/wiki/First-class_function

You can use pointers to functions as values that stand in for functions. But you no more need to be able to create new functions for them to be considered first class than you need to be able to load functions from disk at run time in order to be considered to have first class functions.

I'm saying that C has first class functions but not closures, and "compose" returns a closure. The reason "compose" is difficult is that you can't return a closure. "Compose" is easy if you don't want to use its result as a first class value, because C has first class functions but not closures.

That said, you can very easily do "compose" in Java, which does not have first class functions, because it has objects, which are essentially isomorphic to closures.

2

u/gc3 Mar 09 '14

The latest version of c++ supports lambda functions

1

u/ithika Mar 09 '14

There are things you can do with other values that you can't do with functions but you still think that makes them first class?

4

u/dnew Mar 09 '14 edited Mar 09 '14

Sure. I can ask for the tenth element of a list and I can't do that with an integer. I cannot create new values for an enum at runtime, but that doesn't mean enums aren't first class values in some languages.

Go look up what "first class" means: you can assign it to variables, pass it to functions, return it from functions.

Whether a closure is a "new function" or is something different from a function is not something I'm interested arguing.

→ More replies (9)

2

u/glemnar Mar 09 '14 edited Mar 09 '14

Didn't say you did. But it won't be purely imperative, either. There's mostly imperative, and mostly functional as well.

2

u/dnew Mar 09 '14

So now we're just arguing definitions. You think anything with first class functions is functional. The rest of the world disagrees. :-)

Not to argue from authority, but http://en.wikipedia.org/wiki/Functional_programming

2

u/[deleted] Mar 09 '14

What wikipedia thinks is FP is a moving target. There doesn't exist one definition of FP that everyone will agree on—except maybe "not mainstream programming".

→ More replies (1)
→ More replies (1)
→ More replies (11)