3 ms·
Part of the reason I enjoy languages like Haskell is because of the abstraction maximalism enshrined at the language level, rather than the coding level. We al
by hiAndrewQuinn 3y ago
Part of the reason I enjoy languages like Haskell is because of the abstraction maximalism enshrined at the language level, rather than the coding level.
We all agree on what an Applicative is supposed to do. The challenge shifts right in the idea-to-code pipeline to finding the right Applicative for the problem. Most OO design patterns have natural, well defined equivalents in such an environment, but the difference is this way helps minimize the amount of project specific abstractions you have to deal with.
The downside as a beginner is of course a greater upfront cost to learning the language, and quite frequently opening up another Haskeller's work and realizing there are like 12 compiler extensions you've never heard of that you now need to grok. But even there I would argue that's a net win: you can carry those compiler extensions with you to all projects in the future. (The downside as an expert is realizing you have to get a PhD to get a sense for how much RAM your cats will gobble up!)
- pluto_modadic 3y agooh, oh my. The golang opposite where you don't have language extensions and should be able to grok everything about the language in your head all at once... yeah I'm going with "simpler language".
- hiAndrewQuinn 3y agoI'm not dissing Golang, I use it actively, both at work and in my own projects. There's a lot to like about it. There's also a lot to like about Haskell. Complaining about something which you don't understand isn't a good look on anyone, though.
- Dylan16807 3y agoCould you please address the tradeoff if you're going to post on the issue, and not a specific bullet point? How do you feel about the increase in project-specific abstractions in Go? Or do you disagree with that framing?
- tejinderss 3y ago> The downside as an expert is realizing you have to get a PhD to get a sense for how much RAM your cats will gobble up. Go one step further with affine types and use Rust. You get haskell type system with predictable performance.
- ReleaseCandidat 3y ago> You get haskell type system No. When trying to use Rust's traits like Haskell you learn really fast why higher kinded types are needed.
- hiAndrewQuinn 3y agoOh, wait, does Rust not have kinds? That's a bummer.
- zozbot234 3y agoRust has GAT's which have the same expressivity as HKT's. But many Haskell patterns turn out to be unidiomatic in Rust due to extra overhead. (For instance Rust has multiple function-like traits that access their environment differently. There's no equivalent to this in Haskell of course; GC and default boxing choices for Haskell types obviate the issue, but this is not zero cost.)
- deleted 3y ago[deleted]
- adastra22 3y agoWhat is Rust missing out on?
- hiAndrewQuinn 3y agoI know, I know. It's very silly of me not to pick up Rust when I've already got all of its forbearers in my bones. Someday, once I've finished studying everything else I need.
- kreetx 3y agoAs a fellow haskeller, I agree on that the language has very good abstraction capabilities. On the specific example in the blog post though I can only say that there are so many times I've been down the clean code path and it's more often not another person, but the future you, into whose foot you are shooting. Abstraction is not beneficial when you need to study it later to understand it again.
- hiAndrewQuinn 3y ago> Abstraction is not beneficial when you need to study it later to understand it again. This is where a good study routine comes in. I study Haskell like I study all things of any long term importance, using an Anki deck. It takes me longer to start using a new abstraction, but once I have it it's pretty much there for life, due to my daily commitment of half an hour or so to my reviews. It makes far less sense, of course, to do this for a one-off abstraction I had to apply to a specific project, so this naturally tilted me over the years to work more and more in loss like Haskell. (N.B., I do not state this as a prescription. I think this is well above and beyond what most people expect of themselves professionally, and that is okay. Everything in life comes with tradeoffs.)
- Aaronmacaron 3y agoThis is really interesting to me. What exactly do you write on the anki cards? I cannot really image learning a haskell abstraction by mere memorization. How can you learn it without actually applying it to a real problem. Often times the hard part is to know when to use which abstraction. How do you learn this using flashcards?
- hiAndrewQuinn 3y agoWhat you detail is pretty much how you would recognize it. You write out a brief summary of the high level problem, and then ask yourself "which abstraction would you reach for first, absent any other information?" The latter part is often implied, but it's best to make it explicit. You're trying to build up expert intuition, which means allowing for the fractal nature of software development to mean you might be in the 20% of times where this won't work for you.
- tiew9Vii 3y agoWe know what Applicative and Monad (forgetting the burrito) do because the have mathematical LAWS. If a piece of code uses Applicative or Monad you know it’s behaviour due to the Applicative/Monad mathematical laws. No OO design pattern has a law, they are a loosely defined concept/pattern which means they are open to personal interpretation/customisation but no concrete law to say exactly what it is and its expected behaviour/output.
- ReleaseCandidat 3y ago> If a piece of code uses Applicative or Monad you know it’s behaviour due to the Applicative/Monad mathematical laws. Well, we actually only know what it is supposed to do. The laws are not enforced, so it is perfectly possible to implement a type class that violates the laws of the type class.
- Quekid5 3y agoSeveral test frameworks implement Law Testing which will test your instances for lawfulness as long as you can generate instances of your data structures. E.g. https://hackage.haskell.org/package/hedgehog-classes https://hackage.haskell.org/package/hedgehog-classes . So you only need to be able to generate instances and you get comprehensive tests for free, so that's nice too. It is also the case that implementations of these very abstract classes typically only also have very few implementations that make any kind of sense type-wise and that the 'obvious' one is correct. (Just to preempt: Yes, tests aren't proof, but such is life without a full proof system in the language. In practice, I've found property-based testing sufficient.)
- ReleaseCandidat 3y agoOh, I know and I'm not arguing against anything you've said. I just wanted to express - for people who don't know Haskell - that while the laws exist, they are not (as of now ;) enforced or checked by the type checker.
- 3y ago
- karmakaze 3y agoThe OP would have done better to use more OOP principles, unless eschewed by the team in general--then I'd probably work elsewhere. The place where OOP has the most natural fit is implementation of GUI widgets and their editors. I've written a few myself. The 'rule' that unifies OOP's other rules is tell-don't-ask. So for the example at hand we have the handles which are shared in a known way and I presume shape-specific control points (e.g. circle may have center, radius). Then a change of a box handle could call a updateControlPoints(changedHandle). There would also be updateBoxHandles(changedControlPoint). There may be other clean splits, but that's how I'd do it.
- Tainnor 3y ago> We all agree on what an Applicative is supposed to do. Maybe. But not on which parsing library to use (parsec? megaparsec? attoparsec? regex-applicative?), on whether to use Data.Text.Strict or Data.Text.Lazy, on how point-free the code should be, on whether to use "." or ">>>" or any other combinators, on which language extensions to use... I like Haskell, but it suffers from similar problems as any other language: people can't really agree on the best way to do things