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.
"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.
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 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.
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:
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:
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.
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.
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.
But by thinking about programming differently, we can eliminate concerns entirely. This is what garbage collection does, and it is what FP does.