14 ms·
Why I Love Haskell: An Example
- hondo77 12y agoI salute you if you understood anything in "The Problem" section.
- deleted 12y ago[deleted]
- PaulAJ 12y agoIts not difficult. The author has a stream of data (random bytes for crypto keys) which needs to be consumed in different bits of the program at different times. The traditional ways are either a global variable holding the current state of the generator or else re-assigning that state to one or more variables in a complicated and error-prone way.
- dopamean 12y agoThis is my problem with everything I encounter when trying to learn about Haskell. I find almost everything I come across to be completely unapproachable. If I cant understand the problem you're solving in the blog post then the solution makes even less sense. I don't say this as a criticism of this author at all. It's just something I've noticed with Haskell.
- the_why_of_y 12y agoThe problem statement is basically copied verbatim from RFC 5246 sections 5 and 6.3. The author picked a cryptographic function from a rather important and widely deployed real-world internet protocol (TLS 1.2), but of course since the author is writing about Haskell readers assume it must be some esoteric academic nonsense that undoubtedly involves category theory, whatever that is.
- dopamean 12y agoI didn't say anything about "esoteric academic nonsense." Just because the subject matter is a part of something that is very commonly used does not mean it is outside the reach of many very competent people.
- the_why_of_y 12y agoEhh sorry for the hyperbole, was feeling a bit grumpy that day :-)
- jon-wood 12y agoI'm glad I'm not the only one who feels that way. I find that with many articles on functional languages, which leaves me wondering if they attract a certain type of person, or if they're just not well suited to the problems I work on. Is there anything good on doing web development in a functional style? I keep hearing about Om and Clojurescript in relation to React, but I have no idea where to start.
- bandrami 12y agoIf you count Lisp as functional[0] it has a pretty big web presence, both Common and Scheme. Functional languages reward (require?) a different kind of problem domain analysis than imperative languages do, and one of the things they are least good at is "I want to track the state of a bunch of discrete things that share similarities in structure", ie, 90% of Web programming. (But then again maybe that's only 90% of web programming because OO was the fad-of-the-day when web programming took off.) There's the old adage that data structures tell you a lot more than flowcharts; languages like Haskell and ML kind of turn that on its head. Rather than using functions to apply and track changes of state to abstracted chunks of memory, you apply and track changes of state by composing the functions with each other. This is great for some problem domains (eg, I think there's a reason that so much prototyping and code analysis is done in Haskell and ML) and less great for others (interfacing with a table-based database always felt kludgey to me, for instance). I do think they attract a certain type of person, namely the kind of person who prefers debugging on paper to debugging in memory. Haskell may well have a debugger, but I've never used it because I always do a static debug, usually with a physical code printout. Then again I'm also a crotchety geezer. TL;DR: many functional languages aren't great for the kinds of problems a lot of developers today are trying to solve, but the process of refactoring those problems in a way that does make functional languages useful is often a Good Thing for a developer to do. [0] I would argue it's not "functional" except in an accidental sense; it's a "symbolic" language that happens to have first-class functions. Lisp is mostly useful for writing more Lisp (but note "mostly"; I'm a confirmed Lisp Weenie and I find myself very productive in it).
- sukilot 12y agoThis website is written in a Lisp dialect.
- deleted 12y ago[deleted]
- jonnybgood 12y agoWhy would this be difficult in other languages, especially other modern languages? I wish the author expanded on it as I don't see anything special about the use of Haskell here.
- tel 12y agoDid he not? > Haskell provided a very light-weight syntax. > Haskell allows partial-application of functions. > Haskell allows definitions of unbounded data structures... > Higher-order functions like "iterate" and "map"... > Monads allowed me to avoid having to explicitly track side effects ... [also] purity and strong type checking. > Libraries of higher order functions for monads allowed me to limit the syntactic cost of using monads.
- tjradcliffe 12y agoNone of these are both a) special to Haskell and b) necessary to solving this problem in a clean way. So no, he did not. It's also worth pointing out that the last point contradicts the first.
- tel 12y agoI don't think he claimed (a) or (b). Instead, he claimed that Haskell has all of these features together and that the culminating result is a pleasant implementation of a real-world problem. Finally, the last point does not contradict the first. You can have lightweight syntax and use it to express heavyweight ideas. Then you can have libraries which help to alleviate that weight. This is a non-trivial task—it involves the abstraction power of your language and, in the case, the logical power of your type language.
- jonnybgood 12y agoThat just tells me he did it the Haskell way. That doesn't answer the question of why it would be more difficult in other (modern) languages. If you're going to make an audacious claim then we need to see evidence to support that claim. The author didn't do this. All the author did was show us a Haskell implementation.
- platz 12y agoProviding type signatures on all top-level functions would've been nicer for teaching purposes
- WaxProlix 12y agoAbsolutely. One of the nice things about Haskell and its type system in general is being able to look at a function's type and induce roughly what it does. Or, vice-versa, the ability to find pieces of functionality on hoogle by giving a reasonable type signature for your desired code. Skipping out on that visibility when showing how Haskell is expressive seems like a missed opportunity.
- xrstf 12y agoIs hoogle a special search engine for Haskell code or was that an unintentional typo?
- rifung 12y agohttps://www.haskell.org/hoogle/ https://www.haskell.org/hoogle/
- deleted 12y ago[deleted]
- luchs 12y agoYes, it's a special search engine: https://www.haskell.org/hoogle/ https://www.haskell.org/hoogle/ You don't search for words in the documentation etc., but enter the type of the function you want. This often works pretty well.
- TJSomething 12y agoFPComplete's Hoogle is a bit more complete: https://www.fpcomplete.com/hoogle https://www.fpcomplete.com/hoogle
- 12y ago
- Pirate-of-SV 12y agoI like Haskell because of some of the related tools. - HLint, a very helpful linter for ideomatic Haskell - QuickCheck, Fuzz-testing function's properties - hpc, Pretty code coverage
- sgrove 12y agoI find the Haskell tooling ecosystem surprisingly terrible, given how rich the information content of the code is. There's virtually no equivalent of most functions from e.g. Intellij for Haskell that I know of (although I haven't tried FPComplete's tools yet and hear good things). The libraries you mentioned though are indeed all really fantastic, and after learning how to use them you'll miss them dearly when they're unavailable.
- platz 12y agoThere are all sorts of tools, even for refactoring. Maybe not to the degree of Java, no. Although, haskell code tends to have less boilerplate, so there is less toolig for manipulating boilerplate. (Not to say there are other tools that could be improved). But the situation is far from dire. -- Vim: haskellmode-vim for show type and insert type, among other things. ghcmod-vim for HLint and HCheck, also used by Syntastic and NeoComplCache. neco-ghc uses ghcmod-vim for nifty Haskell completion, powered by neocomplcache. Syntastic automatic syntax checking for vim. --Emacs: structured-haskell-mode: https://github.com/chrisdone/structured-haskell-mode https://github.com/chrisdone/structured-haskell-mode haskell-emacs: http://chrisdone.com/posts/haskell-emacs http://chrisdone.com/posts/haskell-emacs
- deeviant 12y agoThen your Haskell expert leaves and then you learn why I hate Haskell(or insert any fringe programming language here).
- sgrove 12y agoLearning Haskell isn't beyond any programmers though, and is likely to pay off long-term. I agree that other fringe languages might have less payoff though - Erlang/elixir, Clojure, F#/OCaml, Idris/Coq/Agda (although who would write production code in these?) are all more likely to impart fundamental understandings than e.g. Coffeescript, Wisp, etc.
- deeviant 12y agoLearning kung fu or the violin isn't beyond most people either, but I'd rather not have that be the prerequisite for being able to be productive on my team. Most companies don't prioritize paying a potentially highly compensated worker to learn an obscure language when the job can just as effectively be solved using standard skills and languages that are much easier to acquire(hire). Also, despite the passionate defence that many functional-first language advocates give, I have never seen any conclusive evidence that these languages, in general, produce better results than the standard suspects.
- Ironballs 12y agoHaving a team member create production code in a language nobody else on the team understands is a risky decision. That applies for anything, software, systems, infrastructure... if one developer is allowed to sit on something, what happens when the dev leaves? Or dies? And the thing he or she worked on had a non-trivial learning curve? Choosing something like Haskell or anything else niche should be a group decision. Even when it comes to prototyping! "Guys, I'm going to prototype this .NET code in F#. Who wants to join?", instead of a developer sitting in a corner applicating his functors while others around him do something arguably simpler. It's incredibly short-sighted! This is not aimed at you though, since I'm not sure if this was your case, I'm only guessing based on your post.
- bluefox 12y agoTook 10 mins to hack a silly, inefficient version. https://play.golang.org/p/UPlzWR5OCO https://play.golang.org/p/UPlzWR5OCO Gives the same result as https://www.ietf.org/mail-archive/web/tls/current/msg03416.html https://www.ietf.org/mail-archive/web/tls/current/msg03416.h... SHA256 test vector. Looks easier to understand, to me...
- bbcbasic 12y agoBut is yours easier to reason about? There is no doubt a steep learning curve with Haskell and FP in general. You may be thinking: what is all this <$> <*> and $ nonsense! However once learned, you can look at the Haskell code and it is more clear precisely what it is doing (and what it can't possibly do). I think the article undersells Haskell. Haskell gives you code purity. Purity means you can reason about a function. A function that takes in an Int and returns an Int won't read data from your disk. It won't call a web service to get the answer. It won't update the counter int on your class and then one day cause it to overflow, causing another class that reads the counter int to throw an exception. This makes maintaining code a hell of a lot easier and more pleasant.
- belovedeagle 12y agoIt actually looked much more difficult to understand to me because golang just really has no structure. Anyways, it probably is simpler, because it doesn't solve the same problem that the Haskell code solves. The Haskell code allows you to generate some bytes from the infinite stream even if you don't yet know how many you need; your go version must know how many you need before you start. In order to do the same thing in go you're going to need to use an iterator or a goroutine + channel. Try doing that as cleanly as the Haskell version.
- azylman 12y agoThis can be done very easily using an unbounded io.Reader instead of channels or iterators. Here's a slightly modified version of bluefox's code where the prf function returns an unbounded io.Reader: https://play.golang.org/p/ZAj8q4eXEi https://play.golang.org/p/ZAj8q4eXEi And here's a version that's modified a bit more, but still essentially the same, to trade LOC for matching the spec very cleanly: https://play.golang.org/p/Rpy0yIwVN1 https://play.golang.org/p/Rpy0yIwVN1
- singlow 12y agoWhy I Love My Left Arrow When pressed in combination with the alt button, it can navigate back to the previous page I was viewing. But not when someone captures onkeypress and cancels it.
- sacado2 12y agoThat's because you didn't use the IO monad.