I think I share the same opinion: I think this is going to be a very painful break with the previous paradigm, but a much needed one, and that actually this version of the current paradigm is quite bad: browsers only survive when Google pays them money.
Instead this will put all browsers on a much more even playing field, and perhaps it will force governments and citizens to realise that free software takes someone to write it.
I don't think it's specifically Haskell's style of functional programming. It's just functional programming.
Any paradigm shift requires re-learning I think. I don't actually think that's particularly hard, nor do I think it means the paradigm isn't a good one, it's just an inevitable consequence of a paradigm shift. Some shifts are easier than others, if the paradigms are closer together, but functional and imperative programming are quite distant in my view.
Nevertheless, I've seen some people find this easy, others find it hard. YMMV I guess.
> Some libraries use exceptions for lots of error states that in Go would be a returned error value.
This just seems like bad libraries, I'd agree that this is bad and sort of defeats the point. I haven't actually encountered this with any libraries I've used, and we tend to avoid MonadThrow / Catch except in particular circumstances.
> in this case, I'm worse off than in Golang.
Having (unfortunately) had to write some Golang, I don't think this is true -- I've encountered plenty of code in Golang in which it seems idiomatic to return things like empty strings and empty objects instead of error values which, I think, it's still possible to mishandle.
Perhaps this can be summarised as: you can still write bad Haskell, but I don't think it's particularly idiomatic looking at the libraries I've spent most of my time using, and the machinery you are provided allows you to do much, much better.
I think this is being taken as me saying “therefore you can write any programme in Haskell” which, while true, was not the point I was trying to make. Instead I was trying to reduce the possible interpretation that I was suggesting that Haskell can write more programmes than other languages, which I don’t think is true.
> computability and programming just aren’t that related
> It is a shame that the article almost completely ignores the issue of the tooling.
Mostly because while I found of the tooling occasionally difficult, I didn’t find Haskell particularly bad compared to other language ecosystems I’ve played with, with the exception of Rust, for which the compiler errors are really good.
> The syntax summary in the article is really good
If I may, as the author of "such sloppily constructed prose" (which I think might be a little unfair as a summary of all 6.5k words):
In this syntax note, I was not trying to teach someone to write Haskell programmes, but rather to give them just enough to understand the examples in the essay. I did test it on a couple of friends to see if it gave them enough to read the examples with, but was trying to balance the aim with not making this section a complete explainer (which would have been too long).
Perhaps I got the balance wrong, which is fair enough, but I don't think it's required to define _every single_ term upfront. It's also not crucial to the rest of the essay, so "The article lost me at following sentence" feels a bit churlish.
Nope: I think the laziness aspect is very interesting, but it's not something that makes Haskell (for me) a great programming language. Or, at least, it's not in my list of the top reasons (it is in there somewhere).
> I find some code easier to express with procedural/mutable loops than recursion
This is what I was talking about in the section "Unlearning and relearning". While there are _some_ domains (like embedded systems) for which Haskell is a poor fit, a lot of the difficulties people have with it (and with FP in general) is that they have been heavily educated to think in a particular way about computation. That's an accident of history, rather than any fundamental issue with the programming paradigm.
> That's why, if you like the Haskell philosophy, why would you restrict yourself to Haskell?
In the essay, I didn't say "Haskell is the only thing you should use", what I said was:
> Many languages have bits of these features, but only a few have all of them, and, of those languages (others include Idris, Agda, and Lean), Haskell is the most mature, and therefore has the largest ecosystem.
On this:
> It's not bleeding edge any more.
"Bleeding edge" is certainly not something I've used as a benefit in this essay, so not really sure where this comes from (unless you're not actually responding to the linked essay itself, but rather to ... something else?).
> In this example bar's type signature doesn't tell you anything about what bar 'consumes'
Yes, it does: `bar` in your example is an `Int`, it has no arguments. That is captured precisely in the type signature, so I'm not sure what you're trying to say.
This part: "the type information only tells you how you can use doSomething. To know what is doSomething, you actually have to read the code :\" I think we're disagreeing on something quite fundamental here, based on "it doesn't tell you that bar depends on foo, and on foo's type. Also you have to read the body of bar, and also it is bad for code reuse."
(Although I am certainly open to the idea that "[I] failed to demonstrate it".)
A few things come up here:
1. Firstly, this whole example was to show that in languages which rely on this goto paradigm of error handling (like raising exceptions in python) it's impossible to know what result you will get from an expression. The Haskell example is supposed to demonstrate (and I think it _does_ demonstrate it) that with the right types, you can precisely and totally capture the result of an expression of computation.
2. I don't think it's true to say that (if I've understood you correctly) having functions call each other is bad for code re-use. At some point you're always going to call something else, and I don't think it makes sense to totally capture this in the type signature. I just don't see how this could work in any reasonable sense without making every single function call have it's own effect type, which you would list at the top level of any computation.
3. In Haskell, functions are pure, so actually you do know exactly what doSomething consumes, and it doesn't matter what getResult consumes or doesn't because that is totally circumscribed by the result type of doSomething. This might be a problem in impure languages, but I do not think it is a problem in Haskell.
Oh! I hope I wasn't bemoaning too much -- that was the lead-in, but it's mostly about what I really like about the language (and had some examples but I also didn't want to write a tutorial).
Sorry to hear that. I built it that way because I prefer reading narrower columns of text (maybe because I read a lot of magazines and newspapers, who knows).
I'm not sure that's entirely true (I wrote the examples): the point I'm trying to make is that you can precisely describe what `doSomething` consumes and produces (because it's pure) and you don't have to worry about what some nested function might throw or some side-effect it might perform.
> - how easy is it to make a web application with a hello world endpoint?
If that's all you want it to do, it's very easy with Wai/Warp.
> - How easy is it to auth a JWT?
We don't use JWTs, but we did look at it and Servant (which is a library for building HTTP APIs) has built in functionality for them.
> - Is there a good ORM that supports migrations?
There are several with quite interesting properties. Some (like persistent) do automatic migrations based on your schema definitions. Others you have to write migration SQL/other DSL.
> - Do I have to remodel half my type system because a product owner told me about this weird business logic edge case we have to deal with?
I think that's going to really depend on how you have structured your domain model, it's not a language question as much as a design question.
> - How do I do logging?
We use a library called Katip for logging, but there are others which are simpler. You can also just print to stdout if you want to.
We do use other ecosystems, yes. I haven't really found the tooling for Haskell to be particularly obstructive compared to other languages. I've run into plenty of mysteries in the typescript, python, ObjC/Swift, etc. ecosystems that have been just as irritating (sometimes much more irritating), and generally find that while HLS can be a bit janky, GHC is very good and I spend less time scratching my head looking at a piece of code that should work but does something wild than in other languages.
Instead this will put all browsers on a much more even playing field, and perhaps it will force governments and citizens to realise that free software takes someone to write it.