5 ms·
So, I’ve programmed in Haskell and Clojure and I really wish people would give over on the Haskell requires category theory meme. What Haskell offers is _gener
by moomin 8y ago
So, I’ve programmed in Haskell and Clojure and I really wish people would give over on the Haskell requires category theory meme.
What Haskell offers is _generalisation of abstraction_. So, the function that satisfies the behaviour of fnil is called fmap, but it’s also the function that maps a function over all the values of a list, or the return values of a function. Equally, the equivalent of some->> (do notation) works for all of the above and more.
None of this requires you to know what a Kliesi category is.
- dmead 8y agoThis is an important point to stress. However the moment people want to get more complicated than bind and return while doing IO the "C" word inevitably creeps into scope. So while you don't need to know anything about abstract algebras to do Haskell, that knowledge is lurking so close to the surface that it is really more of an issue than is generally acknowledged.
- yogthos 8y agoWhether you need to know category theory or not, the reality is that Haskell is a much more complex language than Clojure. My team works with Clojure, and we regularly hire co-op students who typically have no exposure to FP. They're able to to start writing useful code within a couple of weeks or so on average.
- Peaker 8y agoI've mentored programmers in Haskell and they were also productive within a few weeks. I'm pretty sure I could get a student to write useful Haskell code in that time span with just mentoring and existing documentation material.
- moomin 8y agoI think the thing is, if you want to write at a Clojure-level-abstraction, Haskell won’t stop you doing that and I get the impression that it’s actually the way a lot of Haskell programmers operate. (Chas Emerick has recently been advocating this approach and I get the impression it’s actually the style of GHC itself.) We don’t all have to be at EK, BM or GGs level.
- yen223 8y ago> I think the thing is, if you want to write at a Clojure-level-abstraction, Haskell won’t stop you doing that Unless Haskell drastically fixed its record syntax recently, this is definitely not the case.
- moomin 8y agoYeah, Clojure’s “labels are values” map stuff is pretty nice.
- Peaker 8y agoHaskell record syntax with lenses is workable: import Control.Lens data MyRecord = MyRecord { _a :: Int, _b :: MyRecord } makeLenses ''MyRecord Then you can use it nested like: over (b . b . a) (+5) myRecord
- tome 8y agoClojure people use the untyped equivalent of row types, i.e. being able to arbitrarily add and remove fields to and from a record. That would be nice to have in Haskell (though personally it's nowhere near a dealbreaker for me).
- Peaker 8y agoHaskell has reasonable implementations of row types as well.
- yogthos 8y agoUnfortunately, that doesn't match my experience at all. Haskell requires understanding many more concepts to use effectively than Clojure. Lazy evaluation, large syntax, and the advanced type system all add complexity. My experience is that it takes people a long time before they're able to read and write idiomatic Haskell code without assistance. With Clojure, we're able to do a very quick ramp up, and then have new hires write code with very little assistance from the rest of the team. I simply haven't seen this be the case with Haskell even for experienced developers.
- Peaker 8y agoI suspect the problem is mentoring. It took me months to get basic Haskell. The people I mentored, though, could clarify any misunderstanding and get explanations from multiple viewpoints from me -- after years of experience with these abstractions. With such mentoring, you don't have to go through all the confusion phases.
- yogthos 8y agoThe core point here is that Haskell is a more complex language that requires understanding and applying more concepts to write effective idiomatic code. Mentoring does help, but you still need to build a mental model of using the language, and there isn't a shortcut for that. Clojure requires a smaller mental model than Haskell, and that makes it easier to learn. The end result is that you have to spend less time ramping people up. If Haskell works for your team that's great though, it did not work for mine.
- mikekchar 8y agoWhen taken in the context of programming in Haskell, category theory is not really that important IMHO. Yes, the words are strange, but once you know what they mean, they are just words. For example (again, in the context of programming) a functor is just a collection with a function that removes the contents out of the collection, transforms it (into anything) and puts it back into the collection. A monoid is just a functor (ie collection) that can hold zero or more values. A monad is monoid (collection that can hold zero or more values) with a function that takes the contents out of the collection, transforms it into something of the same type and puts it back into the collection. Category theory is really just useful because it shows you the building blocks. Some functors are not able to be used as monads. It's useful to have some intuition as to why. Even some things like applicative (a functor with a function in which you can successively apply multiple parameters) pop out and give you some useful insight (non-applicative functors can't be monads -- it's not obvious why until you try to implement it). There is value in this organisation. The words are not fantastic, but again, they are just words.
- stcredzero 8y agoSo, I’ve programmed in Haskell and Clojure and I really wish people would give over on the Haskell requires category theory meme. What Haskell offers is _generalisation of abstraction_. So, the function that satisfies the behaviour of fnil is called fmap, but it’s also the function that maps a function over all the values of a list, or the return values of a function. Equally, the equivalent of some->> (do notation) works for all of the above and more. None of this requires you to know what a Kliesi category is. These three paragraphs are unintentionally enigmatic and emblematic! Literally, the only thing I understood in the 2nd and 3rd paragraphs was, "What Haskell offers is generalization of abstraction." It's as if some large fraction of the Haskell community is significantly lacking self-awareness of how its own PR comes across. Been there and done that, just with Objects. EDIT: Which is to say, A community that engages in such lack of self-awareness is dooming itself to hipster obscurity.
- hnzix 8y ago“A Monad is just a monoid in the category of endofunctors, what’s the big deal?”
- moomin 8y agoOkay, let’s make concrete what I said about fmap. Let’s say we have a function addOne. Then > fmap addOne Nothing Nothing > fmap addOne (Just 2) Just 3 > fmap addOne [1,2,3] [2,3,4] > fmap addOne parseInt (A function that reads a string for an int and adds one to the result.) So fmap is polymorphic over a whole bunch of things that are unrelated in most other languages. (You might be asking why it’s called fmap and not map, and I wouldn’t have a good answer for you.) So, the abstractions of “Nullable, List and Function Return Value” are all part of a more general abstraction, Functor. Now, at this point some people try to look up what a category theoretic definition of a Functor is. That’s fine, more power to their elbow. However, really all a Functor is in a practical sense for a dumb programmer like me is _something that supports fmap_. My point is, it’s this stuff that’s useful and cool in Haskell. It won’t help you understand whatever they’re talking about on r/Haskell. And my only point about Kliesi categories is that you don’t need to know what they are. There’s a million and one interesting computer science concepts that are usable with a type system with Haskell’s properties, but you don’t have to use them all.
- _halgari 8y ago"Generalization of abstraction" sounds a lot like "a maze of twisted passages, all alike" That's exactly what I don't like about some languages, if everything is a function, then it's all a big ball of mud. The only thing you can do with a function is call it. I'd rather have classes of capabilities. Some things are callable, others are iterable, some are printable. But if it's truely about abstraction generalization, that sounds like a mess.
- joel_ms 8y ago> if everything is a function, then it's all a big ball of mud. Not really, each distinct function will still have a distinct type. (This is largely why I prefer ml-family languages over lisps) >The only thing you can do with a function is call it. You can also abstract over it, and pass it around. Which allows you to build whatever you want, numbers, booleans, if-then-else, etc. The combination of function as your basic unit of abstraction and types as the differentiating descriptor is kind of the opposite of a mess, as you have a correspondence to familiar logic operations. A function type A -> B is implication (given A, we have B), a product type (A,B) is conjuction (A and B), a sum type A|B is disjunction (A or B). (Sure, the logic isn’t necessarily sound, but it’s still useful). When you have the fundamentals down you can build whatever capability system you need on top of solid abstractions. I’m currently working on an ETL-project in haskell and it’s structured around a similar capabilities divide as you describe, defined by typeclasses/interfaces, it’s just all functions.
- joel_ms 8y ago(Edit: The citation got messed up, it should be: >The only thing you can do with a function is call it. You can also abstract over it, and pass it around. Which allows you to build whatever you want, numbers, booleans, if-then-else, etc.)
- tempodox 8y agoKleisli
- moomin 8y agoYou’re right, I’ve been saying “Cleezy”. Should have been saying “Clighzly”