"I'm usually a strong proponent of the rule of law, innocent until proven guilty, and so on, but I strongly believe that anybody who writes an article about functional programming where the only example given is 'factorial' (or 'fibonacci' for that matter) should be summarily executed, no exceptions."
i know.. at the very least i was hoping to see lots of stats on things like adoptions by companies or heavy usage in critical projects with high visibility... all i got was factorial!!
I would be really suprised if functional programming caught on. Most programmers don't start in college, they start in high school. And high school people don't have the patience for functional.
FP is moderately difficult to understand and hard to do wrong.
FP is the pwn sauce, no question. The more interesting debate (and one on which I don't have enough experience to have an authoritative opinion) is the static-vs.-dynamic controversy.
Can someone explain the top 1, 2 or 3 benefits of FP? I just want to hear the key positives that would make an order of magnitude benefit to me. If FP would increase my productivity 5%, not really interested. If it's 50%, that's something.
For instance, I would say for OO two benefits that can create an order of magnitude increase in a programmer's performance are:
- much easier to use 3rd party libraries(since most good code is OO)
- much easier to modify/debug code
1. Concurrency done right -- take a look at Erlang or Clojure to get an idea of multi-threaded programming without the nightmare of locks and deadlocks. This feature will become increasingly important as CPUs are scaled by integrating more and more cores.
2. Testability -- immutable variable bindings and carefully sequestered state changes means your code is vastly better suited for testability.
3. Distributed Computing -- this maybe a controversial claim, but in my experience building distributed systems in Java, Common Lisp and finally Erlang (on separate projects of course), Erlang stood out as the most robust and understandable distributed model of all.
In so far as 3rd party libraries go, a lot of newer FP languages are built on top of existing VM platforms (e.g, Clojure on JVM, F# on .NET), and are able to leverage all their available libraries. Bear in mind, that while these libraries may help build your application slightly more quickly, you end up sacrificing the benefits of FP by integrating their non-FP code.
FP vs. OO is more of a style argument than one of languages, since most decent languages provide support for both styles of programming. It happens that FP is much more often appropriate, at least among the problems I've encountered, but there's no reason a person can't use a language with support for both (e.g. Lisp, Ruby).
Static vs. dynamic typing, on the other hand, involves a decision about the language that has to be made early in development. Lisp's static-typing support sucks in comparison to what Ocaml or Haskell provide (automatic type inference, which kicks ass, and very powerful type systems). Likewise, if you want dynamic typing in Ocaml, you have to create a universal type: there are ways of doing this, but they're gnarly and slow.
I've often wondered about how to build a hybrid language. A possibility would be to implement a language like ML or Haskell (but keeping the S-expressions, because those are awesome despite their unpopularity) as a DSL within Lisp, heh. Now that would be the pwn sauce.
Functional programming is more than a style. While programming in a functional style is possible in many languages it's very limited, even in a language like Scala. Regarding the hybrid languages i personally think that F# is relatively good for both functional and OOP programming. There are better functional and OOP languages than F#, but i don't feel too limited doing either. Clojure may also be a good choice but i don't have enough experience with it to give an opinion.
Yes it is fascinating - the static versus dynamic rears its head in all sorts of places - sometimes not even programming related.
Smarter people then me can probably identify some underlying mathematical reason...
I know the "typed lambda calculus" is the super set of the lambda calculus, but that's about it for me (or rather the "commonly known" lambda calc. is really a special case of the more general typed lambda calculus) - now if that translates into static typing being more mathematically pure/complete, I don't know (and even if it did - what does that mean in practice??).
I think nice languages with decent type systems kind of make static typed languages look nice - so the aesthetic argument (which is what most people refer to when they bring up the debate) mostly goes away (eg haskell, scala to some extent - although it can get gnarly).
I like using both - however from what little experience I have had I haven't enjoyed dynamic languages with optional type annotations (but it is limited experience).
I am interested in Brendan Eich's suggestion for ECMA script 4 (!) to have typed interfaces for the edges of a system....
Static typing began as a performance optimization for Fortran, early on when the developers realized it was a good idea to split ints and floats. If it were a performance optimization only, it probably would've faded from most modern languages entirely, but it offers new ways to think about languages and programming, and also allows tools to exist that can't be built for dynamically-typed languages, such as Ocaml's and Haskell's compile-time type-checkers, which are surprisingly good at catching bugs-- even ones that seem to have nothing to do with the type system.
There are, likewise, functions and tools that can't be built in statically-typed languages. For example, a general "compose" function (or macro, if you're so inclined)-- one that takes a list of functions and produces their composition-- can't be built in a language like Ocaml. (The best you can do is ('a -> 'a) list -> ('a -> 'a) ; e.g. it has the additional requirement that each function have the same return type as its input.)
I'm talking about the compile-time type checker that ML and Haskell have. This is a very powerful tool that doesn't exist in dynamically-typed languages. It seems like a mere curiosity, because a lot of the super-cool things you can do with type-checking are impractical (e.g. the use of phantom type hackery to do bounds-checking on arrays). However, on large projects with multiple programmers, it also helps to keep interfaces stable and self-documenting.
For example, let's say you change the output type of a function deep in the trunk-- instead of returning a 'a or throwing an exception, it returns a 'a option, e.g. a discriminated union between None or Some x, where x is a 'a, using the None value to represent failure, in lieu of the exception-- and want to find all the places where things break in the leaf code, so you can adapt them to the changes. What tool do you use: grep? Nope. You attempt to compile the tree, and all the code-breaks are caught and displayed by the compiler.
http://news.ycombinator.com/item?id=384637