Personally, I like to follow the mantra cabal is not a package manager. Because whenever I treat it like one, I get messed up in a bad way. I buy in to this argument[1] as to why it isn't.
That argument seems more like (ignoring the naming issues of cabal vs cabal-install), that cabal is a terrible package manager, but still (to me) seems to bare all the major features of a package manager.
The fact that it forwards package registration to the underlying ghc-pkg system, has very poor/nearly nonexistent record keeping, and can't perform uninstall operations are kinda crucial. I've never heard of a packager manager that can't uninstall.
If you present it as a package manager, even if it's a bad one, then you also telegraph a certain amount of implied functionality, and in turn the user has a certain level of confidence that the system is smart enough to do its best to prevent you from damaging your package ecosystem (not a guarantee, but at least an effort); cabal and by extension cabal-install doesn't provide this at all. It simply provides a way to install packages and makes a best effort at meeting the build goals required for individual commands to succeed in a vacuum.
I hesitate to call that a package "manager". It's just a very mediocre package installer.
Actually nix is a pretty awesome package manager for haskell. All my projects now have a default.nix and a shell.nix and I have this little snippet in emacs:
This drops you into a nix shell with all the dependencies for the project you're working on present.
You can also (especially easy if you're using projectile) run compile with the command nix-shell -I . shell.nix --command "cabal configure; cabal build" and that give you a nice list of type errors in your current project.
Repeatable builds with no cabal hell. In the words of disney: "I'm never going back, the past is in the past!"
Also I believe last time Stephen was surprised folks had gotten a hold of content on his "pre-prod" domain (e.g. http://dev.stephendiehl.com/), because he was still working on that post, before it was ready.
I like points as much as the next person, but maybe "pre-release" content should not be posted to aggregreators like HN before they are "realeased"
That said I'm excited he's continuing to update this series, it's helped a lot of people and there is a ton for me to learn still!
Reposts may not be encouraged but it gives the chance for new followers and those who missed seeing this post before. Not to mention the added karma for the poster.
On the other hand, for the sake of others, who don't know, please visit http://hn.algolia.com to check if something's already been posted!
I have to say that this line irks me: "Any preconceptions one might have for the word 'return' should be discarded, it has an entirely different meaning."
This sentence literally does nothing to help me even prepare to understand what is about to be explained. At the least, give a small example of what preconceptions should go. "All of them" implies that someone did a crap job of naming this thing.
Edit: Apologies to all responses. I responded to two, but I'm not sure I have different responses for each. If it seems I've ignored some aspect, apologies.
That sentence could have more information, but I think it still serves a worthwhile purpose. It's basically saying that, for now, think of "return" as a new thing you've never seen before and don't worry about correlating it with what you already have seen in other languages.
In Haskell, 'return' creates a monadic value. Here are some excerpts from Learn You A Haskell for Great Good:
> If you've done imperative languages like C, Java or Python, you're probably thinking that you know what this return does and chances are you've already skipped this really long paragraph. Well, here's the thing: the return in Haskell is really nothing like the return in most other languages! It has the same name, which confuses a lot of people, but in reality it's quite different. In imperative languages, return usually ends the execution of a method or subroutine and makes it report some sort of value to whoever called it. In Haskell (in I/O actions specifically), it makes an I/O action out of a pure value. If you think about the box analogy from before, it takes a value and wraps it up in a box. The resulting I/O action doesn't actually do anything, it just has that value encapsulated as its result.
...
> return is sort of the opposite to <-. While return takes a value and wraps it up in a box, <- takes a box (and performs it) and takes the value out of it, binding it to a name.
I should have been clearer, myself. My problem is not that I may have to drop preconceptions from other programming languages. My beef is that the word has meaning outside of programming. And is part of the reason it was chosen in said programming languages.
Imagine if it was called "name". And we had to "throw out all preconceptions you have with the word 'name.'"
It should probably have been called 'unit' or 'pure' as it was in Wadler's original Monad/Haskell papers.
I don't know who decided that confusing legions of future programmers with the name 'return'; using do notation to carry out sequential programming in the IO Monad made calling it return too tempting I guess, even though it's a misleading name for all the other Monads.
Edit: A quick spelunk through the Haskell literature suggests that John Launchbury is probably to blame. His paper "Lazy Imperative Programming" appears to introduce both return and do-notation.
Maybe there is some deep mathematical reason why 'return' is named as such, but I suspect the person who gave it that name was trying (perhaps a bit too hard) to make monadic code appear even more like the imperative code to which most of us are accustomed.
More or less by coincidence, 'return' tends to appear in the same places you would see the 'return' statement in C and derived languages. But the purpose of the 'return' function in Haskell is quite different from the 'return' statement.
All of them. return "lifts" a "plain" value so that it becomes a "monadic" thing. As far as I can see, this has nothing at all to do with returning a value from a function.
Right, but I have preconceptions of the word "return" that have nothing to do with programming. I'm fine if you want to think of it as "returning to the monadic environment."
That is, in English, you can return to things just as easily as you can return from them. I may have to forget some of the things that are common in other environments. But to use a word that has meaning outside of programming and to decry that you have to lose all preconceptions of that word, implies heavily that it was named poorly.
Even within programming, using a word in a way that is completely unconnected to the ways it is used by everybody else is... let's say it's not very useful if your goal is to communicate.
[1]: http://ivanmiljenovic.wordpress.com/2010/03/15/repeat-after-...