5 ms·
Biggest disadvantage for me comes when trying to implement a complex algorithm where the paper uses pseudocode that's imperative (which is almost always). In th
by surement 9y ago
Biggest disadvantage for me comes when trying to implement a complex algorithm where the paper uses pseudocode that's imperative (which is almost always). In the best case you can implement parts of it functionally but when it comes time to put these together you will likely use some kind of loop, but that's not possible in "purely" functional languages.
Otherwise -- and in particular when coming up with algorithms -- I find it preferable for languages to be efficient with functional idioms (recursion, map, filter, etc.).
Edit: I understand that anything's possible in a functional language that's possible in other languages. My point is that conversion from imperative to functional can be complex and might not be worth the trouble, and that doing it purely functionally might defeat the purpose: it will be nearly impossible to read or incredibly inefficient.
- eropple 9y agoIf what you care about is "everything is a beautifully curried function that actually doesn't do anything", the concern about loops is definitely a thing (but any loop can be turned into a recursive function so long as your stack is big enough, even if they're usually hideous). But pretty much everybody I've ever worked with considers functional purity in the logic layer to be "functional programming" at its most useful (Gary Berhardt's functional-core, imperative-shell talk is a good one). Is it easier to write with a loop? Then use a loop! If that loop is contained in a pure function that has no side effects and encapsulates something that isn't the most beautiful crystalline code formation anybody ever did see, nobody cares. It's the mindset, not the implementation, that actually makes functional programming so valuable a tool.
- RBerenguel 9y agoFunctional API, efficient implementation. It's always a good rule of thumb
- surement 9y ago> Is it easier to write with a loop? Then use a loop! Yes, but, say, in Haskell, that's not an option. It's useful to note that Haskell is usually touted as efficient, and lack of efficiency is a #1 concern around functional programming. That concern I personally find revolting: Haskell is slower than C, yes, but orders of magnitude faster than many widely used languages.
- deleted 9y ago[deleted]
- nilved 9y ago> Yes, but, say, in Haskell, that's not an option. forM_ [1, 2, 3, 4] $ \n -> print n
- deleted 9y ago[deleted]
- gizmo686 9y ago>Yes, but, say, in Haskell, that's not an option. Haskell does have the ST monad, which lets you encapsulate a non-pure algorithm (as in, one that relies on mutable state) within a pure function. In fact, any monad will let you write imperative looking code (whose behavior is determined by the semantics of the particular monad), the standard library even provides for and while loops as functions. You can also look at OCaml, which is very clearly a functional language, but has 1st class support for side effects and loops.
- wyager 9y ago> in Haskell, that's not an option. I'd say you have at least three fairly straightforward options. 1. Mechanically translate the loop to a recursive call. Not always idiomatic, but easy and pretty much guaranteed to compile to the same/similar assembly for a tight loop. 2. Use StateT and lenses. Your code can even look almost exactly like C if you want, with for and while loops with the same semantics as in C. I often use this when implementing heavily imperative papers in Haskell. It's still pure and everything, but looks just like an imperative language and performs well (if maybe not always full C speed). 3. If for some reason neither of those approaches work (e.g. If you're writing an algorithm that really benefits from mutation), you can use IO or ST for mutable variables. ST is really cool; it provides local mutability, but uses the type system to ensure that mutability never "escapes" into pure Haskell.
- surement 9y ago> 2. Use StateT and lenses. Your code can even look almost exactly like C if you want, with for and while loops with the same semantics as in C. I often use this when implementing heavily imperative papers in Haskell. It's still pure and everything, but looks just like an imperative language and performs well (if maybe not always full C speed). I am no Haskell expert and that sounds quite interesting. Do you have any links to examples?
- tmerr 9y agoThe concern about stack space is slightly misleading since many languages, i.e. Scheme, can easily optimize such functions to use O(1) space by reusing stack frames across recursive calls. The problem is that while Scheme guarantees this tail-call optimization in the spec the are many other languages that leave it up to implementation, or intentionally omit it because they don't want to lose stack traces. Anyway I agree with the overall sentiment, and will check out the talk you linked. There's another good one along similar lines: "The Clean Architecture in Python" by Brandon Rhodes: http://pyvideo.org/pyohio-2014/the-clean-architecture-in-python.html http://pyvideo.org/pyohio-2014/the-clean-architecture-in-pyt...
- deleted 9y ago[deleted]
- justbaker 9y agoYES. Functional programming is more of a pattern. I can write functional ruby/es6, but neither of those are purely functional languages.
- falcolas 9y agoSomething of a tangent, but: > any loop can be turned into a recursive function so long as your stack is big enough, even if they're usually hideous What amuses me to no end is how TCO turns around and converts that recursive function call right back into a loop before executing it. And this summarizes my thoughts about the main disadvantage of functional programming - you're working against the way the computer fundamentally works, and relying on the compiler to get it right.
- carussell 9y agoIt's not that silly, really. The same argument could be made regarding GOTO. The compiler can't really avoid turning everything into jumps, because it's all the machine understands. And yet structured programming is hands down far more advantageous for the human who has to be able to reason about the program at the end of the day.
- SomeStupidPoint 9y agoIsn't it trivial to implement a loop via recursion? loop fn cond update i acc: if (cond i): return acc else: return loop fn cond update (update i) (fn i acc) I'm not sure how using such a loop wouldn't be "functional", since you're not updating anything. (I believe you get TCO, so it shouldn't be that bad performance wise.)
- eropple 9y agoThat's "functional", but I sure don't want to read it.
- fao_ 9y agoOne of the things that I really love about Erlang, is that it unrolls loops and recursion like: count_to_ten(n) -> count_to_ten(n+1); count_to_ten(10) -> done. which is much cleaner than how the same code is presented in 99% of functional programming languages.
- fbonetti 9y agoThat's just a combination of pattern matching and tail call optimization. That code would look exactly this same in Haskell: countToTen n = countToTen (n + 1) countToTen 10 = done
- dllthomas 9y agoThe 10 case would have to be first, or that's an infinite loop. Cases are checked in order. That said, the compiler will give you a warning about it.
- SomeStupidPoint 9y agoWhy? I'm genuinely curious why you think that it's worse in functional languages than, eg Python or C. It's not like you don't specify all of those variables when using a loop in C -- you just have a special syntax to. I was outlining the actual recursion mechanism, not showing what you'd have to code.... You can make it look basically the same, with a signature like... loop (idx test update) fn acc ...which in practice will look like... loop (0 (\ x -> x < 5) (+1)) fn 0 The only annoyance is the slightly verbose lambda syntax for the test, but if you're using a function as a test, it becomes a smaller issue.
- nilved 9y agoNot to get all FP on you, loops and recursion are isomorphic. It is a hurdle to convert imperative code to functional code, just like the opposite, but it is unconditionally possible.
- surement 9y agoI'm aware of that. It's still not always trivial to implement.
- wyager 9y agoI ran into this exact problem and figured out you can fix it with StateT and Lenses. You can reproduce imperative code exactly, but in pure Haskell. You can even write things like for loops, no problem.
- lojack 9y ago> that's not possible in "purely" functional languages To be clear, it's always possible in a purely functional language, just not always reasonable or efficient. As far as your point goes, I totally agree. There are algorithms that are better suited for functional languages (ones that involve tree's and lists) and there are algorithms that are better suited for imperative languages (disjoint sets, hashing algorithms, lots of graph algorithms).
- jordache 9y agoyeah but functional operations just abstracts imperative statements.. so your pseudo code is almost like a granular expansion of the eventual implementation