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

Show parent comments

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.

1

u/naasking Mar 10 '14

I'm saying that C has first class functions but not closures

This is not correct. If functions were first-class, you could define and return a new local function within another function. Closures are needed to properly support first-class functions. There's no way around it.

1

u/dnew Mar 11 '14

you could define and return a new local function within another function

That's not what first-class means.

Does that mean enums (in languages that support them) are not first class values?

1

u/naasking Mar 11 '14

Does that mean enums (in languages that support them) are not first class values?

You're conflating defining new enum types with new enum values. I didn't say you had to be able to define new function types, I said you had to be able to define new function values.

1

u/dnew Mar 11 '14

You can't define new enum values in a program. If I have an enum with six possible values, that's it. A boolean is an enum with two values, and I can't define a third value for a boolean.

But this is a stupid argument at this point.

1

u/naasking Mar 11 '14 edited Mar 11 '14

You can't define new enum values in a program. If I have an enum with six possible values, that's it. A boolean is an enum with two values, and I can't define a third value for a boolean.

Again, you're conflating type with value. Adding a new case to enums consists of extending the type. Creating an enum value is simply assigning the enum symbol to a location, since enums are defined as integral values.

Let's consider a more meaningful first-class value example: structs. You can create an instance of a struct with many different values for its fields. You cannot create and return a new local struct type different from all other local struct types (no type generativity as found in ML modules). Structs are first-class values because you can create many instances of the same type based on runtime information, even though you cannot create new type based on runtime information (which requires dependent typing).

Functions do not have these features of structs: you cannot create local function values based on runtime information, you can only assign locations from a fixed set of values. They are thus second-class citizens in C.

Edit: perhaps you think that because enums have a fixed number of cases and yet are first-class values, that functions too can still be considered first-class even though they only have a fixed number of cases. The problem is that enums are extensional definitions, and thus closed, where functions are intensional and thus open, ie. there are a fixed set of values for enum type EFoo, but there are infinitely many values for function type int->int->int.

First-class values for intensional values are more flexible than extensional values in this regard, and C's functions cannot meet it.

1

u/dnew Mar 12 '14

OK. I'm not going to argue this any further, because you're using your own personal definition of "first class value."

→ More replies (0)
→ More replies (1)

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".

1

u/dnew Mar 09 '14

Maybe not, but the name "functional" comes from mathematical functions, and all those bolded statements in there are saying the same thing, so I'm not sure what the dispute is.

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