6 ms·
Software Development Languages: Haskell
- colingw 5y agoThis is Part 3 of an on-going series about the usage of various languages for real-world software development.
- dwohnitmok 5y ago> Haskell is in the best-of-class category when it comes to documentation. Haskell's type system quickly earns your trust, and once it does, you almost never need to read someone else's code in order to understand it; you can just read the type signatures shown in the docs and get on with your life. I don't think this is an accurate representation of how the Haskell community itself views the state of Haskell documentation. A large section of the community views the state of documentation as very not best-of-class and strongly advocates for improving it (and views type signatures as a poor replacement for at least examples). See e.g. https://www.reddit.com/r/haskell/comments/2ory86/there_is_a_documentation_problem_stop_pretending/ https://www.reddit.com/r/haskell/comments/2ory86/there_is_a_... Likewise "Otherwise, toss a coin!" as a response to Cabal or Stack makes me sad. Tooling can often depend on exclusively either one or the other (see e.g. https://plugins.jetbrains.com/plugin/8258-intellij-haskell https://plugins.jetbrains.com/plugin/8258-intellij-haskell) and the fact that from a capability point of view, they're converging on the same thing makes it an unnecessary point of friction for new users, although I understand the reasons for why they both came to be. EDIT: I should detach myself from the usual curmudgeonly HN comment to say that the organization of the article is very well done. I would like to see how non-Haskellers approach it because I think stuff like "What language idioms are available?" is a good way to approach a new language. EDIT 2: The original Reddit link was far older than I thought it would be. Here's a more extreme (more than I personally agree with) take on the situation, but is a lot more recent: https://old.reddit.com/r/haskell/comments/or93z3/what_is_your_opinion_on_haskell_remaining_as/h6h6q12/ https://old.reddit.com/r/haskell/comments/or93z3/what_is_you...
- dmitriid 5y ago> I don't think this is an accurate representation of how the Haskell community itself views the state of Haskell documentation. A large section of the community views the state of documentation as very not best-of-class and strongly advocates for improving it Almost every time (though it's quite rarely) that I end up on a Haskell documentaiton page, I facepalm and move on. Yes, there's a dump of inpenetrable types. But... how do I actually use those types? :)
- ggm 5y agoI think this is a very insightful comment. If the documents showed: 1) a simple instance of use of the language feature 2) a few typical instances of use and 3) did NOT use towers-of-hanoi, prime-sieve, mathematical smartness, pointless tricks unrelated to the core functionality, dubious features under dispute.. The best UNIX man pages for systems commands do exactly this. They show all the commandline options in the sort-of BNF, they list the meaning/intent of the options (hopefully alphabetically) and under EXAMPLES they show you the 3 cruicial commands you really came looking for, exactly as the worked when the manual page was written. I know I used man -s 1 or -s 8 to exemplify how to do man -s 2 and man -s 3 pages, but the point is they obey some simple (BNF) norms, some simple (nroff -man) format and EXAMPLES exemplify real-world use. Not "I am smart, watch me put a fruitloop in my nose" but real world, applicable instances.
- Zababa 5y agoCabal and stack are also very hard to understand when starting out.
- colingw 5y agoRust's `cargo` kicks the crap out of either of them.
- T-R 5y agoI think, coming from other languages, it takes a while to really absorb how much you can rely on types to tell you what a function is doing - to the degree that for some functions you can infer the implementation from them[1]. That said, Haskell documentation tends to be really lacking on some of the basics that other ecosystems get right, like where to start, shielding beginners from functions for more niche usecases, examples of how to build or deconstruct values, or end-to-end case studies. Some of the nicest things to _use_ have an API that primarily comes from typeclasses in base, and don't provide any documentation beyond a list of typeclasses. My impression has been that most Haskellers seem to be on the same page that those things need work, though - I'm optimistic about the situation improving, but it's still hard to recommend to anyone expecting the experience of working with popular libraries from more mainstream ecosystems. [1] https://bartoszmilewski.com/2014/09/22/parametricity-money-for-nothing-and-theorems-for-free/ https://bartoszmilewski.com/2014/09/22/parametricity-money-f...
- rowanG077 5y agoIf I compare Python docs and Haskell docs even the official python docs are completely terrible. For example let's take the regex library and want to look up how to get match groups: https://docs.python.org/3/library/re.html https://docs.python.org/3/library/re.html 99 out of 100 times someone will land on this page and already know what regexes are. So basically 1/3 of the page is useless. After a while you find you need to use the `match` method. Great! Now I see I get a match object. How do I deal with those? There is not a clickable link here. In the example it's an opaque object. So I scroll further maybe ctrl+F to find match object. Here I find what I'm looking for. So this take me pages of scrolling and then manually searching for the object a method returns. That SUCKS. Everytime I use the re library and need to refresh my knowledge I'm in pain. Compare this to Haskell: https://hackage.haskell.org/package/regex-compat-0.95.2.1/docs/Text-Regex.html https://hackage.haskell.org/package/regex-compat-0.95.2.1/do... Great. I instantly see how to construct a regex. The next thing I see is the `matchRegex` function. The bread and butter of using regexes. And what does it return? "Maybe [String]". Literally couldn't be easier then that. Of course this doesn't hold for every Haskell library and Python library. But this is my general experience.
- daenz 5y agoI learned Haskell a few years ago, enough to read it, but not fluent enough to comfortably write it. Haskell scratches a real intellectual itch, related to how it formally captures certain concepts (types, purity, etc). But my opinion is that Haskell collapses under the weight of its terseness and academic complexity. Can it be extremely elegant? Yes, in contrived examples[0]. Is it able to maintain this elegance when dealing with common problems? No. 0. https://wiki.haskell.org/Introduction#Quicksort_in_Haskell https://wiki.haskell.org/Introduction#Quicksort_in_Haskell
- exdsq 5y agoI've worked on commercial Haskell projects and it was actually quite nice! Tooling was a pain, libraries may be lacking, but describing a complex domain as a state machine in the type system with automatically generated tests (via properties) and formal methods to prove some of the core algorithms was a really interesting way to develop. Not sure it'd be my pick for my own startup though.
- nextos 5y agoWhat formal methods did you use?
- exdsq 5y agoCombination of Agda, Isabelle, Coq, and TLA+ depending on the team - I mostly interacted with TLA+ and the compiled Haskell from Agda specs :)
- dwohnitmok 5y agoWow definitely want to pick your brain. How large/# of LOC were the Agda, Isabelle, and Coq specs? What industry was this?
- exdsq 5y agoBlockchain - two repos with specs are: * https://github.com/input-output-hk/cardano-ledger https://github.com/input-output-hk/cardano-ledger * https://github.com/input-output-hk/plutus https://github.com/input-output-hk/plutus There's quite a few recent Isabelle repos such as https://github.com/input-output-hk/high-assurance-legacy https://github.com/input-output-hk/high-assurance-legacy
- laurensr 5y agoTrivia: the recently posted PostgREST project was written in Haskell.
- lambdasquirrel 5y agoIt might be worth giving a pointer on setting up your own stackage server. Otherwise, Haskell projects can become an ugly monolith sooner in a company's lifetime than one might expect. It can then become a double-edged sword that you're quite productive in the language. The CI for a medium-sized Haskell-using company should have multiple instances of: Project repo -> CI compilation -> tests -> publish library to company's internal stackage. That way, when someone inevitably publishes something that breaks things, the other teams will have an easy mitigation / known-good-version to fall back on. In other codebases (especially if they use the typical popular dynamic languages), you might start breaking things up into microservices sooner than you would with Haskell. But given that Haskell runs much, much faster than those other languages, and isn't quite the memory hog that the JVM is (when we're comparing to Scala), you might find that it'd help you scale if you broke up the codebase into libraries, rather than breaking it up into microservices. This is especially the case if your company / project is bottlenecked on ops (which many companies are, not just ones using Haskell). Multiple libraries is much easier to manage than microservices and forestalls the point at which you'll need serious dedicated ops.
- hyperhopper 5y agoIn your opinion, is that still the case if the company uses a one-version monorepo? Ideally every test would break when the library team tried to commit.
- lambdasquirrel 5y agoDepends on how big the monorepo is. I’ve seen just two or three highly productive teams start stepping on each other in ways that were more par for the course at 200 person engineering teams.
- Barrin92 5y agoFrom a practical software development POV I think the biggest problem with Haskell is the laziness by default. It's the central theoretical motivation for the language but when it comes to real work there are so many ways it can bite you, which is ironic given how much Haskell prioritizes safety in almost every other aspect of the language. To me it's always been hard to reconcile that you have to deal with so many restrictions in the language that save you from ending up in some ill-behaving program state, yet a wrong fold can basically blow your entire program up.
- yoyohello13 5y agoIs Laziness really that big of an issue in practice though? Admittedly, I'm pretty new to Haskell. I've done a few CLI programs and one little web app using Yesod, and the fact that Haskell is lazy by default has never come up.
- colingw 5y agoIt can sometimes be an issue in certain "Gotta go fast" scenarios, where you'd otherwise be able to reason quite confidently about program behaviour with a strict language.
- anyfoo 5y agoMy experience: For one, it makes reasoning about runtime (as in "how long") harder: E.g. an innocent looking "take 5" might be what actually executes half of the code you've written... which is also harder to reason about than if it would be "all of it". This can also make debugging harder: Values are only evaluated when they are needed, and a "value" itself may not be just, say, a single number, but a complex data structure consisting of many values, so that "evaluated" has many different stages between "a thunk, not evaluated at all" and "weak head normal form". So code does not get executed when you wrote so in your program, but potentially much much later. Semantically that should not make a difference (the results should be the same), but when you want to debug program flow...[1] You can see how "thunks" in general add a certain dimension to everything you do. Throw in interaction with garbage collection, and things aren't always obvious in resource usage. Also, there is maybe an argument that if you have infinite data structures that you only tend to evaluate partially (which is what makes laziness really fun, actually), then accidentally trying to fully evaluate such a data structure makes your program not terminate anymore. But I'm not sure how that's really a problem coming from laziness. Laziness allows you to handle infinite data structures in the first place, mishandling them is not much different than accidentally writing an infinite loop in a strict language, in my opinion. That being said, I still enjoy writing Haskell very much when I get to. It makes me feel much more productive, and I do lament having to use other languages at work. I must say using Haskell was always on private projects, and I have never tried doing so in a team, though. [1] On the flip side, I find the pureness and strictness of Haskell to make debugging easier, or just less necessary.
- bedobi 5y agoI wish there were more articles like this. So much content online on programming languages go trough the basics of the language itself, with very "forced" code examples to showcase some feature of the language, and while they're great for what they are, they don't tell me anything about "what does the software development life cycle actually look in this language?" (including tools like package managers, IDEs etc etc)
- dexwiz 5y agoI agree. In another forum someone was asking what level of competency you should be at with a language to put on the resume. Most responses were related to the language itself, but I argued it was more about the knowledge around the language. Knowing testing, tooling, packaging, and standard library is way more important than syntax. In turn, I think it's easier to write an article about syntax since its likely to be correct forever. While an article about dev life cycle is much more tied to the time at which it was written.
- chopin 5y agoI like the article much but I am missing some statements around IDE. What I like about typed languages is the code completion and refactoring it enables when used in a good IDE. Code completion also enables me to "explore" what is possible at the current location. Are there any good IDE's out there for Haskell?
- travv0 5y agoI find VS Code with the Haskell extension to be very good for displaying type signatures, code completion and navigation, etc. Holes (which are covered by the article) are the go-to way to see what's possible at the current location. You type an underscore in your code and the compiler tells you a bunch of information about what goes there including things you could put there that would typecheck.