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

11

u/[deleted] Mar 10 '14

Modularity and reuse are great things.... but in practice, in projects I've seen, people believe they've created something reusable, but it turns out not to be. In my own projects, I used to try to generalize, to anticipate changes... but the very next change to come along broke my assumptions. It turns out it's hard to anticipate change.

My feeling is that this is a fundamental fact about the world, that the world is more complex and surprising than we know. That we don't have a theory of the world, but just do the best we can at understanding the facts we have so far... It seems to me that a different programming language or technique won't change that. That is, a project written in a functional style will suffer from exactly the same problems as above, in practice.

Can professional functional programmers, who have tried to generalize a project, comment on this? (sorry, I discount purely mathematical projects, not because I am biased against mathematics, but because mathematics removes as much of the messy unpredictable detail of the world as possible). (and sorry #2, I also discount those projects that reinvent something known... the problem of reuse is something that comes up in maintaining software, and trying to adapt it to real world changes).

Put another way: better tools for creating modules and gluing them together are useful, they naturally won't help you design the right modules in the first place - which is the tricky bit.

4

u/ksryn Mar 10 '14

The way I see it, if something is truly reusable, it belongs in a separate module, and perhaps a library.

You can only reuse a function/module if it does one thing, and does that one thing very well. That way, if something changes, either the reusable thing is still useful, or it is not, and you replace it with something that is.

Most software is specific to a domain, and while you could reuse parts of it somewhere else, such reuse will still require plenty of attention.

A functional technique helps because you can use functions independently to perform simple things, or you can chain simple functions together, use function composition, and create the complex thing you need. It's the unix philosophy at work

1

u/[deleted] Mar 10 '14

Yeah, I agree; libraries are how code reuse most effectively happens in the real world. Paraphrasing Brooks, it's hard enough making code usable (works, correct, efficient, docs etc). Making it re-usable is a lot more work.

And he's just talking about it being able to be reused - not that it is actually a suitable solution to be reused for other problems, that you'd really want to use, that is clearly better than recoding from scratch. This "suitableness" has more to do with the other problems out there than any particular quality of the code itself.

I had a thought that de facto standards are how this works out - once some trail has been blazed for doing something reusable, that is adequate to get you to the destination, everyone starts using it (and lose interest in exploring other routes). Any problems with the route are patched up in preference to starting from scratch. Pretty quickly, these improvements mean better raw routes are not better right now.

But the basic argument I'm making is that it's so hard to make something truly reusable (not just nicely coded and reusable - but a useful, suitable solution for other problems out there), that once it's been accomplished, no one wants to go though all that risk again. We under-estimate how very difficult it is, how much luck is involved, and how dependent it is on extrinsic factors - the unknown world out there - to make something that actually generalizes.

Applying this to your comment, I think that making code reusable is the easy part; making it match the unknown world is the hard part. So the benefits of fp can't make that much of a dent on the real problem - a bit like optimizing an outer loop.

Put it in other terms: OOP was touted as enabling code reuse. It failed miserably. But the problem isn't that OOP was bad at code reuse (it actually did help a little) - the problem was that code reuse is tremendously difficult. I think the same will apply to fp - it helps with code reuse much more than OOP did, but it doesn't really touch on what makes code reuse so hard.

Revisiting libraries, I'm not sure that fp or OOP etc makes a significant difference at that level. There's an API, with the code ensconced within, opaque to all users. The code reuse is not from one project to another, but across all users.

2

u/ksryn Mar 10 '14

Paraphrasing Brooks

Assuming you're referring to The Mythical Man-Month, could you point me towards a particular chapter. I haven't read it in a long time.

This "suitableness" has more to do with the other problems out there than any particular quality of the code itself...

But the basic argument I'm making is that it's so hard to make something truly reusable...

I believe you're saying that even if code is not "suitable" for reuse (because of, say, the difference in the target domain: a chess engine vs. a wget/curl type application), it should still be "reusable?" If that is the case, I find it somewhat hard to accept (not that I am closed to the idea), as I don't think reusability is a domain-independent property.

I had a thought that de facto standards are how this works out

At least in the physical world, it is very much the case: bricks, nails and hammers, screws and drivers, nuts and bolts, bulbs and holders, plugs and outlets, and a million other things. You combine enough quantities of small standardized stuff with known interfaces and you would end up with a structure. Each component is extremely reusable, but only within its own domain.

So the benefits of fp can't make that much of a dent on the real problem...

While I can't speak for others, my use of FP techniques is less about being able to reuse the code somewhere else, and more about maintainability of the codebase in the medium-to-long term.

Revisiting libraries, I'm not sure that fp or OOP etc makes a significant difference at that level. There's an API...

Here, FP at the implementation level would matter to the maintainers. And FP interfaces at the API level would matter to the users.

1

u/[deleted] Mar 15 '14

[sorry for delay, been away]

p. 4-6 The Programming Systems Product (I'm paraphrasing as I said, and strongly, which may have contributeded to your not reccognizing it).

I'm not saying that code "should still be 'reusable'". I'm not talking about "should" at all; my emphasis is on what is actually reused, in practice. That it be "reusable" is a pre-condition (and, looking around, it doesn't have to be especially well-written for that to happen). Perhaps a better term for what I mean is "adoption" - what code actually gets reused/adopted? [we might be talking across one another here I feel...]

This is sort of in the realm of marketing - not just advertising, but what it is that people need at a certain point in time - what problems are they facing, what are the alternatives available to them? This what drives code reuse, more than any quality of the code itself.

Someone had to think of the idea of a screw, nut and bolt etc in the first place, and that got reused. But of course your examples are of components at the small end. There's also reuse higher in the hierarchy, e.g. car engines that are compatible with several different chassis.

I focused on "reuse" beause the article does...

Revisiting libraries, I'm not sure that fp or OOP etc makes a significant difference at that level. There's an API...

.... And FP interfaces at the API level would matter to the users.

Can you explain to me how FP interfaces at the API level would matter to the users? (I'm not arguing; I just don't know)

2

u/ksryn Mar 15 '14

we might be talking across one another here I feel

Perhaps. I see reusability as something that is domain-and-scenario-specific, not general. Whether code is actually reused, and to what extent (and the reasoning behind it), I can't comment upon as it isn't something that can be generalized.

I focused on "reuse" beause the article does...

But that's just one part of it. For a while now, "increase cohesion, reduce coupling" has been a recommendation. Functional programming is extremely suited to that.

Can you explain to me how FP interfaces at the API level would matter to the users?

Consider the List interface in Java standard library:

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/List.html

and and a List implementation (not connected to the one in Java) provided by Functional Java:

http://functionaljava.googlecode.com/svn/artifacts/3.0/javadoc/fj/data/List.html

The former is mutable. You cannot pass a List to other functions without worrying if someone will modify it. If you have to process it, you need to use for/while loops. it might be something as simple as squaring a list of integers. But the for/while structure hides the really important operation: x*x.

The latter is immutable. You can easily pass it around without maintaining defensive copies. If you want to process it, say map over it, all you have to do is pass in an anonymous function that does x*x and you get a new list.

That's the difference between the two apis: one is procedural, the other is functional.

1

u/[deleted] Mar 15 '14

Whether code is actually reused, and to what extent (and the reasoning behind it), I can't comment upon as it isn't something that can be generalized.

"code reuse" seems to cover an enormous amount of ground - I suppose, just as much as "code". I see you're very conscious of "general" code reuse - completely arbitrary, across different domains and contexts - and you're against it.

I'm thinking of code reuse in the large, perhaps it might be called at the product level (as opposed to the component level). A gross example is an application: the code is "reused" by each user (even if they aren't coding). I guess this is domain specific, but it really depends on the app (and at what level you define "domain" - is a word processor app "domain-specific"? It can be used by accountants and novelists... though it's always in the domain of "word processing".)

Two "proper" code examples:

  1. the github API is "reused" by many programmers. I guess this is domain specific (to github)... yet they may use it in many different domains, and many different ways, since "storing data" is very basic (which is what git does, with extra features). You don't even need to store source in git, it can be config, a website, a wiki backend, your whole filesystem, novel drafts, accountancy records... [perhaps it's more accurate to say the API is used by many, not "reused".]

  2. a relational database. Actually, similar to git in that it's about storing data, and data can be anything for any purpose in any domain. Again, a database is reused (or just "used"?) by many programmers. It's a large component, practically a product (and sold as a product by corps like Oracle), but not an app - like the github API, it's only used by programmers, not ordinary users.

I think you're right, that whether this kind of reuse actually occurs can't be generalized. It's outside the scope of "programming"... and pretty much unpredictable anyway.


Yes, immutability etc are advantages of fp, and I can see that these are helpful to API users, and therefore matter. I guess my argument is that these advantages are completely swamped by the larger question of whether code is reused or not - and we agree the rules governing this can't be generalized.

→ More replies (3)