6 ms·
> Haskell is simple That it might be, but it sure as hell isn't easy. Brainfuck is simple, but nobody would choose to write a real project in it. Most program
by atilaneves 8y ago
> Haskell is simple
That it might be, but it sure as hell isn't easy. Brainfuck is simple, but nobody would choose to write a real project in it.
Most programmers struggle trying to understand what a monad is. That's not easy.
The free monad is not easy.
Monad transformers are not easy.
Understanding foldable/traversable/arrows/applicate is not east.
Lens is/are not easy.
I have personally worked with dozens of programmers that would never be able to write "proper" Haskell.
- hardwaresofton 8y agoComparing Haskell to brainfuck is a little hyperbolic -- you do not have fully understand Monads and their underpinnings to be productive in Haskell. Just like when new programmers write "public static void main" and have no idea what it does, or how JAR files work, or how cout works, newbies can type `do` and get off and running. In Haskell most of your time is spent writing non-monadic code -- writing pure functions that don't care about the outside world. Another important distinction I want to draw is that while you're that Haskell isn't easy, the difficulty contained within is fundamental to computation itself. Haskell uses it's type system to buddy-up with category theory which is considered a dual to typed lambda calculus[0]. There are spooky (to me at least, less so to actual mathematicians) natural equivalencies here in that there are certain things you can talk about at the level of Haskell types (category theory) that are universal, and since we're talking about computation, they start becoming universal truths about computations. This is a powerful concept because it changes the way you think about problems. Regardless of whether it's useful in your day job (which might be plumbing two RESTful APIs together) -- I'm not trying to convince anyone to use haskell for everything (you should use the right tool for the job given the constraints), I'm trying to encourage people to try it at least once to see the difference. Haskell in my mind offers a step stool to understand the deeper theory/mathematics underpinning of computation as a whole, by providing a language that can essentially do both -- express complex concepts and actually do useful things -- it's somewhere on the opposite end of the spectrum from assembly, but not as far as a pen and paper/chalkboard/your mind. To follow on the point above, all the concepts you're discussing as hard are what we're building in other languages -- the other languages are just giving us versions of the power/expressiveness with corners cut for ergonomics sake, or in the worst cases, drastically reduced power. There is a tradeoff, and it obviously does not always make sense to use Haskell's version of some abstraction, if you do not understand it or it takes you 5x as long to code up. That said, knowing the underlying concepts that underpin these things is the kind of knowledge you can take from project to project -- concepts like traversable show up in file/folder walking, graph traversal, all these problems that you might think were not generically solvable if you only ever dealt with libraries that worked at the lower level (as in one library for walking graphs and the other for walking the filesystem). You're right that understanding the concepts isn't easy, but this is the best kind of understanding to struggle and overcome -- it's fundamental to the field itself. No one is going to come up with a new Monad/Foldable/Traversable tomorrow, they can generally at best discover new concepts. > I have personally worked with dozens of programmers that would never be able to write "proper" Haskell. As long as these programmers learn the paradigms I don't care, use another language that's easier to write. The problem is that you can happily write language x for years and never scratch the surface of these deeper truths/paradigms/approaches, but that doesn't mean it's a good idea for your own personal development as a developer/computer scientist/whatever else. If you don't see value in exploring different, likely fundamental ways of thinking about computing then you do you. Maybe it's just me, but I see value in languages that expand the way I think -- just like that aha moment when I figured out how to use map/filter/reduce instead of writing for loops. I learned to think in transformations, one step abstracted from the imperative reality. Haskell may not be for everyone, but the paradigms it exposes are for all computer scientists (as far as I can tell anyway), and thus software developers/engineers who want to work smarter and not harder. [0]: https://math.stackexchange.com/questions/589311/lambda-calculus-and-category-theory https://math.stackexchange.com/questions/589311/lambda-calcu...
- atilaneves 8y ago> you do not have fully understand Monads and their underpinnings to be productive in Haskell I don't think that's true. Most programming is done in a team, and someone will have written a transformer stack. I was told to use the free monad to solve my testing problem in my first Haskell program. "Hello world" doesn't count. > the difficulty contained within is fundamental to computation itself. Not always. The examples I gave are all of what I consider to be "unforced errors". I don't need monad transformers in any other language I've written code in. Or lens. Or arrows. Or free monads. Or... > I'm trying to encourage people to try it at least once to see the difference. I did. Hence me even knowing what lens is. > concepts like traversable show up in file/folder walking, graph traversal, all these problems that you might think were not generically solvable if you only ever dealt with libraries that worked at the lower level (as in one library for walking graphs and the other for walking the filesystem). Honest question: how is knowing Haskell's traversables (which are hard) going to add to one's knowledge if one has already worked with any of the following: * C++ iterators * Python iterables * D ranges * C++20 ranges * (I think) Clojure's transducers? Sure, Python and Clojure are less applicable due to being dynamic, but D and C++? Generic. Same goes for foldable. > As long as these programmers learn the paradigms They wouldn't be able to. I say this as someone who somehow managed to take a student who didn't know how to add fractions together and tutor him to the point of (just) passing a university Linear Algebra class. > Maybe it's just me, but I see value in languages that expand the way I think So do I. Trying to learn Haskell was enlightening. I can't see me picking it as the tool of choice for pretty much any project though. > software developers/engineers who want to work smarter and not harder. When I wrote Haskell I found myself working harder, writing bugs anyway and wondering what the point was. It's intellectually interesting, and worth looking into. I just don't want to write in it.
- hardwaresofton 8y ago> I don't think that's true. Most programming is done in a team, and someone will have written a transformer stack. I was told to use the free monad to solve my testing problem in my first Haskell program. "Hello world" doesn't count. Right but there isn't any other language where a production application will be obvious to newcomers anyway. There is always some cruft/enterprise design pattern/whatever else that will need to be learned or at least hand-waved for early productivity, and will be deeply understood later. My point was that you don't have to understand what "do" does. If you get some simple feature let's say update the user wiggle count when any friend wiggles), the chance you're going to be editing legible, clear haskell (given you understand how to read haskell) is high. Something like: -- | do a user wiggle and return the wiggle count doWiggle :: User -> IO WiggleCount doWiggle user = do _ <- saveWiggleToDB user wiggle <- updateWiggleCount user -- here's where the newbie would probably start thinking to add some code return wiggle While this code is just a fake example, it's concise, and very legible -- you don't need to understand the complexities of the IO monad or any other stack that would be there, haskell can mimic the simplicity of a completely imperative monad-less environment, down to the `return`. > Not always. The examples I gave are all of what I consider to be "unforced errors". I don't need monad transformers in any other language I've written code in. Or lens. Or arrows. Or free monads. Or... But see this is the the whole point of the discussion of the relationship between lambda calculus and category theory. You're using most of these concepts already, you're just calling them something different, and wrapping them in some unnecessary ceremony/enterprise design pattern. Or even worse, you're using weaker, partial, worse approximations of these concepts and don't know it. Ignorance is not bliss in our line of work -- whether or not you use the concepts I (at least) expect good programmers to know the underpinnings. > I did. Hence me even knowing what lens is. I can't argue with your personal experience -- if you don't think learning that stuff was beneficial then there's nothing I could say to change your mind. My argument hinges on the fact that those concepts are beneficial and haskell shows them to you without much adulteration faster than other languages. > Honest question: how is knowing Haskell's traversables (which are hard) going to add to one's knowledge if one has already worked with any of the following: It adds to one's knowledge the same way knowing the Iterator/Iterable pattern exists instead of having used for loops in any of those patterns. It adds to one's knowledge the same way reading the gang of four book does, or any theoretical computer science does. Traversable is roughly identical to the iterator patterns but it is the purified form of the concept -- you don't get bogged down with how python iterates or some other language and how they built their iterator implementation. > They wouldn't be able to. I say this as someone who somehow managed to take a student who didn't know how to add fractions together and tutor him to the point of (just) passing a university Linear Algebra class. I don't consider myself an optimist, but I think you're wrong. If you were right, growth would be impossible for humankind. A more useful statement IMO might be that the amount of effort and focus one would have to put in is beyond what they could exert in the amount of time they have to devote (or their lifetime) -- but even then that's a hard statement to prove. > So do I. Trying to learn Haskell was enlightening. I can't see me picking it as the tool of choice for pretty much any project though. I mean that's OK though -- hopefully you picked up some things that were useful to you. Haskell ergonomics or practicality (basically, language features) is something that the Haskell community has to work on and make better. > When I wrote Haskell I found myself working harder, writing bugs anyway and wondering what the point was. It's intellectually interesting, and worth looking into. I just don't want to write in it. Again, I can't argue with your personal experience, but I can tell you that if you're using haskell's type system at all correctly what you're saying just can't be true. It's just not how it works -- for example, you probably have never gotten an NPE in Haskell -- it's a class of errors that doesn't exist for the most part. The errors you were getting (or maybe compiler feedback?) isn't the same as in other languages.
- lmm 8y ago> Brainfuck is simple, but nobody would choose to write a real project in it. Sure. But it's worth knowing whether a language is simple or not (and what tradeoffs have been made to get there). > Most programmers struggle trying to understand what a monad is. That's not easy. It's easier than achieving Haskell-like defect rates in languages that have ad-hoc built in solutions to the same problems, IME. > The free monad is not easy. Disagree. Certainly it's a lot easier than solving the same problem by hand. > Monad transformers are not easy. Agreed, but again, easier than achieving the same defect rates without them. > Understanding foldable/traversable/arrows/applicate is not east. Easier than understanding dozens of ad-hoc informally specified implementations of half of them, which is what working in an ecosystem without them boils down to. > Lens is/are not easy. Perhaps not, but easier than achieving the same defect rate without them.
- atilaneves 8y ago> It's easier than achieving Haskell-like defect rates in languages that have ad-hoc built in solutions to the same problems, IME. My first Haskell program type-checked and passed all tests. It was incredibly broken. As in it didn't work at all. I understood monads and it didn't help one jot. Monads in other languages _can_ be helpful. It pays off to know what one is. But in Haskell, more often than not they're being used to solve problems other languages don't even have in the first place. > Disagree. Certainly it's a lot easier than solving the same problem by hand. How? Anyone knows how to write a test double by hand. Most people can use a mocking framework. The visitor pattern is in the GoF book. These are well known and don't involve completely changing the type signature of the code you're writing just so you can interpret it. And let's not even mention Lisp. > Agreed, but again, easier than achieving the same defect rates without them. Not really. Write pure code, test it, have a thin layer of side-effects around it. The transformer stack is solving, again, problems only Haskell has. I don't need the state monad anywhere else, so I don't need to layer it on top of anything. In a language with exceptions, ditto. And so on. > Easier than understanding dozens of ad-hoc informally specified implementations of half of them, which is what working in an ecosystem without them boils down to. I would bet good money that in my old team I wouldn't be able to explain what an applicative functor is to 90% of them if I had one month of full time training. > Perhaps not, but easier than achieving the same defect rate without them. Solves, yet again, a problem only Haskell has.
- agentultra 8y agoEasy for whom? Finding Haskell difficult is nothing to be ashamed of. However it's going to appear more difficult than it ought to be if you're approaching it as an experienced programmer with strong opinions. It can be humbling to realize that there's a whole branch of programming you're completely new to and know little about. It's going to be difficult to climb that mountain and you will feel like a beginner again and that's okay. It's worth the effort!
- atilaneves 8y ago> Easy for whom? Nearly everyone I have met and/or worked with. > Finding Haskell difficult is nothing to be ashamed of Agreed. > It can be humbling to realize that there's a whole branch of programming you're completely new to and know little about. Agreed. > It's worth the effort! To learn it? Sure. To use it? I disagree. I was more unproductive with Haskell than I've ever been with C, which is usually the language I love to bash on. I can look up opcodes and write assembly faster. "Ah, but with experience!" - I don't see why I'd bother. I write mostly functional code in any language I'm working in as it is. The functional parts of Haskell don't really have anything for me, at least not to compensate the pain of not getting anything done. Take lens, for instance. It's an incredibly complicated solution to a problem that AFAIK only plagues Haskell! I'd love to know of any exceptions. Writing networking code was an exercise in frustration where I had to try multiple libraries and faff about with changing types from eager to lazy bytestrings.. I'm glad I bothered to try and learn Haskell. I just don't see me ever using it in production, let alone try to hire anyone who knows it. It's hard enough finding Python programmers who know what generator expressions are.
- agentultra 8y agoIf we're only talking experiences here then I can say that I've written plenty of networking code in C. I grew up on C. I have 15+ years' experiencein C-like languages across the gamut; more if you count the years when I was a youth and hacking together games and homework assignments for fun. I've definitely felt the pain you're describing and have even thought of lens in the way you ascribe. How can anyone be productive in a language where logging is so difficult to add? I can add logging to a Python application in 3 lines. And as you say... converting from lazy to strict from text to bytestring to string depending on the library. So annoying! Nothing like those clean examples they show you in the tutorials! Every time I went down that rabbit hole was because I was getting frustrated with feeling like a beginner again. What was I getting from Haskell for all of this hassle? Why were these simple things in other languages so hard? What's the benefit? Peace of mind. It's easier to get started with a C or Python or Javascript program. Partly because of experience. Partly because those languages do nothing to isolate side effects, constrain mutation, or check my code in any effective way. I stick to a particular style (usually functional), I write tests first, and I usually end up paying for that easy start later on in the project when, despite our intentions and efforts; side effects, mutation, and plain old type errors creep in. What I gain in efficiency early on in the project I pay for later with interest. The interest rate is only compounded when we start adding team members. My experience with Haskell has been that it is frustrating and sometimes slower to get started with, especially when I was first starting out, but that it has been worth the effort in the long run. Down the road when my project started to grow I was better equipped to manage the complexity because I had a type system that kept me honest and guided me towards strong designs. I had a tool that would ensure that only the parts I was really sure about could perform IO actions or use shared mutable state. And best of all I could not touch a module for months and when I came back to it there's a good chance I could understand what it was doing, make the change I needed to make, refactor it, and push it to production without any worries. I think the human side of software development was the nicest feature of working with Haskell. As I added new team members I didn't have to worry about junior developers breaking the build as much. Training was much more straight forward. The documentation was much easier to write as we could focus on the higher-level designs and let the type system document the details. Testing was more effective as we could focus on problems and tests that brought more value to the business problems. I still choose other languages for various reasons but Haskell has been worth it in my experience. Painful but worth it.
- mbrock 8y agoWanna name a supposedly easy language and let’s see if we can come up with a list of things about it that are kinda difficult?
- atilaneves 8y agoAnd that would prove what, exactly? That no language is perfect we already know. My assertion is that, for the vast majority of programmers, Haskell is fundamentally harder than the languages they already know or could learn instead.