Hacker News new | past | comments | ask | show | jobs | submit login
Why Why Functional Programming Matters Matters (2007) (raganwald.com)
141 points by olalonde on Dec 20, 2014 | hide | past | favorite | 34 comments



While reading, it made me think:

It’s important when approaching architecture—and probably software problems in general—that you do not start by reasoning in terms of the constructs of a particular language (e.g. classes and interfaces). The philosophy underlying this is: your range of potential conceptions becomes wider as abstraction increases; and, as you become more concrete you inevitably introduce auxiliary problems that result purely from the features of the particular language you are expressing with, which means you are prematurely diverting thought from, “what is the correct description of this thing” to, “what is the best wording for this description”.

Also:

Working at a higher level of abstraction has a lot in common with looking at a scene from far away, a mountain range for instance: the further away you get, the easier it becomes to change which mountain you are experiencing: you merely turn your head a quarter of an inch and now three new mountains have entered your consciousness. If you’re trying to decide which mountain to climb, this is an extraordinary benefit—but at the same time, if you are too far away, you can’t perceive the features of the mountain clearly enough for optimal decision making. A similar tradeoff is always present in working at one level of abstraction or another, and understanding these tradeoffs helps you figure out where to stand more effectively.


Better formatted version of the blog post:

http://raganwald.com/2014/12/20/why-why-functional-programmi...

The original paper by John Huges mentioned in the posting:

Internet Archive: https://web.archive.org/web/20070323095313/http://www.math.c...

PostScript, PDF and the BibTeX reference.



To me what makes functional programming matter and what differentiates it from OOP today is less its essential properties than the simple fact that it pushes you to think in terms of functions that process collections of objects rather than functions that act on a single one. This may look like a simple statement yet the implications are huge.

Now it doesn't reflect a property of FP as such, it only highlights one of the biggest shortcomings of OOP along mutability that we are slowly awakening to as a community.


As an additional exploration of these excellent ideas, I recommend the textbook How to Design Programs (HtDP):

https://en.wikipedia.org/wiki/How_to_Design_Programs

It's available online: http://htdp.org/


Is there a .pdf of the latest version? Couldn't find.


The latest version is a work in progress - for example, near the start of chapter VI we find "The rest of this chapter is under development. Use HtDP/1e in the meantime.". I wouldn't be surprised if there wasn't a PDF version until it was finished.


It's a good paper, but what it hints at (but doesn't really come out and say) is that in separating concerns, functional programming actually eliminates concerns from the programmer. This isn't really just a question of the language -- you can do FP in any language.

But by thinking about programming differently, we can eliminate concerns entirely. This is what garbage collection does, and it is what FP does.


No, you really can't do FP in any language.

"Please let’s not have a discussion about Turing Equivalence. Computer Science “Theory” tells us “there’s no such thing as more powerful.” Perhaps we share the belief that In theory, there’s no difference between theory and practice. But in practice, there is."

Programming paradigms are about how programs are written. If a problem can be solved in one language, it can be solved in every language, but that doesn't mean it can be solved in every paradigm in every language.


You make a claim here but don't back it up.

I think that a functional program, compiled to native code is STILL a functional program. You seem to not think that. Edit: If so, why?

Edit 2: Oh, maybe your point is that FP is statically typed?


Of course not. Functional program compiled to machine code becomes imperative program.

It's now all about global variables (memory, stack and registers) and side effects. How is that functional?

Well, you can think of it as functional, if you consider every machine instruction to be function (whole machine state->whole machine state), but it's not practical and nobody really thinks about machine code like that. And anyway - if you want to think about it like that - evey imperative program becomes functional :)


I am not entirely sure that ASM can be used directly for functional programming. Also I am not entirely sure that functional == declarative although that is a very powerful combination. As far as I am concerned functional programming centers around the guarantee that f(x) has the properties associated with a function, i.e. for every x, exactly one f(x) is correct. That's why your data structures must be immutable. That's why you need referential transparency, etc. But how you calculate f(x) really doesn't determine whether this is FP or not. There's certainly a lot of power that can come from a language that can compose or decompose functions for you. But I wouldn't use that as a litmus test for FP.

