Hacker News new | past | comments | ask | show | jobs | submit login

I'm a PHP developer and I didn't understand one single thing in this presentation. Any reason I should learn Haskell?



If you're really happy and think things are dandy and don't really have an alternative, then no, stay away from Haskell and FP. As others have commented, you will not be able to code the same way after you have learned functional programming.

While FP doesn't solve everything, it does massively reduce the amount of code you write. Where I work, I started writing everything I owned in F#. After a while, I noticed all other new projects were being written in F#, even by people that had previously told me "we are sticking with C#". Why? Because they feel bad having to write loads more code to get the same work done.

Every time I have to work in C#, I'm constantly annoyed about how verbose even the tiniest things are, how much work there is.

Beware, PHP's syntax for lambdas is incredibly verbose (and IIRC there are some odd limits on how you can use them), so if you become "enlightened" then continue to try to apply it in PHP, you are in for a rough ride. Even C# which slightly embraces functional concepts, gets pretty nasty if you write in any sort of real FP style.


Where do you work that you can just take a decision like "I'm going to use language X" if you don't mind me asking?

How did you deal with concerns (which I assume your manager must have had) about skilling up the rest of your team, and your increasing component of the bus factor? [1]

I tried to make a case for F# for some parts of our codebase and got shot down!

[1] http://en.wikipedia.org/wiki/Bus_factor


If you maintain code that is a gigantic ball of if-foreach-else-switch-is_null or your class hierarchy looks like something a Java developer would produce, and you are constantly thinking "there must be a better way," you might benefit from exploring Haskell or a language with some of its features.

PHP is actually one of those languages, since it gained real support for first-class functions, anonymous functions and closures starting with 5.3 and improving with 5.4. So if you do learn Haskell you'll be able to directly apply some of its ideas to making your PHP more concise, easier to test, and less error prone. Check out the PHP Underscore library to provide some of the infrastructure: http://brianhaveri.github.io/Underscore.php/

Haskell brings a lot more to the table than first class functions, and it may or may not be a good introduction to functional programming for you, but other functional(-ish) languages such as Scala or Clojure (or Scheme & other Lisps) will work well, too. Just give it time. It's worth the effort, but you're not going to magically transform your code into the Unicorn Monad overnight.

If you do PHP you probably do a lot of JavaScript, too, so there is another language that supports getting into functional programming, and there is definitely a lot of interest in moving JavaScript in more classically functional direction. So you won't be blindsided by maps, folds and promises.

I apologize if you already use first class functions like a boss and you were really asking if you needed static type inference. The answer is Maybe.


Functional programming is a tool. It's a really powerful tool. Knowing really powerful tools helps you solve really difficult problems.

Whether it's Haskell or some other purely functional language, I'm of the opinion that every programmer should have one in their toolset.


It's more than a tool, it's a different programming paradigm. It helps you to look at something in a different way. You can pick up a thing or two that are useful pracitices in other imperative programming languages, too.


Learn Haskell if you want your mind blown. It will make you smarter.

But there's a real danger that you will not be able to look at your own code the same way again. It can negatively affect your ability to code with your peers.

I'm not kidding. It's a blue pill/red pill kind of thing.


Nope. I see no negetive effects.

Functional programmers can write better OO code imho.


It's hard to identify a practical reason because presumably using your existing PHP stack is going to be easier for you than learning how to run a Haskell stack. Every new language comes with such barriers. It's sometimes hard to see how severe those barriers are -- I remember trying to show a totally novice-to-programming kid how to set up EasyPHP so that they could start coding. Setting up EasyPHP, which is, well, Easy, requires explaining what HTTP is and what Apache is and all that... it's actually a huge barrier to entry for a novice programmer.

But if you're OK with the impractical, here goes:

Haskell trains you to think about programming in a couple of subtly different ways that change your entire perspective.

(1) Variables are replaced with definitions and values. You probably remember HTTP as stateless and cookies as a sort of informal "patch" for this; similarly it's hard to define state in Haskell. This means that `x = [1, 2, 3];` is allowed but `x[1] = 5;` is not, because the list cannot be directly modified. This does not actually weaken the language because you can always bind new names to new values, and idiomatically you'd often use recursion -- when you want to change a parameter you arrange the code so that you can recurse and call the function again with a new parameter. It's not 100% practical but let's take the Fibonacci numbers, which you might code in PHP like so:

    function fibs($n) {
        $curr = 0; $next = 1;
        for ($i = 0; $i < $n; $i++) {
            $tmp = $curr;
            $curr = $next;
            $next += $tmp;
        }
        return $curr;
    }
