Live data from Hacker News

Pedagogical Downsides of Haskell

ciobaca.substack.com

61–70 of 118 posts

Re: Pedagogical Downsides of Haskell

#61

The pedagogical downside of Haskell is that it ignores the physical reality of the machine. Physically, a computer is imperative, has mutating state, and is filled with all kinds of possible race conditions. Even after you apply the operating system, allowing processes to live together (and giving you space to define new ones), very few constraints are placed on your program and process space. Instead of building on…

> Abstractions can be beautiful, but they are ephemeral, changeable, unreal

Where can we find 'no abstractions' these days? Even if you write in ASM, there will be tons of abstractions. Instructions will run out of order. Memory is abstracted. Even the ASM you write will be translated to microcode.

The closest you'll ever find to 'the physical reality of a machine' are microcontrollers (and even then, only some of them) and machines from the 80s. I have one sitting right next to me that I can tell you exactly how many cycles every CPU instruction takes.

Everything else is an abstraction. C abstracts a machine that doesn't exist(it was closer to machines that did exist at the time it was created). Even something as simple as a short circuit expression in your IF statement is an abstraction. Even in C you have to sometimes fight the abstractions when you are trying to, say, use caches effectively.

Re: Pedagogical Downsides of Haskell

#62

I find its syntax & idiomatic style incredibly difficult to follow, in a way nearly no other languages have been for me, including some functional languages (OCaml doesn't seem nearly as bad to me, for instance). It's sometimes implied that those who trip over Haskell just aren't big-brained enough to understand various important concepts related to it, but I've found they're usually very easy to grasp, provided the…

I find the terminology that Haskell uses quite misleading for software engineering. It borrows concepts from category theory with quaint names such as a "monad", "endofunctor", "catamorphism", etc. The problem is that, instead of a "monad", we can say "brrrdogcogfog" and nothing will change -- the name is absolutely irrelevant to the problem being solved. Given that a monad is an interface for sequential computation,…

A monad is just a monoid in the category of endofunctors. Would most people know what "brrrdogcogfog" means? Couldn't we make that argument about literally any word? I don't see why it applies more here than elsewhere. For people who have experienced it before, it's straightforward and easy to work with, for those who haven't, then there's a learning curve. No one would likely have encountered "brrrdogcogfog" before and everyone would have to go through the learning curve.

Re: Pedagogical Downsides of Haskell

#63

I wonder if there could be a (or already is) a "teaching" Prelude designed for this purpose. One of the reasons the standard Prelude includes partial functions and specialize versions of `map` and `filter` is to support the pedagogical use-case (as far as I understand the situation). Most production applications will use a custom Prelude of some kind in order to prevent programmers from using foot-guns like `head` or…

I don't know if there is one already, because the Haskell community generally heads in the other direction with its alternate Preludes.

But the effort to fix up the fixable issues mentioned in the post is about the same as writing the post was. Getting it distributed to the students may be a bit harder, depending on the local setup.

But it's definitely fixable with Haskell as it is today.

Linked lists are particularly tricky in Haskell, because as a data structure manifested in memory, they really stink. But as a lazy data structure traversed exactly once and thus just serving as a mechanism for providing "the next thunk", they're fine. Haskell and its laziness completely conflates the two of these, so it ends up being easy to think you have one and end up with the other.

Re: Pedagogical Downsides of Haskell

#64

Earlier quoted context omitted.

I'm sorry to break it to you but every single programming language in existence ignores the physical reality of the machine. That's the point of abstractions such as programming languages.

There are abstractions which build on the inherently stateful nature of computers with their instruction pointers, registers, memory and peripheral devices, and there are abstractions which coerce you into framing any computational problem like a mathematical formalism.

Yes, this is essentially it. There's a shape to the causal connections in the real machine that must be respected at higher levels of abstraction. In particular, the shape I mean is that basic mechanism of computation where you have a program counter, instructions and data in mutable memory (von Neumann), and a CPU with registers that "starts on the upper left" of memory, and leaves interesting shaped smears behind when it's done.

On top of this machine shape the OS adds a process abstraction, and a method to speak to devices. It is not coincidence that this process shape looks like the machine shape: lines of source correspond to instructions, declared structures correspond to main memory.... And from here we programmers pick a coordinate system and begin to build. But whatever coords we pick the space, the degrees-of-freedom, always the same: as vast as Turing could fathom. The interesting part of coordinate systems is the kinds of shapes you get for the constraints you picked. But Haskell seems to be a coordinate system with some valid constraint ideas (clear division between purity and side-effect, immutability), but an invalid sense of its identity as merely one coordinate system within this larger structure.

Re: Pedagogical Downsides of Haskell

#65
post #63

I wonder if there could be a (or already is) a "teaching" Prelude designed for this purpose. One of the reasons the standard Prelude includes partial functions and specialize versions of `map` and `filter` is to support the pedagogical use-case (as far as I understand the situation). Most production applications will use a custom Prelude of some kind in order to prevent programmers from using foot-guns like `head` or…

I don't know if there is one already, because the Haskell community generally heads in the other direction with its alternate Preludes. But the effort to fix up the fixable issues mentioned in the post is about the same as writing the post was. Getting it distributed to the students may be a bit harder, depending on the local setup. But it's definitely fixable with Haskell as it is today. Linked lists are particularl…

Definitely. Linked lists are great for pedagogy and useful in many applications. I think it’s a bit of a sign that the struggle between pedagogy and practice can lead to suboptimal outcomes for both parties.

Re: Pedagogical Downsides of Haskell

#66

I find its syntax & idiomatic style incredibly difficult to follow, in a way nearly no other languages have been for me, including some functional languages (OCaml doesn't seem nearly as bad to me, for instance). It's sometimes implied that those who trip over Haskell just aren't big-brained enough to understand various important concepts related to it, but I've found they're usually very easy to grasp, provided the…

I find the terminology that Haskell uses quite misleading for software engineering. It borrows concepts from category theory with quaint names such as a "monad", "endofunctor", "catamorphism", etc. The problem is that, instead of a "monad", we can say "brrrdogcogfog" and nothing will change -- the name is absolutely irrelevant to the problem being solved. Given that a monad is an interface for sequential computation,…

tl;dr -> I agree that the terminology is probably not something that enhances cohesion amongst devs using Haskell, and certainly can be distracting in a pedagogical setting.

I think the fact your experience leads you to believe that a monad is an interface for sequential computation. A monad is often used for ordering computations, but Haskell’s monads can also be commutative (like the Reader instance of monad) which do not order anything.

The real issue is that the naming convention where some typeclass is named after a concept in category theory means wildly different things to different developers. For instance, I would expect a type/typeclass named for some categorical construct to behave in the way the categorical construct behaves and that would be the extent of what I use it for. However, some developer may see a particular usage the same construct and extrapolate that said construct is intrinsically tied to that algorithmic pattern of usage.

So the problem is controlling expectation and managing consistency throughout the dev community. I doubt Haskell will ever get away from the category theory inspired libraries and the subsequent naming conventions. See the relatively lively development of the profunctor optics based work. But, I can certainly see how it may distract or confuse newcomers.

Re: Pedagogical Downsides of Haskell

#67
post #42

Earlier quoted context omitted.

Technically, within the language, yes. C itself simply delegates a lot of logic to the "physical machine"[1] by leaving it unspecified or implementation-defined. In contrast, Haskell actually tries to model these differences within the type system and standard libraries, with IORefs, STMs, and whathaveyou. (In fact, I just checked the IORef documentation and it actually references the x86/64 architecture manual to ex…

I see. The language spec explicitly talks about the machine. That's not nothing. In practice, though, when I have some piece of memory-mapped hardware attached, and I want to talk to it, in C I can say: *(uint32_t*)0xF00BA4 = 0x0102ABCD; or whatever I need to flip the bits. C lets me actually control the whole machine. Whereas Haskell... I don't know, but I suspect it lets me actually use the physical machine a lot l…

There might be a cleaner way of doing it, but

    do
      let ptr :: Ptr Word32 = nullPtr `plusPtr` 0xF00BA4
      poke ptr 0x0102ABCD
should have you covered.

Re: Pedagogical Downsides of Haskell

#68
post #48
post #5

Point 11 surprised me. Not the “go” thing but the “where” syntax – I wish more languages had it!

Yes. Where is often lovely -- I want to delegate details, and not think about them yet, but keep that delegation scoped to the function that needs the relevant details. But calling auxiliary functions "go" is almost always bad naming.

"go" is a fantastic name for communicating that all you're doing is exactly what the containing named definition promises. It's a lot better than adding "Worker" or "Impl" as a suffix of the same name as the parent. It contains no additional information because there's no additional information to contain - the parent name already says it all. So you might as well make it short and a standard idiom.

Re: Pedagogical Downsides of Haskell

#69

I find its syntax & idiomatic style incredibly difficult to follow, in a way nearly no other languages have been for me, including some functional languages (OCaml doesn't seem nearly as bad to me, for instance). It's sometimes implied that those who trip over Haskell just aren't big-brained enough to understand various important concepts related to it, but I've found they're usually very easy to grasp, provided the…

I find the terminology that Haskell uses quite misleading for software engineering. It borrows concepts from category theory with quaint names such as a "monad", "endofunctor", "catamorphism", etc. The problem is that, instead of a "monad", we can say "brrrdogcogfog" and nothing will change -- the name is absolutely irrelevant to the problem being solved. Given that a monad is an interface for sequential computation,…

F# calls them Computation Expressions which is far more approachable imo

Re: Pedagogical Downsides of Haskell

#70

I find its syntax & idiomatic style incredibly difficult to follow, in a way nearly no other languages have been for me, including some functional languages (OCaml doesn't seem nearly as bad to me, for instance). It's sometimes implied that those who trip over Haskell just aren't big-brained enough to understand various important concepts related to it, but I've found they're usually very easy to grasp, provided the…

I find the terminology that Haskell uses quite misleading for software engineering. It borrows concepts from category theory with quaint names such as a "monad", "endofunctor", "catamorphism", etc. The problem is that, instead of a "monad", we can say "brrrdogcogfog" and nothing will change -- the name is absolutely irrelevant to the problem being solved. Given that a monad is an interface for sequential computation,…

As I understand it, monads help solve the problem of sequential computation in Haskell but the concept is not limited to that. For example, how would you consider the monadic properties of data type like Maybe or Either to be (exclusively?) interpreted through the lens of sequential computation? What about commutative monads where the order doesn’t matter?
Post reply on HN