Comments

(newest first)

  • Mel pullen | Sun, 06 Dec 2015 12:19:39 UTC

    I come from a hardware background, and also have problems with this pure software view of concurrency. With limited experience of co-design I have come to see there is duality between functions in hardware and software.
    
    In my duality view, a gate is a decision and a counter is a loop. Am I supposed to do without registers in case I store a side effect?
    
    
  • Gabriel Claramunt | Tue, 29 Sep 2015 04:23:18 UTC

    Yeah, a lazy Lang with GC is a very bad choice for an airplane control system. Heck, probably Java using only stack allocation will be a better option, but I'll probably stick with Ada :)
  • Naise Dikotomie | Sun, 26 Jul 2015 05:11:45 UTC

    @Jesse the one coded in Ada or a formally verifiable subset of C.
  • David Clark | Wed, 24 Jun 2015 13:00:02 UTC

    I am a language designer and your accolades for functional programming are ridiculous (I was thinking of the anti-spell from Harry Potter).
    
    The language/database system I am creating has been written in C. It has many hundreds of "purely functional" functions (the same input always returns the same values). I have hundreds/thousands of functions that change only the object structure that is passed to it (OOPS anyone!). I have other functions that don't fall into either of these categories. Does this mean that C is functional? Object oriented? Partly functional? If I want lazy execution (I have a byte code interpreter in my program), I can delay any expression or function I want to any time I want it executed. Funny thing is, I appreciate my programs executing when they are told so, so I rarely invoke my right to lazy evaluation (values tend to take a lot less space than functions).
    
    I can implement any level of "undo" I want, but I don't need that capability so it isn't included in my project yet (or never). I don't actually need to get rid of all the intermediate results because I have "varying variables" unlike "immutable variables" in Haskell. I can "pass" function pointers to other functions (higher order functions) but I only do so in a few special cases. I have implemented my own automatic memory manager (something like a GC but no global waits, pointer chasing or random pauses). I can't think of anything that can be done in Haskell that I can't do in just plain old C. Is C the "God" language? Did I also say I have created automatic multi core, concurrent execution with code that is exactly like single user code without any user level locks or any concurrency annotations in the programming language. I guess I don't need Haskell's immutability for concurrency after all.
    
    All my global state is read only and available to all threads at all times. (Yes I mean in C. Once the threading starts the global data can't be changed because I say so.) The independent servers that run on concurrent threads have their own local memory managers and can change local state without any locks at all. Globally available functions have no side effects. All global resources have critical sections that make their code also mutable without any problems. My design minimizes the use of global resources or queues their requests and does the work asynchronously. Data can be passed from server to server using a message queue that can deliver millions of messages per second but most of the work is done concurrently at the local level.
    
    I challenge your "real world experience" and your thesis that Mathematics should be the language that programs computers. Haskell was first made available in 1992, over 23 years ago, and according to Wikipeda, over 5,400 libraries and tools are available for Haskell programming. What language would be called a success that has more than 5,000 libraries of functions and not a single major program that was completely created in it? The only answer I know of is Haskell that was made and promoted by a group of publicly paid professors with next to no "real world experience" between them.
    
    Purely functional programming is a small subset of the code that can be created in a language like C. Haskell should be compared to niche languages like APL or SmallTalk rather than real world languages like C, C++, Java, C# etc. If you are an academic and want to print a Fibonacci sequence, Haskell was made just for you.
    
    I have completed over 1,000 programming projects (big and small) for over 65 different companies spanning 35 years. I have programmed in at least 20 languages for over 10,000 lines of code each and written 100,000's of lines of C and assembler. I designed and coded a language/database that sold over 30,000 copies in 1987 alone.
  • Jesse | Sun, 16 Nov 2014 05:47:05 UTC

    To anyone who believes that "mostly functional" is good enough and that purity is overrated:
    
    Please pick your preferred airplane that you will ride in: the one that has all its control systems written as multi-threaded Java, or the one that is written in multi-threaded Haskell. 
  • Alex liddell | Mon, 26 May 2014 00:44:51 UTC

    I think many ideas can be solved with proper research and understanding on almost any subject your choose from life, and improve how articles can react to social impacts
  • George | Tue, 13 May 2014 22:35:58 UTC

    It's going to be hard to get programmers to switch to purely functional programming languages since this implies throwing out everything they learned in their algorithms course. Yes, there is "Purely Functional Data Structures" by Osaki but that doesn't mention how to do graph algorithms. Perhaps more importantly purely functional algorithms generally don't compete in asymptotic performance, please correct me if I am wrong. Finally, anybody who moves to a purely functional programming language is not going to want to rewrite all the existing libraries they need to get the functionality their application requires so won't using those libraries introduce imperative programming back into their purely functional code? Purely functional programming is very attractive but let's not minimize the barriers to using it in a commercial product.
  • Richard Hein | Fri, 09 May 2014 17:31:34 UTC

    @Bernd:  You're missing the point of the first example, it's not about whether the calculation gives the right results in the end, it's about when the functions are evaluated - the behavior is different than expected and with just a simple example; more complex examples compound various issues the paper discusses.  The point is, if you try to be "mostly pure" with the first example, and even remove the Console.Writes from it, you will still get a side-effect that results in interleaving the functions instead of performing the filtering in the order written.  Without the console output, the functions are pure, but yet things are wrong, because "mostly pure" doesn't actually work.
  • Bernd | Wed, 07 May 2014 20:44:56 UTC

    Uh, I am not sure how that paper should help me.
    
    Starting by the first example: of course I need to know when a method will be evaluated to put side effects in there. But if I don't care about debug output (or actually love the fact that I see when something was executed!) the resulting calculation is still correct, even when not using pure functional programs.
    
    So this paper spends 3 ornate paragraphs to re-state an advice with no further proof in the rest of the paper. I would strongly recommend to rename or rescope the paper in "pitfalls of functional programming for the imperial soldier".
    
    Greetings
    Bernd
    
    PS How many EAL 7 systems do you use?
  • David Barbour | Sat, 03 May 2014 20:03:08 UTC

    There is a golden middle: object capability model, especially if we eliminate 'new' as an ambient authority (and thus require all new objects be provided through factory or allocator capabilities).
  • Eric | Thu, 01 May 2014 20:03:30 UTC

    This pure-functional debate has been going on since I was a CS grad student in 1978.  It is reminiscent of Steve Martin's old stand-up line:
    
    "How to make a million dollars, AND NEVER PAY TAXES."
    "First, make a million dollars..."
    
  • Paul Cantrell | Wed, 30 Apr 2014 16:14:52 UTC

    Note to site admin: you REALLY need to support non-ascii characters in comments. Your site just stripped half the punctuation in my comment. We want our m-dashes!
  • Paul Cantrell | Wed, 30 Apr 2014 16:13:05 UTC

    A fine read on the advantages of strict isolation of effects  but it pulls a bait and switch with its click-grabbing thesis that mostly functional programming does not work. What the article actually demonstrates is that mostly functional programming does not give you concurrency for free.
    
    This may explain the negative reactions.
    
    One could write a similar bait-and-switch article which shows the dangers of mixing managed memory with pointers, demonstrates the advantages of fundamentalist garbage collection  which are manifold  but then concludes incorrectly that mostly managed memory does not work. Anyone who has used ARC on iOS knows perfectly well that it works. It just has drawbacks.
    
    In both cases  functional programming and memory management  a mixed approach places new cognitive burdens on the programmer, and may serve to hide dangerous cases. In both cases, gaining some of the convenience of the higher-level approach while maintaining a lower overhead and deterministic behavior may well be worth the extra burden on the programmer. In both cases, the middle may be the right tradeoff in some situations. In both cases, the fundamentalist declaration that it does not work is ridiculous, and muddies the waters.
    
    The articles opening sentence suggests a better, more defensible thesis: silver bullets dont work.
  • Ruud H.G.van Tol | Wed, 30 Apr 2014 13:21:34 UTC

    Hmm, my comment somehow got marked as spam, and now I regret not having copied it, before clicking [Post].
  • Daniel | Tue, 29 Apr 2014 22:05:55 UTC

    "How do you prove that your code 'works' then?"    Just like the rest of our multi-billion dollar industry does: QA.
    
    And unfortunately proving that a snippet of code works as designed does not protect from bad design or bad business logic implementation, making incremental benefits from all the elaborate academia approved obscure languages dubiously valuable at best.
  • Derf Skren | Tue, 29 Apr 2014 00:02:13 UTC

    "The benefit is... DETERMINISM."
    
    Until you start introducing any form of useful IO - that's what the article is saying. Like any imperative language programmer, it's fairly easy to 'prove' that your routine to load a text file into a string 'works', the problem is when you run your code in the real world and the file doesn't exist, is too big for memory, or whatever.
    
    How do you prove that your code 'works' then?
  • Arturo Hernandez | Mon, 28 Apr 2014 23:42:26 UTC

    I agree with the points made by Michael Schuerig. There is an extra nuance I'd like to comment on. We may be witnessing a transition in programming practice. Changes like these take a long time, and a "Mostly Functional" language may be a good stepping stone in the right direction. The marketing may still be off, rather that advertise these "Mostly Functional" as the solution. They should be advertised as a good step. I'm not sure if it would be an effective campaign. I suppose the even the path to purity may be impure.
  • Joshua Scholar | Mon, 28 Apr 2014 22:32:42 UTC

    I saw a talk where Microsoft has some experimental examples (based on an extension of Z3 I think) designed to prove correctness of individual routines - obviously the routines had to use very limited semantics, but they were written in a much less restricted language like C#.
    
    So perhaps it's possible to have provably correct subsystems where the prover just fails if that subsystem uses anything but a very limited set of features.
  • Daniel | Mon, 28 Apr 2014 20:07:36 UTC

    "Unfortunately, just as "mostly secure" does not work"  :   it does.    It is all we mostly have.    It just got to be hard enough to break to not make it worth the effort.
    
    If mostly functional features help solve a concrete problem in code, it is mostly useful, and there is no need to suffer through self-imposed purity in the rest of a project, where nobody cares.
    
    
  • Michael Schuerig | Mon, 28 Apr 2014 13:53:23 UTC

    I *think* that Erik and his critics are talking past each other. I also think that it is mostly Erik's fault for he doesn't make it explicit enough what the advantages of functional programming are supposed to be.
    
    He starts the conclusion with this sentence:
    
    "The idea of 'mostly functional programming' is unfeasible. It is impossible to make imperative programming languages safer by only partially removing implicit side effects."
    
    I take this to be the core of what Erik is arguing for: If you want (provably) safer programs, you need programming languages with specific properties, such as a type system that keeps effects in check. Mostly-functional languages don't have that property and thus do not qualify for this particular goal.
    
    I don't see an argument anywhere that it would be bad in any way to program in an informal functional style where it fits. I read previous comments as asserting just that and it matches my own experience.
    
    However, being only informally functional doesn't give you provable properties and most likely the compiler isn't able to get any leverage out of it.
  • Joshua Scholar | Mon, 28 Apr 2014 07:18:56 UTC

    Though I should admit that the sorts of programming I've been interested in so far don't include Haskell and I certainly don't have access to massively parallel systems with huge datasets that some people in this thread have said can make use of the optimizations that that sort of programming allows.
    
    I have found little bits of higher order functional programming useful as a more reliable way of coding some algorithms, and I'm definitely interested in finding out how useful lazy evaluation, and stranger variants like curry with it's "needed narrowing" and (in one implementation) multiple automatic search strategies turns out to be in practice.  Same with other other kinds of programming that I haven't had a chance to become familiar with, such as constraint handling rules, or searches on satisfiability modulo theories.
  • Joshua Scholar | Mon, 28 Apr 2014 07:05:40 UTC

    My own take on this is that you since you can't have a single dialect that's ideal for every possible programming problem the answer is to have a language that natively supports having different dialects for different purposes and mixing computations from these different dialects easily.
    
    Actually, I'm working on a language like that.  
    
    One main feature is to expose maximum support for metaprogramming, parsing, code walking etc. instead of the usual attempt to limit features like these to be safer.  
    
    Systems that allow you to write domain specific languages are becoming popular, but I'm more interested in a system that allows you to embed multiple general purpose languages.
  • Kyle Dewey | Mon, 28 Apr 2014 07:05:26 UTC

    While the author has demonstrated certain interoperability issues between pure and impure features, it doesn't seem to me that any of these demand everything to be completely pure.  Most of the examples are specific to lazy evaluation, and not pure functional programming as a whole.  The example with Ha() seems very contrived to me, and making this pure doesn't fix the fact that common subexpression elimination can't be performed; it just makes it more obvious that it cannot be performed.  With the last example with object creation, this can viewed as pure if we see a constructor as taking implicit parameters specifying hash codes, memory addresses, and the like.
  • Tom | Mon, 28 Apr 2014 05:41:01 UTC

    Mostly functional programming is widespread in parallel and distributed programming, and it works very well for that purpose. I suspect mostly functional programming doesn't work for achieving security and correctness because even pure functional programming fails to achieve those objectives too: in practice, Haskell programs turn out to be as messy and buggy as Java programs.
  • Lonny Eachus | Mon, 28 Apr 2014 03:57:34 UTC

    I agree with the other comments which say the author does not seem to have demonstrated his point.
    
    Not only does he dismiss out-of-hand the idea of carefully crafting code to avoid side-effects, he demonstrates quite clearly that so-called "pure" functional languages are not pure at all and also have to be treated (at least in some cases) with care to avoid side effects, which is a direct contradiction of what appears to be his central point.
    
    If "pure" functional languages also have to be crafted carefully to avoid side effects, which is what he appears to be demonstrating (and advocating), then the only genuine advantage of the functional languages is that they make it "easier" to code "properly", without said side effects.
    
    I find this argument very far from convincing. Yes, the utility of "pure" functional languages is evident. But by his own admission it is not a panacea; it is merely a baby step in the right direction, and that baby step comes at the high cost of woefully abstract and difficult-to-follow syntax.
    
  • John | Mon, 28 Apr 2014 00:40:03 UTC

    To those arguing that enforcing purity is somehow 'totalitarian', and argue that we should be more balanced, hear me out:
    
    This is a wonderful article about functional purity, but, like nearly every other article on purity, doesn't explicitly mention the most important benefit.  This benefit is the awesome reward you get for depriving yourself of the convenience of mutable state.  The benefit is... DETERMINISM.
    
    When you code 'in the real world', and you're obliged to write unit tests, you'd hope that your tests prove something, right?  Well they don't.  They 'suggest' some fact is true about your function, but they don't 'prove' it.
    
    If you unit test an impure function with a given input, e.g. assert (f(5)==6), this result may hold for all of your tests, but as soon as you deploy it, f(5) might evaluate to 7 in production, and crash everything - or provide your clients with incorrect and damaging data.
    
    If you unit test the equivalent pure function, and (f(5)==6) happens in tests, then f(5) *will* happen in production.  This is why functional programmers make such a big fuss about purity.  
    
    Does the 'totalitarian' argument still hold?  Only if you feel that we should take a balanced stance between functions returning the correct answer, and functions returning an incorrect answer.
    
  • Bruno Jouhier | Sun, 27 Apr 2014 22:42:29 UTC

    was about -> what about. Sorry, I posted too quickly.
    
    My point is that your post title should be changed: "does not work" -> "breaks static typing".
    
  • Roman Sokolovskiy | Sun, 27 Apr 2014 22:41:54 UTC

    > Roman, 'atomic' here is the name of the function.
    > atomic :: STM a -> IO a
    
    Yes, I see. That function is named 'atomically' in original Haskell STM API.
    
    http://hackage.haskell.org/package/stm-2.1.1.2/docs/Control-Monad-STM.html
  • Bruno Jouhier | Sun, 27 Apr 2014 22:18:30 UTC

    I think I get most of your point in the context of a statically typed language (like Haskell or C#): it is important to have the side effects surface in the types; monads is the right way to do it and you'll get leaks if you start to compromise.
    
    But was about dynamically typed languages? Isn't "mostly functional" sufficient in this context? What would be the improvement path for these languages? (without introducing static typing)  
  • Matt Slaybaugh | Sun, 27 Apr 2014 22:14:29 UTC

    Roman, 'atomic' here is the name of the function.
  • Roman Sokolovskiy | Sun, 27 Apr 2014 21:57:27 UTC

    First of all, thank you for an amazing reading!
    
    > Finally, the function atomic injects the transaction monad into the general I/O monad.
    Did you replace 'atomically' with 'atomic' for a reason?
  • Topi Mäenpää | Sun, 27 Apr 2014 20:59:23 UTC

    Theory meets practice
    
    Pure functional programming may solve many prominent problems in parallel code, but it certainly isn't a silver bullet for all applications. Pure this or pure that is sure to hit a wall sooner or later.
    
    When I first learned about Haskell, I was quite amused about a quicksort algorithm example that was intended to highlight how powerful the language is. While the algorithm could be written in about three lines of code, its performance sucked. Hard. To me, this highlights a major problem in a purist approach: the new and nifty technique solves a problem (in this case running code efficiently in parallel), so it must be applied everywhere and reintroduce problems that were solved long time ago. Single-threaded algorithm performance on bare metal is still (and will be) important.
    
    I personally work with real-time machine vision applications and write a lot of parallel code to embedded environments with heterogeneous hardware. So far, I have found the semi-functional approach a really good one. It may not be theoretically right, but yields best performance in practice. Parallelism can be implemented in imperative languages. It may be harder, but heck, anything you can do with Haskell can also be done in assembler.
    
    I cannot create an efficient quicksort algorithm in Haskell because I'm not allowed to modify data in place. The same purity prevents me from reusing a 12 Mb image buffer even if I could write to it. And I'm not allowed to cache processing results internally by thread because that would create hidden state and thus break the rules. To me, such rules are just insanity and performance hits no amount of parallelism can compensate. In my applications, things like cache hit ratio are a big deal even though the number of processing units may be relatively large.
    
    I'm not saying functional programming doesn't have its merits. It does. But they certainly do not apply everywhere.
  • Benjohn | Sun, 27 Apr 2014 20:17:47 UTC

    There is useful information here about functional programming, for which I thank the author. However, I find the author's suggestion that there is no place for partly functional languages (such as Lisp variants, for example) to be nonsense.
    
    I am certain there are advantages to entering the pure functional domain, and it is beneficial in certain situations. Perhaps in the future we'll feel it is a good setting well suited to most problems. That's hardly the case at the moment, though.
    
    As the author is making, to my mind, unsupported claims, I'll reply with one of my own. 
    
    Totalitarian orthodoxies rarely succeed, in politics (fascism / communism), management (agile) & economics (neo-liberal or Marxist), or in design (modernism, flat design, etc), science or software. The claim "you didn't see the benefits because you didn't take it far enough".
    
    This argument for pure functional programming is totalitarian: that you won't see the real advantages until you're completely functional. Such claims should be treaded too exactly the level of suspicion that they currently are.
  • Stilgar | Sun, 27 Apr 2014 18:14:38 UTC

    I really don't understand how the title relates to the content of the article. I have written code for years in an imperative way for years and then after C# 3.0 I have developed a good amount of semi-functional code (some of it multithreaded) and I can definitely say that the semi-functional code is easier to read and reason about and has less bugs. By this metric semi-functional programming surely works and the comparison with semi-security is unfair. Maybe pure functional approach is even better, I don't know but unless you claim that LINQ and TPL have made C# development worse I don't see how you can claim that semi-functional doesn't work. If it makes code better it surely works, doesn't it?
Leave this field empty

Post a Comment:

(Required)
(Required)
(Required - 4,000 character limit - HTML syntax is not allowed and will be removed)