In Haskell you could write this itero-recursively as:

    let fibs n = f n 0 1
      where f n curr next = if n < 1 then curr else f (n - 1) (next) (curr + next)
Notice that there's no $tmp and the named variables are now function arguments. You'll find yourself writing PHP more like:

    function fibs($n, $curr = 0, $next = 1) {
        return n < 1 ? $curr : fibs($n - 1, $next, $curr + $next);
    }
(2) Haskell is lazy. The above is actually impure because it implements `fibs` as a function when really the Fibonacci numbers are a sequence and should be treated that way. Haskell actually has no problem with defining the infinite list of Fibonaccis as:

    fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
That's a list just like any other in Haskell, it just happens to be infinite. Or, you can write the infinite list of primes:

    primes = 2 : filter prime [3..]
      where prime k = all (\n -> mod k n /= 0) (takeWhile (\n -> n^2 <= k) primes)
You will miss this a little in other languages; even Python, which can do this with custom generators, gets a little clumsy. Especially, I miss this in Node.js, where the whole language is built around an idea of "callbacks" which wouldn't need to exist if the JavaScript operators could work on deferred computations (sometimes called "promises").

(3) Haskell has a type system and explicit pattern-matching. This is a little harder to express: you're used to saying `x = my_object->x` in PHP to avoid saying "x" over and over. Let's say that the object should also have "y" and "z" fields; then you'll have to deal with cryptic errors if your function is ever called with a my_object which does not have a field named "x", but it will be okay if "y" or "z" is not allowed, even though that doesn't actually make sense really!

In Haskell you'll specify in the definition of the argument "Object x y z"; and then x, y, pattern-matching to those respective values. So your functions don't start off with a bunch of "data-extraction" commands; those commands are in the input pattern. You can also define the function when the patterns do not match, because you can define a function several times for different patterns.

The type system can also flag, for example, unsanitized text going into a SQL query and other such things you might have missed, so you can lean on it a surprising amount.

(4) The biggest thing that this page was talking about was monads, and the reason why it was talking about them is because Haskell offers a special notation for dealing with monads.

A monad is basically a context which you can't necessarily "break the data out of". For example, the "IO" monad is a context which says "this data depends on an unrepeatable IO action, like getting a random number or reading a file." You can't really erase that fact from the data, but that fact shouldn't stand in the way of handling the data. The IO monad allows you to very cleanly separate the stuff which might be different in two different runs of the program, from the stuff which is never so.

The author makes the claim that analogies are bad for understanding monads. Instead, you should just look at the definition. A monad is a typeclass which wraps another type, so the type is "M(T)" where T is any other type. A monad is defined by two functions. One is called "return" and has type T -> M(T), it puts plain data into the monad. The other function is called "bind" and accepts a function T -> M(T2), which intuitively "takes the data and feeds it to the function." The reason that you can't always "break out" of the monad is that the output of this function is M(T2), so the function output must also be in the monad. We know that "monad" is a scary-sounding word but really nobody has a better name for it.

Lists are a good monad; here `return x = [x]` and `bind xs f = concat (map f xs)`. Another simple monad is called Maybe, which can either be `Just x` or `Nothing`, it sort of represents a computation which might fail. Here `return x = Just x` and `bind Nothing fn = Nothing; bind (Just x) fn = fn x`. There's also a "State" monad, which gives you a "put" and "get" method and a scope block for typed modifiable variables, so you can have code that looks imperative -- but you've got to carefully mark it as such with the type system as a whole. The whole point being that once you allow that "put" statement you make it much harder to think about bugs because the value of the parameter will depend on where in the function that parameter appears -- so the type system acts as a warning flag.


Start here:

http://learnyouahaskell.com/chapters

This is good too, but I found it somewhat dry:

http://book.realworldhaskell.org/read/

I think that learning Haskell will make you a better programmer. It's really a different way of doing things.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: