About your point 3), it's worth noting the "toHtml" call buried in that example.
Haskell is both strongly and statically typed. That type boundary between strings and HTML output is enforced by the compiler, and it automatically (and provably!) prevents a metric crapload of injection attacks.
Here's an example that brings together Aeson, Lens, Acid-State and Scotty together in one file. Haskell really does have some great offerings for building very solid and fast web applications.
I disagree completely with his analysis on monads.
If you just present the abstract structure, you cannot understand why you even want (for example) the do notation as a language-level concept. I think this is more of a case of bad examples than anything.
Trying to represnent monads via analogy works badly too though, because monads as used in haskell are more about programming pragmatics than modelling real world objects.
The way to explain it should be :
- Show real code
- Explain why we use this structure to write our code .I think a good explanation is to ...
in Jquery you do things like chaining to build things.
Chaining APIs are useful because you're combining computation('chaining'), and you don't want to have to carry around a value everywhere. You want to do the same thing in Haskell obviously.
Haskell doesn't have dot notation, so you can't do this style exactly. First idea would be to do something like
let x=jQuery document selector in
let y=css x 'color' 'red' in
let z=filter y someFilter in
...
This is a pain, especially considering that the 'chaining' here is mechanically obvious
let [n+1] = f [n] [whatever] in
let [n+2] = g [n+1] ....
So monads, in the most pragmatic sense, allow you to represnt this form of computation. You end up with
In any case the Maybe monad is the worst example ever, just like how a singleton group is a bad example. Sure it's the 'simplest' , but it's far from the most typical
I'm not sure you actually disagree with his method of learning monads.
He primarily advocates for avoiding the use of analogies, which you seem to agree with. He advocates using concrete monads in real code, which you also seem to agree with.
The only contentious point might be learning typeclasses and how monads fit into the Typeclassopedia. If you want to be able to trace how your monad-using code is evaluated this is a necessity. Like it or not. Also, attacking monads from both the concrete and the abstract at the same time seems to be a good approach, with satori being achieved once the understandings meet. A dynamic-programming approach?
You may possibly be disagreeing with the order in which he lists these components of learning in his 'Eightfold Path', but if the analogy to the Buddhist teachings is followed further, then the steps need not be taken in sequence.
The slides certainly include many monad examples besides maybe at any rate.
The problem with bringing jQuery into the discussion is that it's not a monad. Don Stewart explains this more elegantly than I can [1] but the crux of the argument is that chaining together computations is not enough to be a monad, one needs to prove that the monad laws hold.
I've read lots of monad tutorials. I get it, they're a way of encapsulating side-effects in a pure lazy language.
But Haskell doesn't sink in unless I use on a regular basis. The time that I've felt like I was able to see a light at the end of the tunnel (i.e., that I might be able to be useful enough in Haskell that I could keep using it regularly) was when I simply memorized the expansions for the do, <-, return sugars.
>I disagree completely with his analysis on monads
You say that, but your post doesn't actually show disagreement. He said to avoid analogies, not avoid real code. His list of steps in fact contains "use monads in real code".
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:
(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.
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.
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.
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.
Does anyone know the best book for learning Haskell? I have heard it is good for just thinking about programming in new ways and keeping your mind agile. I can really only learn a language with a good structured book with exercises at the end of each chapter. Haven't found something definitive yet, but would be open to suggestions.
The 'best' introductory book for learning Haskell is Graham Hutton's 'Programming in Haskell'. It focuses on the essentials of the language, and its clear, spare presentation is in the spirit of Haskell itself. And it is accessible to everyone.
Personally, I would agree with the guy that said that Learn You a Haskell and Real World Haskell are some of the best resources. LYAH is really good at explaining the language features while RWH is currently the best we have in terms of giving practical examples with real libraries and things like that.
This post somehow triggered me to grab "Learn You a Haskell for Great Good" this morning and I have been gorging on it since then. I've had quite a few "holy shit" moments.
Pretty comprehensive (including plenty of things I haven't had time to look at into more details yet). Bonus points for using applicative style, which makes it a lot easier (and clearer) to apply function to value inside monads.
How so? An OOP language without inheritance would still be coupling code and data together "in unnatural ways". It is the object that is doing the coupling, not inheritance.
As freyrs points out, GHC "desugars" all Haskell code into a very small intermediate language that is similar to the System F lambda calculus. In the slide you linked you can kind of see that: you start with two doubles for 2 and 3 (created wit the `D#` function) and then you add them with the addition operator. Notice that this exposrs the implementation of typeclasses: the overloaded + operator is actually a function of three arguments and the first argument is the "vtable" that has the actual number operations.
I don't know why he is doing all of this though. The slides themselves don't give much context...
I first learnt Haskell ten years ago for a class. Mostly toy problems. Looking to get back into it. What books are good to learn to build actual apps - especially user input, UI, etc.?
[+] [-] cies|13 years ago|reply
1. ACID (acid-compliant persistance on Haskell data types, with indexes)
http://dev.stephendiehl.com/hask/#(27)
2. Pipes (program on streams of data)
http://dev.stephendiehl.com/hask/#(30)
3. Scotty (micro web-framework, a la Sinatra or Flask, on top of the super fast Warp server) http://dev.stephendiehl.com/hask/#(32)
[+] [-] cscheid|13 years ago|reply
Haskell is both strongly and statically typed. That type boundary between strings and HTML output is enforced by the compiler, and it automatically (and provably!) prevents a metric crapload of injection attacks.
[+] [-] freyrs3|13 years ago|reply
[1] https://github.com/sdiehl/haskell-warp-rest/blob/master/serv...
[+] [-] avital|13 years ago|reply
[+] [-] rtpg|13 years ago|reply
If you just present the abstract structure, you cannot understand why you even want (for example) the do notation as a language-level concept. I think this is more of a case of bad examples than anything.
Trying to represnent monads via analogy works badly too though, because monads as used in haskell are more about programming pragmatics than modelling real world objects.
The way to explain it should be :
- Show real code
- Explain why we use this structure to write our code .I think a good explanation is to ...
in Jquery you do things like chaining to build things.
$('selector').css('color','red').filter(someFilter).css('color','blue')
Chaining APIs are useful because you're combining computation('chaining'), and you don't want to have to carry around a value everywhere. You want to do the same thing in Haskell obviously.
Haskell doesn't have dot notation, so you can't do this style exactly. First idea would be to do something like
let x=jQuery document selector in let y=css x 'color' 'red' in let z=filter y someFilter in ...
This is a pain, especially considering that the 'chaining' here is mechanically obvious
let [n+1] = f [n] [whatever] in let [n+2] = g [n+1] ....
So monads, in the most pragmatic sense, allow you to represnt this form of computation. You end up with
jQuery 'selector' >>= css 'color' 'red' >>= filter someSelector >>= css 'color' blue'
You implicitly carry around your computation.
)
In any case the Maybe monad is the worst example ever, just like how a singleton group is a bad example. Sure it's the 'simplest' , but it's far from the most typical
[+] [-] sordina|13 years ago|reply
He primarily advocates for avoiding the use of analogies, which you seem to agree with. He advocates using concrete monads in real code, which you also seem to agree with.
The only contentious point might be learning typeclasses and how monads fit into the Typeclassopedia. If you want to be able to trace how your monad-using code is evaluated this is a necessity. Like it or not. Also, attacking monads from both the concrete and the abstract at the same time seems to be a good approach, with satori being achieved once the understandings meet. A dynamic-programming approach?
You may possibly be disagreeing with the order in which he lists these components of learning in his 'Eightfold Path', but if the analogy to the Buddhist teachings is followed further, then the steps need not be taken in sequence.
The slides certainly include many monad examples besides maybe at any rate.
I think the slides are worth another look :)
[+] [-] freyrs3|13 years ago|reply
[1] http://stackoverflow.com/questions/10496932/is-jquery-a-mona...
[+] [-] gavinpc|13 years ago|reply
http://stackoverflow.com/a/2704795/4525
I get it now, so thanks!
[+] [-] tome|13 years ago|reply
[+] [-] kzrdude|13 years ago|reply
[+] [-] marshray|13 years ago|reply
But Haskell doesn't sink in unless I use on a regular basis. The time that I've felt like I was able to see a light at the end of the tunnel (i.e., that I might be able to be useful enough in Haskell that I could keep using it regularly) was when I simply memorized the expansions for the do, <-, return sugars.
[+] [-] lmm|13 years ago|reply
[+] [-] papsosouid|13 years ago|reply
You say that, but your post doesn't actually show disagreement. He said to avoid analogies, not avoid real code. His list of steps in fact contains "use monads in real code".
[+] [-] mercuryrising|13 years ago|reply
http://www.stephendiehl.com/posts/essential_haskell.html
http://www.stephendiehl.com/posts/types.html
[+] [-] sid6376|13 years ago|reply
[+] [-] egeozcan|13 years ago|reply
[+] [-] Kiro|13 years ago|reply
[+] [-] drostie|13 years ago|reply
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:
In Haskell you could write this itero-recursively as: Notice that there's no $tmp and the named variables are now function arguments. You'll find yourself writing PHP more like: (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: 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: 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.
[+] [-] xaritas|13 years ago|reply
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.
[+] [-] MichaelGG|13 years ago|reply
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.
[+] [-] archivator|13 years ago|reply
Whether it's Haskell or some other purely functional language, I'm of the opinion that every programmer should have one in their toolset.
[+] [-] marshray|13 years ago|reply
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.
[+] [-] tkahn6|13 years ago|reply
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.
[+] [-] nnq|13 years ago|reply
[deleted]
[+] [-] yummyfajitas|13 years ago|reply
[+] [-] thomasjames|13 years ago|reply
[+] [-] jimmyjazz14|13 years ago|reply
[+] [-] ericssmith|13 years ago|reply
[+] [-] ufo|13 years ago|reply
http://stackoverflow.com/questions/1012573/getting-started-w...
Personally, I would agree with the guy that said that Learn You a Haskell and Real World Haskell are some of the best resources. LYAH is really good at explaining the language features while RWH is currently the best we have in terms of giving practical examples with real libraries and things like that.
[+] [-] lobster_johnson|13 years ago|reply
[+] [-] freyrs3|13 years ago|reply
[+] [-] Evbn|13 years ago|reply
[+] [-] pervycreeper|13 years ago|reply
[+] [-] simpsond|13 years ago|reply
[+] [-] mercurial|13 years ago|reply
[+] [-] Uchikoma|13 years ago|reply
should be
"Inheritance couples code and data together in unnatural ways. Typeclasses are a better way of structuring logic."
[+] [-] papsosouid|13 years ago|reply
[+] [-] kzrdude|13 years ago|reply
What is the value of -ddump-simpl as shown here? http://dev.stephendiehl.com/hask/#%2816%29
[+] [-] ufo|13 years ago|reply
I don't know why he is doing all of this though. The slides themselves don't give much context...
[+] [-] freyrs3|13 years ago|reply
[+] [-] rtkwe|13 years ago|reply
[+] [-] sordina|13 years ago|reply
[+] [-] theicfire|13 years ago|reply
[+] [-] mwerty|13 years ago|reply
[+] [-] cies|13 years ago|reply
i think the yesod o'reilly book (free on yesodweb.com) is a very good one if you dont mind to make web apps.
[+] [-] yayitswei|13 years ago|reply