But I suspect (not entirely sure, but suspect) that if you apply sufficient discipline, and omit from the equation the global necessities of registers, you can probably create functions in assembly, and call them in a functional way. In fact I suspect if this were not possible, then FP languages would not be possible to create.

But FP in ASM sounds really really painful.


But it accesses the global variables in way that is functional.. I.e does not overwrite memory that other variables have references to and such. Anyway, it is -- to me -- a superficial difference, but I think it causes this disagreement about whether you can program functionally in some other language. According to my view, you can, according to your's you can't. It comes down to your definition of what 'functional' is.


>you can do FP in any language.

Not in my experience or that of my colleagues, no. I'm a Haskell user and writing a book for learning Haskell. I'm friends with several Scalaz developers including the creator and people that have worked on similar libraries for other languages. I've also attempted to use FP idioms outside of Haskell.

You can't take it with you. At best you'll learn to eschew a few bad habits, but that's not FP nor does it bring anywhere near the same benefits.


Nor in mine. I worked on some codebases in Java 6/7 with a team who yearned for functional programming. They used various libraries that tried to support a functional style - Guava for the moderates, FunctionalJava for the zealots, lambdaj for those who liked to be different.

None of them really worked well (for functional programming - Guava is excellent in other ways). Java just doesn't let you write the function-like classes concisely enough for it to be worth breaking code down as far as you need to to call it functional programming.

Plus, no higher-kinded types, so no functors. And what's functional programming without functors and their kin?


But here you are talking about functional style rather than functional programming on a definitional level. I do agree that Java is not well suited for FP. I think you can apply the base theory of FP to the language, but it may be little more than an academic exercise.

The problem with FP and Java is that FP and object encapsulation don't really go very well hand in hand. I.e. in Java you are encouraged to think about objects and their behavior, as encapsulating state. Encapsulated state in not a goal in any FP I have done -- rather the problem is solved by making state structures immutable.

But this doesn't mean you can't. It certainly won't look like Haskell though. It won't be idiomatic Java either. In fact it may be almost, though not entirely, unlike normal Java code.


Think about what following the most basic aspects of functional programming would mean in Java:

1. No private attributes (all state is transparent and immutable). 2. All methods that transform an object return a transformed copy. So instead of:

    rectangle.stretch_x(2.5);
you have:

    newRectangle = rectangle.stretched_x(2.5);
Even this very small move here moves you way outside Java as typically programmed. This means further that even at this level (the most basic level of FP), your program will:

1. Be unable to work with standard libraries without mixing paradigms

2. Be unable to be used in other projects because of the same problems.

Given that ABCL uses supertypes to allow round-trips between Java and Common Lisp, I am fairly sure that functors should be possible in Java, if not elegant.


You're conflating a couple of things here: encapsulating state, and mutability of state. Your examples are about mutability. But immutability is already standard practice in Java - standard enough that it's one of the items in Josh Bloch's 2001 book 'Effective Java', the bible of righteous Java programmers:

https://books.google.co.uk/books?id=ka2VUBqHiWkC&pg=PA73#v=o...

It's not usually pursued with the same rigour as in many functional languages, but it would be absolutely normal to see a Rectangle class with a stretchedX method which returns a new rectangle rather than mutates its receiver.

Now, you might argue that despite what Bloch, and every other good Java programmer, says, "Java as typically programmed" still trades mostly in mutable state. Since Java is actually widely used in the real world, it's typically incompetently programmed, and so this is probably true.

Nonetheless, i am confident that Java code written using immutable objects could both use and be used by other code. I say this because it's what i and my colleagues have been doing for years.

I had a go at functors in Java a while ago. You're certainly right that it's not elegant:

https://news.ycombinator.com/item?id=7898294


Consider than most software in actual use, changing the world and making millions is written in C/C++, those "benefits" must not be that many or that difficult to overcome...

And if the price we pay for this "worse is better" is buffer overflows and the ocassional crash and/or security exploit, that's hardly unsurmountable either. Life would be boring with perfectly perfoming programs anyway...


You sincerely believe that because "most software in actual use is in X" it means that language X must be effective?

> Life would be boring with perfectly perfoming programs anyway...

To me, it sounds like you are trying really hard to rationalize why the current state of the industry is okay. I don't blame you for this, it's horribly depressing to believe otherwise and work in our industry. However, if your first sentence is true, why do you feel the need to justify it with "But C/C++ having crashes and exploits can be exciting"?


>You sincerely believe that because "most software in actual use is in X" it means that language X must be effective?

I sincerely believe that "effective" in some platonic rhealm of ideas is BS.

I only measure effective in actual effectiveness. Has it worked in the industry? Were products written with it? How evolved? How many use them? Etc...

U"most software in actual use is in X" is a checkable observation, that shows fitness to the task and an evolutionary advantage to X.

What was the cause of the advantage I don't care much, but I'm 100% sure it's not "just marketing" (on the contrary). And even if it was because "most programmers are idiots and can't comprehend Y which is better" that would still be an advantage of X -- as it's more suited to the available programmers pool.

Just don't come to me with platonic ideals of what "should" be used instead, let your Y language win in the real world, and then we talk.

>However, if your first sentence is true, why do you feel the need to justify it with "But C/C++ having crashes and exploits can be exciting"?

Because what I'm trying to convey is having software with buffer exploits is better than no software (better than the vast amounts of non-written software for Y languages that we rely everyday in its X language version: from all Operating Systems to all browsers).


What is the part of FP in Haskell you can't do in lets say C++?

EDIT: or to phrase it better, what is missing or hard to do that you feel has the biggest influence (some things are possible, but just way more complicated)? I don't have enough FP experience myself to judge that.


How can you guarantee referential with C++? Can you do it in a practical way? I've heard of people using templates to do this, but is a solution like that really maintainable?

Can you write maintainable, sane, and performant C++ code that leverages immutable data structures, guarantees referential transparency, and eschews mutable state?


Now, note what I said that started this thread, that you can do FP in any language. I never said you could do it well or maintainably. For some languages (I am thinking of Java in particular, but C++ seems similar there), I can't imagine it being more than useful as an academic exercise.

Certainly there are languages which don't support FP approaches well. But lack of utility is not the same as impossibility. If nothing else the exercise ("How far can you take FP in Java?") will teach you all kinds of things.


> Now, note what I said that started this thread, that you can do FP in any language. I never said you could do it well or maintainably. For some languages (I am thinking of Java in particular, but C++ seems similar there), I can't imagine it being more than useful as an academic exercise.

> Certainly there are languages which don't support FP approaches well. But lack of utility is not the same as impossibility. If nothing else the exercise ("How far can you take FP in Java?") will teach you all kinds of things.

My mistake then. I agree that seeing how far you can take FP in Java is a useful exercise.


> you can do FP in any language

Depends on your definition of functional programming.


This is true. However....

The basic premise that you are operating with mathematical functions, which allow you to reason equationally can be done in any language.

Of course when you move from C to Perl you pick up a lot of power in what you can do functionally, and when you move from Perl to Common Lisp you pick up even more, and when you move to Scala or Haskell, you pick up even more from what I have seen.

But just as you can do object-oriented programming in C (a language really not designed for it), you can do functional programming in a lot of languages not really designed for it too.


> But just as you can do object-oriented programming in C (a language really not designed for it), you can do functional programming in a lot of languages not really designed for it too.

This statement is only true depending on what you mean by OOP. For instance see this post[0] implementing minimal OOP with scheme.

0: http://robots.thoughtbot.com/you-could-invent-objectoriented...


This is also true. OOP in Java is certainly not the same as OOP using CLOS, and not the same as Perl and Moose.

But there is a common thread through these. Namely with OOP, you are tying structure and behavior together so that behavior can encapsulate structure. OOP, like FP, isn't so much "a paradigm" as a "family of paradigms," one or more per language.


Related: Does anyone know of an html / epub / mobi link to the original paper (I could find only the pdf)?



Pure functional programs either don't work or are bug free. At a high level the entire app can be viewed as one continuous evaluation, which is kind of beautiful. It could transfer to an FPGA without needing a von nuemann simulation.


FP isn't a silver bullet. A statically-typed function language with a strong type system will keep some classes of issues away. It will not, however, prevent logic errors or infinite loops or resource leaking.


(2007)




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: