Hi,
Rusky wrote:Brendan wrote:Maybe the reason I'm missing the point is because there really is no point.
First, let me apologise. I should've worded that more accurately.
The individual ideas and concepts behind functional programming may be useful in some situations, but imperative programmers have been using most of those ideas and concepts in those situations "by accident" for half a century. It's the restrictions (and changing the way programmers need to think) that aren't useful. The benefits of a new technology need to outweigh the cost of changing from old technology (retooling, retraining, etc); and the benefits of functional programming (negligible) fail to outweigh the disadvantages (severe).
The world is a big place. Just because a minority are stupid enough to use a completely crappy language (e.g. Perl) doesn't mean that the language is good. Functional programming has existed for a very long time, and imperative programming has dominated (and continues to dominate) for all of that time.
The "structured programming" advantage looks like wishful thinking to me. For functional and imperative programming a bad programmer can easily have functions scattered all over the place with no sane structure at all (and a good programmer can make well structured code). If anything, both approaches are equally inferior to object oriented programming where the programmer is encouraged (forced?) to structure their software as classes and methods.
The "shorter and easier to understand" advantage is dodgy. For any style of programming, you can create a language that is shorter and harder to understand (make it more terse), or shorter and harder to learn (shift more functionality into the language and standard libraries).
For function pointers (or "first class functions" if you like marketing hype) I think C actually gets this right - it's there and it works, but it's ugly enough to prevent morons from using them all over the place and making it hard for anyone to follow the logic of the program. Assembly makes using function pointers far too easy (and far too flexible). In both these case (C and assembly) it's relatively rare to want to use function pointers as arguments to other functions because usually there's an simpler (easier to understand and maintain) way of achieving the same result. Functional programming makes the "easier to understand and maintain" ways harder to use, and therefore the "harder to follow the logic" techniques aren't so rare.
Long and boring story about a pair of assholes that inflicted Lisp on some poor unsuspecting maintenance programmer who probably had to rewrite the entire thing in a language more people are familiar with to prevent the company from going bankrupt after the original programmers left.
Didn't read it (too long). I did see that "novelty" was the first advantage, even though it's a massive disadvantage. Instead of reading about the supposed benefits of Haskell (which is a language that even function programming advocates say is terse, hard to learn and full of "academia"; typically before suggesting Clojure) I found
the benefits of drinking urine. Without caring about the disadvantages of drinking urine, it's hard to understand why large companies aren't making millions of dollars selling "nice cool carbonated urine in a can".
An excessively long and boring pile of waffle that failed to make a clear and concise point. I only skimmed through it (I lost interest near the start of the author's autobiography). The only advantages I saw were advocating for interactive programming, not Lisp or functional programming. I must admit, I like the idea of interactive programming, it's just hard to do for languages that aren't slow/interpreted.
I took a quick look at those 3 pages. The "Advantages Of Functional Programming" page seemed to contain (supposed) advantages of function programming so I ignored the other 2.
I'll run through all of their "bullet points" as quickly and concisely as I can, in the same order:
- "nice, protected environment" just like Commodore 64 BASIC
- "encourages safe ways of programming" just like Commodore 64 BASIC
- "tend to be more terse" which is how an advocate makes "unmaintainable crap" sound good
- "encourages quick prototyping" just like Commodore 64 BASIC
- "modular in the dimension of functionality" just like Commodore 64 BASIC
- "modular in the dimension of functionality" just like Commodore 64 BASIC
- "Generic routines with easy syntax". Was going to put "just like Commodore 64 BASIC" for this too, but maybe in academic-waffle-speak-land the term "generic routines" actually means something. I don't know. I googled for "generic routines wikipedia" just in case, and got a page about boring old linked lists.
- "ability to have your cake and eat it". Sigh. In this scenario, if I wanted a history of different states I would've implemented it; and if I don't want a history of states I don't want the extra overhead (memory consumption) forced on me.
- "Many housekeeping tasks made for you" is the same as "many important decisions made incorrectly for you". It's the same reason I prefer assembly and C to languages like Python.
- "Safe multi-threading". What they really mean is "safe until you have to do something an outside observer/s can see, where it becomes unpredictable, non-deterministic and unusable".
- "Referential transparency makes it easier to reason about subprograms". Agreed; but the downside is that it's impossible to write useful software with referential transparency alone. What they really mean is "makes it painful to write real software by trying to ram referential transparency down your throat".
- "Referential transparency makes it easier to reason about subprograms". Agreed, but you can do referential transparency in any language (even accidentally) when it's needed, and it's not an advantage of functional programming alone
- "Referential transparency makes testing easier". Agreed, but so would banning branches (if, for, while, etc).
I skimmed over it. The conclusion seems to be saying lazy evaluation is good. I'd agree with that, but I'd add that forcing programmers to rely on it is bad, and that most decent C compilers will effectively do it anyway by reordering the code where possible/beneficial.
Rusky wrote:I found all these by googling "functional programming" and "why functional programming," though I'd encountered most of them before.
Yep. I was hoping for a clear and concise explanation of the differences that actually does make functional programming sound better than "change for the sake of change, marketing hype and meaningless jargon"; and you felt the need to bombard me with links to around 50 pages of biased opinion. I was thinking of responding in kind; but I guess you can
google for "functional programming criticisms" yourself.
Rusky wrote:As I've said before:
Rusky wrote:Functional programming is different from imperative programming in the way C is different from assembly:
You can do all the same things in C as in assembly, and most of the time there's a direct translation, although not always if you stick to "pure C" without inline assembly (and the naive translation is probably inefficient), but C is more abstracted from the hardware so it's a better tool for some things.
You can do all the same things in functional programming as in imperative programming, and most of the time there's a direct translation, although not always if you stick to "pure functional programming" without IO or FRP (and the naive translation is probably inefficient), but functional programming is more abstracted from the hardware so it's a better tool for some things.
We all know how silly it is to use machine/assembly language for everything. Functional programming is just another "level" above C, et. al. The "blub paradox" described in
the Paul Graham article above describes why you might not appreciate this without actually trying functional programming.
Higher level imperative languages are higher level than lower lower level imperative languages, in the same way that big apples are bigger than small apples. Higher level functional languages are higher level than lower lower level functional languages, in the same way that big oranges are bigger than small oranges. Now tell me what is bigger - apples or oranges?
Surely big apples are bigger than small oranges, and big oranges are bigger than small apples. Surely higher level imperative languages are higher level than low level functional languages, and higher level functional languages are higher level than lower level imperative languages.
Of course if nobody sold any small oranges, then you might make the mistake of thinking that the average apple is smaller than the average orange. In the same way, if there were no low level functional programming languages you might make the mistake of thinking that the average functional language is higher level than the average imperative language.
Cheers,
Brendan