Unfortunately, while you may not have appreciated the tone of the Haskell interaction, they are correct in their assessment from a factual perspective. This explanation propagates a number of misunderstandings of the topics well known to be endemic to beginners. In particular, I observed the common belief that functors apply to "containers", when in fact they apply to things that are not containers as well, most nota…
One can start with a partial explanation and expand it cover all the cases as learning progresses. This is how most learning takes place. I expect your primary school teachers introduced numbers with the natural numbers, instead of, say, transfinite numbers. Students learn Newtonian physics before relativity. It's completely fine to build an understanding of monads as operating on containers, and then expand that und…
Functors, Applicatives, and Monads
61–70 of 90 posts
Re: Functors, Applicatives, and Monads
#62Earlier quoted context omitted.
> Monads seem to have this strange aura around them that attracts certain kinds of personalities Historical accident. There was a time, not very long ago, when we didn't know applicative functors were a useful separate subset of monads. We thought full monads were needed for all the neat things that applicatives are sufficient for. During this time, lots of ink was spilled over monads. Had we invented applicative fun…
Indeed it was not long ago that in the language there was no relationship at all between the Applicative class and the Monad class. And then one release Applicative was made the superclass of Monad. That's the reason why we have sequence and sequenceA, sequence_ and sequenceA_, liftM and fmap, ap and , liftM2 and liftA2, return and pure, traverse and mapM etc. All these pairs of functions do the same thing but are du…
After months of mailing list discussion and committee meetings. This is my go-to example for why I'd like a language with a push-out lattice of theories (path-independent accumulation of types, operators, laws). This should ideally "just work", no committees needed. Coding with math-like tight locality.
> This historical accident has, IMO, made the language harder to teach.
As LLM refactoring continues to improve, perhaps instead of current "here's an alternate prelude which cleans up historical mess for teaching", we might get to "here's a global refactoring of cabal and open docs to ..."?
Re: Functors, Applicatives, and Monads
#63Earlier quoted context omitted.
If I give you a function "f(x) := 3 * x", is it really that useful to talk about it as a container of the natural numbers? The reverse though is useful, a container looks like a function that takes one or more indices and returns a value or element.
I think that understanding the (moral) equivalence is useful in both directions. In particular, I think helping people understand the "function-as-container" analogy is a useful way for people to understand pure functions- another thing that's conceptually simple but a lot of people struggle to really wrap their mind around it.
But then I've never thought the concept of a pure function to be particularly difficult, despite growing up on procedural languages.
It's other bits that I struggle with when it comes to functional programming.
Re: Functors, Applicatives, and Monads
#64Unfortunately, while you may not have appreciated the tone of the Haskell interaction, they are correct in their assessment from a factual perspective. This explanation propagates a number of misunderstandings of the topics well known to be endemic to beginners. In particular, I observed the common belief that functors apply to "containers", when in fact they apply to things that are not containers as well, most nota…
Functions are just containers of calculations (the whole “code is data”). I don’t know why lists as values in a container would be confusing. Lots of very popular languages literally have box types which may not be exactly the same, but show that expecting containers to potentially commission complex data isn’t unusual.
The most widely recognised example, IMO, would be monadic parser combinators. "A parser for a thing, is a function from a string, to a list of pairs of strings and things."
Re: Functors, Applicatives, and Monads
#65This reminds me of https://www.adit.io/posts/2013-04-17-functors,_applicatives,... I think over the recent years, there's been a rise in typed languages that support functional programming like TypeScript and Rust. It will be interesting to see if this trend continues in the context of AI assistant programming. My guess is that it will become easier for beginners, and the type systems will help to build more robust p…
My guess is it'll be the opposite: I suspect compared to humans, LLMs will make fewer type errors, and more errors that are uncaught by types. Thus I expect type systems will be of lower value to them (compared to humans), leading to a shift toward dynamic languages and the possible extinction of typed languages.
The alternative I could imagine is moving toward Haskell-like languages with MUCH stronger type systems, where higher-level errors ARE type errors.
My one concrete observation in this direction: "press . to see valid options" behavior is a traditional strong point of typed languages. And interestingly, proved to be one the first thing that early/dumb LLMs were actually pretty good at. I believe that indicates LLMs are relatively good at type inference (compared to other things you can ask them to do), and we should expect that to continue being a strong point for them.
In working with Cline in both TypeScript and JavaScript, I find the LLM making tons of errors it has to go and fix in a future iteration, but virtually none of them are type errors.
I suspect LLMs are relatively good at duck-typed languages because they have a much bigger working memory than humans. As a result, the LLM can hold in working memory not just e.g., the function argument in front of them, but also all the callers of the function, and how they used the variable, and callers of the callers, and thus what "duck-type" it will be.
A system that can do this level of automatic type inference doesn't necessarily benefit from a formal, static, compile time type system.
Re: Functors, Applicatives, and Monads
#66Earlier quoted context omitted.
> Learn about higher-order functions, higher-kinded types, parametric polymorphism, and bounded polymorphism. Except that's not the case because most people know all of those concepts from their main language, and don't know what a monad is. Higher order functions yup. A function can take a funtion as an argument and correctly assign the argument type (unless C where you can finagle it but it's not first class). High…
I assure you, most people cannot tell you the difference between bounded polymorphism, parametric polymorphism, and whatever their language thinks polymorphism means. (The latter is not the same as either of those.) Most people cannot handle the idea of talking about an unapplied type constructor, because their language of choice cannot do that. Maybe the number of people who can think in higher order functions has r…
And yet most people know one of Java, C# and Typescript and know how to use generics with constraints. Meaning they know those concepts. Your arguing my point for me. Knowing those concepts clearly isn't sufficient.
There are three things being discussed that you are conflating. Knowing a concept, knowing it's terminology and knowing how to all of them combine when used in a new concept. Knowing the underlying concepts does not imply the first. And similarly not knowing the terminology does not imply someone does not know the concepts as you seem to think it does.
Re: Functors, Applicatives, and Monads
#67Earlier quoted context omitted.
> really hard [...] leap Two stepping stones might be array getters (function that's array-ish), and arrays with an indexed default value function (array that's function-ish)?
I've recently started writing a series of blog posts ( https://rebeccaskinner.net/posts/2024-10-18-dictionaries-are... ) trying to explain the idea and my approach has been to explain the idea using comprehensions. I haven't had a lot of people review the post yet, and I still have at least one if not two more follow-ups before it's done, so I'm not yet sure how well the idea will land.
Will you be covering common dictionary operations like adding/removing elements and iterating over the dictionary keys?
I have some ideas on how one might frame it in a pure function setting but they all seem quite contorted in a similar way to your incrementDict, ie you'd never actually do that, so curious if there are better ways. Then maybe you'll sell me on the premise.
Re: Functors, Applicatives, and Monads
#68Earlier quoted context omitted.
> really hard [...] leap Two stepping stones might be array getters (function that's array-ish), and arrays with an indexed default value function (array that's function-ish)?
I've recently started writing a series of blog posts ( https://rebeccaskinner.net/posts/2024-10-18-dictionaries-are... ) trying to explain the idea and my approach has been to explain the idea using comprehensions. I haven't had a lot of people review the post yet, and I still have at least one if not two more follow-ups before it's done, so I'm not yet sure how well the idea will land.
Curiously, I've a backburnered esolang idea of gathering up the rich variety of dict-associated tooling one never gets to have all in one place, and then making everything dict-like. Permitting say xpath sets across function compositions.
Re: Functors, Applicatives, and Monads
#69Earlier quoted context omitted.
I assure you, most people cannot tell you the difference between bounded polymorphism, parametric polymorphism, and whatever their language thinks polymorphism means. (The latter is not the same as either of those.) Most people cannot handle the idea of talking about an unapplied type constructor, because their language of choice cannot do that. Maybe the number of people who can think in higher order functions has r…
> I assure you, most people cannot tell you the difference between bounded polymorphism, parametric polymorphism, And yet most people know one of Java, C# and Typescript and know how to use generics with constraints. Meaning they know those concepts. Your arguing my point for me. Knowing those concepts clearly isn't sufficient. There are three things being discussed that you are conflating. Knowing a concept, knowing…
Which is why I keep focusing on understanding the Haskell type system. Those are necessary concepts, which you will learn the names of along the way.
Re: Functors, Applicatives, and Monads
#70Earlier quoted context omitted.
I'm not familiar with Haskell and am really, really struggling to follow the article. In the case of the functor, the author doesn't explain in technical, specific enough terms the difference between "open the box, extract the value out of it, apply the function, and put the result back in a box" and "apply a function to a box directly; no need to perform all the steps ourselves." I have no idea what 'apply a functio…
The number one mistake is everyone trying to explain a Haskell concept to the general population makes is using Haskell. If someone already knows Haskell there is a good chance they know there concepts. Don't use Haskell as the language, use js to explain it. The number two mistake people make is being aware of the number one mistake so they go write yet another Monad tutorial in Javascript (or Java or whatever...).…
I waver between a belief that developers with curiosity about computer science topics will, over time, be quantitatively better developers, and the notion that these are niche topics with limited relevancy.
After all, it's very clear that the Java standard library design committee understands what monads are and where they're useful, since the library is littered with the things, but there's vast numbers of developers out there making effective use of futures, collections, optionals, and streams, building their own intuitions about what "flatMap" means you can get away with, all without reading any monad tutorials.