[HN Gopher] Monads are like burritos (2009)
___________________________________________________________________
Monads are like burritos (2009)
Author : ipnon
Score : 75 points
Date : 2024-06-02 12:25 UTC (10 hours ago)
(HTM) web link (blog.plover.com)
(TXT) w3m dump (blog.plover.com)
| koolala wrote:
| How many bites does a monad burrito take to eat?
|
| 90.
|
| https://archive.org/details/monadologyotherp00gott/page/217/
|
| You don't even have to finish eating it to feel full.
| tengbretson wrote:
| And we all know that a burrito is just a lasagna in the category
| of endofunctors.
| koolala wrote:
| praise math
| mightybyte wrote:
| Not endopasta?
| layer8 wrote:
| Is that like ravioli code?
| BriggyDwiggs42 wrote:
| I didn't know anything about monads before, now I'm curious what
| the point of one is
| MarkMarine wrote:
| Making burritos
| koolala wrote:
| Burrito(Veggies)
| it_citizen wrote:
| It is a widely used analogy generator
| koolala wrote:
| F
| momentoftop wrote:
| There's no point as such. They are a natural (non-leaky)
| generalisation of a recurring pattern in mathematics and
| software over which you can build some general theory and, in
| the case of programming languages such as Haskell, a general
| purpose library.
|
| Haskell is one of the few languages that lets you write those
| general purpose libraries. In other languages, there's really
| no point talking about monads.
| VirusNewbie wrote:
| Scala supports it just fine.
| rvense wrote:
| A "monad" is a description of something so general it covers
| lists, things that might not exist, things that might fail, and
| things that might happen in the future.
|
| It is a concept from category theory, which is the branch of
| mathematics that deals with saying as little as possible about
| as much as possible.
|
| You don't have to worry about any of this unless a teacher
| tells you to. (And if they do, you can just leave.)
| mmaniac wrote:
| Haskell started using them because it allows a pure language to
| express side effects.
|
| Beyond that, they're a pretty general and reusable way of
| looking at data structures that nest.
| koolala wrote:
| Burritos have side effects?
| Y_Y wrote:
| Many impure functions take place in Taco Bell bathrooms
| juunpp wrote:
| A "side effect" is generally the behaviour that can be
| modeled by a Monad under chaining (join), and is not
| necessarily IO (although IO is a Monad). For a burrito, the
| side effect of join is the union of burrito contents.
| chuckadams wrote:
| Monads embody the concept of "chaining" functions. Every monad
| implements the chaining in a different way, but the user of the
| monad doesn't have to know how it's done. It's just "call this
| function on foo, take the result and pass it to the next" and
| so on. Plain old functions do it with plain old function
| composition (functions are monads!) but something like Maybe
| will return None if it gets a None, and only otherwise pass the
| data on. The Future monad will await completion then pass it on
| (async/await is a monad!), the List monad will merge together
| zero or more list results from mapping over each of its items,
| and so on.
|
| Again, the cool thing is that it's the same syntax no matter
| what kind of Monad you're in, so you can totally change the
| behavior of a monadic function by just using it with a more
| specific return type (at least in Haskell, other languages
| might make you pass around an implementation) Monads are a neat
| tool of composition, but composing monads themselves is fiddly
| and cumbersome, involving monad transformer "stacks" of deeply
| nested generic types. Monad transformers are really just not
| fun.
|
| I'd give specific examples, but I'm kind of lethargic from the
| burrito I had for lunch. If you're familiar with flatMap(), a
| Monad is anything that's "flatmappable" (which in JS is just
| arrays, but languages like Scala take it much further). In C#,
| it's IQueryable (LINQ is a monad!)
| aodonnell2536 wrote:
| Would it then follow that commands/builtins like `time` and
| `sudo` are monads? What about shell commands in general,
| since you can always chain together stdout to stdin with
| pipes?
| chuckadams wrote:
| Streams are definitely monads, so if you're reading lines
| from stdin and printing zero or more lines for each to
| stdout, you basically have a List monad (Haskell's laziness
| makes every list a poor man's stream, though if you're
| doing serious streaming work, you'd probably want something
| more specialized).
|
| Mind you, shell pipes aren't actually implemented
| monadically, but you can certainly visualize it that way
| when working with functional libraries.
| jerf wrote:
| "Monads embody the concept of "chaining" functions."
|
| No, it doesn't. Monad implementations may call the provided
| function zero times, or multiple times. Chaining implies
| exactly once, one of the common misconceptions about the
| monad interface.
|
| Flatmap is another common attractive nuisance; flatmap is
| _the monad implementation for lists_ but is not "monad" in
| general, any more than "an iterator on linked lists" is
| "iterator" in general.
| kelseyfrog wrote:
| It's an abstraction - a very high level abstraction.
|
| Like all abstractions, if you squint hard enough, different
| things can look the same. Monads can make optionals, lists,
| error handling, i/o, continuations, state manipulation, reading
| values, writing values and many other things look the same.
| spion wrote:
| They are interesting in purely functional languages like
| Haskell because they allow for side effects without sacficicing
| purity and referential transparency. Rather than allowing side
| effects, you describe the program as, say, specs for the
| instruction to run, plus the function that decides what the
| next instruction is after the first instruction completes and
| yields a result. Kind of like a linked list of functions that
| return imperative instructions.
|
| I don't think the general concept is that interesting, at least
| in programming. Monoids, though simpler, are probably way more
| interesting (mapreduce, caching, etc)
| chuckadams wrote:
| Monads _are_ Monoids, so it 's a good idea to build up an
| intuition for Monoids first. Then move up to Applicatives,
| and then finally Monads if you find you actually need them by
| then. By the time you get to them, Monads will be boring.
|
| Applicatives were dusty theory when I learned Monads, so they
| never burned themselves into my consciousness. I'm doing good
| with Monoids tho.
| program_whiz wrote:
| The easiest examples from mainstream languages are things like
| Result<T>, Future<T>, or Option<T>. Its honestly a very broad
| and vague way to say "some data with context". The advantage is
| that instead of using things like exceptions or panic/crash,
| your code must handle every case in order to get at the value
| unlike the normal case.
|
| For example, an Option<T> could force you to unwrap the value
| and deal with errors. In true functional languages and/or where
| pattern matching is used, you must handle both cases,
| presumably creating a chain of "monads" all the way down (as
| most of your functions will return Option<T> or Result<T, Err>
| type patterns, since you can't throw an exception, and any
| value might be empty/error, so you have to propagate it
| upwards).
|
| Honestly its a fancy term that functional programmers use to
| cow the laity. Its a bit like calling an if statement
| "probative procedural data query with indeterminate flow
| control."
| lr4444lr wrote:
| Assuming you're familiar with basic programming concepts, it is
| practically speaking just the abstract definition of a way to
| ingest and pass around data in an unfamiliar context. Promises
| are a great example (packaging data for async processing), or
| the "Optional" wrapper on JVM return signatures (Passing around
| an object for possible-null handlers). Both those
| implementations fail on some purity grounds, but they're good
| for understanding the gist of your question, i.e. "the point"
| of one. (Even though I'm 73% sure some Haskell-ite is going to
| respond to me with an _ACTUALLY..._)
| Tarean wrote:
| Lambdas have two hidden features: Variable capture lets you
| access variables/values from outer scopes, and
| statements/calling other functions lets you do control flow.
|
| Monads are types that let you build chains of lambdas, so you
| can mix control flow and variable scoping with the some type-
| specific logic.
|
| Async IO/streams/optionals are monads. It's no accident that
| these could be programmed as nested callbacks/nested
| loops/nested if statements. That's the nested chain of
| Monad->lambda->Monad->...
|
| Monads work well with syntax sugar (think async/await), and
| some languages like Haskell can abstract over them in neat
| ways.
| ww520 wrote:
| Monad provides a way to wrap types of data to process and chain
| them uniformly.
| bbminner wrote:
| For me, everything made sense when I read that generator
| functions in python can be used to implement algebraic effects,
| and algebraic effects and monads express the same ideas/logic
| using somewhat different language (and for some, including me,
| the algebraic effect lagngauge is easier). So I like an
| explanation that goes like "langaues without either but with
| exceptions and async io > generators/coroutines > algebraic
| effects > monads".
|
| On a fundamental level, all these describe abstraction over
| what happens "between functions calls" and how values are
| passed around.
|
| 1. Some languages provide special syntax for exceptions and
| async io - in both cases "something" might happen between
| function calls - either an exception handler is called under
| certain constitutions (eg prints logs) or a kernel level
| callback is created and the program is suspended.
|
| 2. One generalization of this can be implemented using python
| generator functions / coroutines - you can build a call graph
| by invoking all functions in you callstack as "yield from
| func()", and use "yield Exception" to propagate errors and
| "yield Timer(1)" to ask an outer caller (event loop) to wait,
| or "yield Print(mag)" if we want to keep our functions pure and
| make the C event loop handle all the IO. You can also pass
| values down the stack via corp.send(x).
|
| 3. But it is a little clunky. Some langaues like Koka give you
| an ability to define arbitrary "effects and effect handlers"
| which is essential special syntax for how we were abusing
| coroutines in the previous step that makes differentiating and
| handling different "kinds things that we pass up and down the
| callstack" (exceptions vs timers vs prints) easier.
|
| 4. But some langaues do not have effect handlers but still want
| to do "custom arbitary custom things between function calls".
| That's where monads come in - they define a type for defining
| chains/trees of function calls and rules for how these threes
| must be iterativley unwrapped and wrapped back depending on how
| the wrap looks like. Eg instead of doing a(b(c)) you say
| unit(c) | b | a and describe how piping must be done it terms
| of types of values that these steps process. I hope it makes it
| clear how one could implement side effect IO, or exceptions, or
| async io that pauses by defining how to "unwap such piping". In
| principle, you abstract away control flow by introducing your
| own syntax for building function call trees and then rules for
| writing piping that works with such trees.
|
| Monad guru please correct me if I am wrong.
| draw_down wrote:
| I don't know how many times I've read things like this but it
| doesn't seem to click. It's like a burrito with map and bind
| functions? Well, alrighty!
| vendiddy wrote:
| Yeah seriously.
|
| I feel like these kinds of concepts I to hear a few concrete
| examples, then generalize.
|
| These analogies usually don't click with me.
| chuckadams wrote:
| That's actually the point of the article. There used to be a
| cottage industry in using real-world analogies to explain
| Monads. I'm not sure whether it started as an in-joke or not,
| but the most outlandish metaphor among others involved burritos
| (other metaphors out there that really did exist: assembly
| lines, toxic waste handling, and space suits). So now burritos
| are an in-joke among Haskell programmers, sort of a whimsical
| shibboleth.
|
| Check my other post in this thread for what I hope is a more
| accessible explanation of Monads. They're a very abstract
| thing, so there's no concrete metaphors to be had, just a
| common thread of piping values through "contextful" functions.
| throwaway689236 wrote:
| Yeah, seems like a lot of articles are written just to have a
| catchy title.
| tiagod wrote:
| This was actually a great explanation. Still delivering 15 years
| later. I wonder what other mathematical constructions are
| abstractions of burritos.
| Waterluvian wrote:
| The application of the red sauce to the tortilla when the
| burrito is resting on the plate describes a transverse Mercator
| projection.
| passion__desire wrote:
| I have a general rule about abstraction. If the abstraction is
| so general (e.g. a root node of a tree of abstractions), then
| it's qualities will be reflected in every leaf node. Leaf nodes
| such as snow, rock, water, trees or burrito.
| ldjkfkdsjnv wrote:
| Functional programming is dead. It never really caught on. For
| all the articles I saw from 2010 - 2020, functional languages are
| still as niche as ever. Influential languages like scala have
| their best functional features pulled into java. LLMs will
| further accelerate the decline. All the highest quality, most
| crucial software I have seen is written in something like Java,
| using classical OOP design patterns.
| TwentyPosts wrote:
| Counterpoint: Rust.
|
| Seems to be taking off (difficult to predict the long-term, of
| course), but Rust is excellent at functional paradigms and
| Brings many advancements of functional languages to the people.
| ldjkfkdsjnv wrote:
| Rust is still extremely niche, large scale mission critical
| software that runs big tech is not written in Rust
| rcxdude wrote:
| it's getting built into some pretty widepread applications:
| firefox is a big one, it also runs a lot of the super-low-
| level parts of dropbox. I'd say it's overtaken haskell for
| adoption at least.
| SoftTalker wrote:
| Because it's really better, or because it's trendy?
| chuckadams wrote:
| It's more _practical_. I love me some Haskell, but you
| 're never going to write Servo in it.
| TwentyPosts wrote:
| Linux Kernel, Firefox, Dropbox, Discord, Cloudflare,
| Windows, AWS.
|
| Idk, looking pretty good to me, unless you think none of
| these count.
|
| Considering everyone seems to hate C++ nowadays, and Rust
| looks like the only existing alternative. Hard to imagine
| the trend won't continue.
| akira2501 wrote:
| Rust? Why not just JavaScript? It's far more functional than
| Rust and is much more widely used and deployed.
| ovyerus wrote:
| JS _is_ really good at FP, but it doesn 't have any real
| concept of function purity and isolating side effects.
|
| Rust has constant functions, for one: https://doc.rust-
| lang.org/reference/const_eval.html
| juunpp wrote:
| "Most crucial software I have seen".
| ldjkfkdsjnv wrote:
| At big tech firms, there is no FP in the big crucial systems
| Waterluvian wrote:
| I've seen the complete opposite. So much total OOP nonsense in
| Java.
|
| You know what I think it means? That no single perspective will
| ever be sufficiently complete to offer a meaningful opinion of
| the whole.
| koolala wrote:
| FP? More like FF? "Fat and Flabby" jk its Free and Flappy like
| Flappy Bird, flapping through a series of tubes
| fifilura wrote:
| > Influential languages like scala have their best functional
| features pulled into java.
|
| Here I feel you contradicted yourself, because the functional
| patterns are making its way into mainstream languages.
|
| Also, functional patterns has its special use in
| distributed/parallel programming.
| vendiddy wrote:
| React is a functional pattern and is pretty popular.
| akira2501 wrote:
| Does it's popularity come from it's functional foundations or
| just because a billion dollar corporation keeps it up to
| date?
| 12_throw_away wrote:
| I often forget what a monad is, and need to keep reminding myself
| "remember list.map and Option.and_then? if so, then you don't
| _need_ to know what a monad is ". But will try thinking about
| burritos next time to see if it helps.
|
| I still don't get what they have to do with i/o in Haskell, but
| am ok with i/o in Haskell being one of my life's forever
| unknowable mysteries.
| sunshowers wrote:
| The way I think about it is that the general monadic structure
| is that the results of an operation can cause new operations to
| happen with equivalent complexity. This is exactly what "flat
| map" is.
|
| So what the "IO monad" in Haskell represents is the general
| principle across programming languages where you can, say, read
| a file, then for each line in the file read another file or
| otherwise do additional I/O -- and this can spiral out in an
| unbounded fashion.
|
| As developers we can observe the monadic structure of
| operations everywhere (and generally seek to avoid it! Monads
| are fundamentally too powerful!) But whether it is worth
| encoding the general idea of monadic structures into the type
| system is a separate question. Haskell says yes, most others
| say no. There are good reasons both ways. (One underappreciated
| reason is that exposing a hierarchy of typeclasses/traits
| introduces API stability considerations. When Applicative was
| inserted in between Functor and Monad in Haskell, the whole
| ecosystem had to be updated.)
| roflc0ptic wrote:
| (Tries to fight the urge to explain, fails) it's a construct to
| sequence async interactions, one after the other, without
| blocking. It's very similar to c# or python's await
| minitech wrote:
| I/O is just one thing that can be described with a monad.
| `Option` with `and_then` as the parent suggested was another
| example.
| Cu3PO42 wrote:
| I'd argue that if you know what Option.and_then does, you do
| know what a monad is. and_then, known as flat_map or bind in
| the generic case, is the quintessential operation of a monad.
|
| One of my biggest gripes with Rust (and other languages) is
| lack of a good monad abstraction (and accompanying syntactic
| sugar). But I also acknowledge that this is a "I have done too
| much category theory" problem and and_then is probably a more
| reasonable name to those not familiar with this particular area
| of maths.
|
| > I still don't get what they have to do with i/o in Haskell,
| but am ok with i/o in Haskell being one of my life's forever
| unknowable mysteries.
|
| They don't. Not really, anyway. IO happens to be a monad, but
| that's not really relevant to it being used as an abstraction
| around side effects. Haskell being a pure language is at odds
| with the necessity of some side-effects, such as printing to
| the console. The solution is to construct a "to-do list of
| actions" or "blueprint" for desired side-effects. This is an
| instance of IO. Any such blueprint that is assigned to the name
| "main" is executed. That's it.
|
| The monad part comes in when you want to construct this
| blueprint. It so happens that one reasonable way to do this is
| via flat_map.
| lkuty wrote:
| This might be interesting: https://jelv.is/blog/Haskell-Monads-
| and-Purity/
| gabesullice wrote:
| I've referred to this blog post at least twice a year since I
| read it 6 or 7 years ago. Not because I need to explain monads,
| but because the "monad tutorial fallacy" [1] is an incredibly
| useful concept to be aware of when trying to convey knowledge. I
| encourage you to read about it :)
|
| [1] https://byorgey.wordpress.com/2009/01/12/abstraction-
| intuiti...
| Symmetry wrote:
| That reminds me of giving the advice, "Just do what comes
| naturally," to beginners. That's the last advice someone who
| has spent years building up an intuitive model needs, but it's
| terrible for beginners.
|
| https://putanumonit.com/2021/09/10/rules-for-noobs/
| Swizec wrote:
| Just do what comes naturally is _great_ advice for beginners.
| See the pottery class parable:
| https://www.industryweek.com/leadership/companies-
| executives...
|
| tldr: Pottery class, 2 groups. 1 group instructed to make the
| perfect pot (graded by quality of 1 best pot). 1 group
| instructed to make a bunch of pots (graded by pounds of clay
| used).
|
| At the end of semester, the group who was trying to make as
| many pots as possible also produced the single best pot of
| the class.
|
| Lesson: You need reps. Lots of reps. You really do just gotta
| do what comes naturally, get feedback, then do more. Doing is
| the only way to learn tacit skills.
|
| You can read about the best way to ride a bike for 10 years
| and achieve nothing. Or you can spend an afternoon failing a
| lot until you can ride a bike. Software architecture and code
| structure are similar. You just gotta produce piles upon
| piles of code and see what works.
| mightybyte wrote:
| Yes, this post is classic. My answer to Brent's "monad tutorial
| fallacy" is https://mightybyte.github.io/monad-challenges/. It
| was inspired by The Matasano Crypto Challenges that Thomas
| Ptacek & others created awhile back which, instead of trying to
| teach you cryptanalysis, guides you down the path of actually
| doing realistic cryptanalysis with a series of challenges.
| pdpi wrote:
| For a long while now, I've been trying to write a monad
| tutorial I'm actually happy to give people as an entry point,
| and that point is precisely why I haven't put anything out
| there yet. It's also the reason I keep trying: there's
| something important to be learnt there in terms of
| communicating tricky concepts.
| kqr wrote:
| I think the lesson is that tricky concepts have to be taught
| by example.
|
| Some theoretically-bent people can read a definition and
| generate their own examples, but most people I've met need to
| be presented with and taught one example at a time. After a
| while, they just get it and the abstraction falls into place.
|
| https://two-wrongs.com/the-what-are-monads-fallacy.html
| pdpi wrote:
| > I think the lesson is that tricky concepts have to be
| taught by example.
|
| The bigger insight, for me, is that they also have to be
| taught by counter-example.
|
| E.g. it's easy to find Functors that are neither
| Applicatives nor Monads (usually, because you can't produce
| a reasonable definition for `return`). It's surprisingly
| hard to find a non-contrived example of a Functor that is
| also an Applicative, but *is not* a Monad. Without that
| counter-example, it's very tricky to build the intuition
| for where the boundary lies.
| andrepd wrote:
| Now I'm curious: what's this non-contrived example?
| chongli wrote:
| _Some theoretically-bent people can read a definition and
| generate their own examples_
|
| This is what mathematical training taught me to do. It's
| something I wish everyone could learn to do but high school
| is too short to teach it to most people.
| behnamoh wrote:
| Monads are so easy. That's why there are 2,000 articles online
| explaining how easy they are. :)
|
| Okay hear me out:
|
| I don't like exception handling, because it doesn't feel "pure"
| and consistent with the rest of my program flow. If any errors
| happen, I want to know what they are so I can plan ahead. You
| might say "well, just catch your exceptions dammit". But see,
| what if I forget to catch an exception right away and it
| propagates? Also, other than Swift, I don't know of any
| programming language that let's me explicitly mention if a
| function could throw an exception. In Python, for example, you
| can't just do Optional[str], because returning None is different
| from raising an exception. So by just looking at a function type
| signature, one can't know if it throws, which means you never
| know if you should use try/catch or not.
|
| But let's say you take care of all edge cases and return None in
| those bad paths instead of raising exceptions. Let's also assume
| that Python does't suck and it never raises exceptions by its own
| standard libraries (e.g., json throws). The problem is: How do we
| know if the function returned None because the evaluation was
| None, or because it failed at some point?
|
| So a better approach is to explicitly say the function returns
| "something" which may or may not be there. If it's there, then
| the function worked correctly, even if the value is None. If it's
| not there, then the function failed. Go does this. Rust does this
| better. Haskell has had this since ages thanks to Monads.
|
| I like to think of monads as wrappers around data. In Python, I
| simply write a Result monad (similar to Rust). In Haskell, this
| is called a Maybe monad.
| chuckadams wrote:
| > I like to think of monads as wrappers around data
|
| Technically they're a wrapper around a data _type_. Maybe Foo
| is a Foo that might not be there, [Foo] is zero or more Foos,
| etc. Which is actually describing a Functor, but Monads are
| also Functors, the "monadness" comes from the particular
| functions like `bind` (or `flatMap`) that work on them.
| airstrike wrote:
| You might enjoy Hurl, the exceptional language:
| https://news.ycombinator.com/item?id=40480056
| behnamoh wrote:
| I mean, I literally said I don't like exceptions :) But for
| Hurl I'll make an exception!
| flakes wrote:
| > Also, other than Swift, I don't know of any programming
| language that let's me explicitly mention if a function could
| throw an exception.
|
| Checked exceptions in Java. I both like and hate them.
|
| They force the function to be explicit about what exceptions
| they can raise. If you call a function that raises a checked
| exception, you must either explicitly handle the exception, or
| mark that it is propagated up by adding the same exception to
| the calling method signature.
|
| However, they cause a lot of pain for working with higher order
| methods (map, filter, flatmap, etc). Because they change the
| signature of the method (and therefore the interface it can
| satisfy), you need to use a lot of generic variants of higher
| order methods to accept them, or like a lot of libraries, you
| end up writing wrapper functions that convert the checked
| exceptions into unchecked runtime exceptions, such that they
| don't modify the method signatures. This then leads to a lot of
| weird code, and uncaught exceptions at runtime, taking down the
| application.
| justinpombrio wrote:
| Jerf wrote a great monad tutorial for people who have read too
| many monad tutorials (like this one):
|
| https://www.jerf.org/iri/post/2958/
| scythmic_waves wrote:
| Thank you! I was trying to find this the other day but
| couldn't.
| SatvikBeri wrote:
| My favorite approach is from Functional Programming in Scala,
| which doesn't mention monads until chapter 11. But it has you
| implement a bunch of collections with `map`, `map2`, `unit`, and
| `flatMap`, and exercises that repeatedly show how useful this
| interface is. So by the time you get to it, the definition of
| Monad feels obvious, as well as Functors & Applicatives.
| brudgers wrote:
| Not really related, https://the21stcenturymonads.net/
| Mathnerd314 wrote:
| > But he said no, I was the lone genius.
|
| I think that's the issue? Haskell was designed by and for
| geniuses (Larry Wall). But Python... certainly Guido likes
| compliments but for the most part he was an average programmer,
| designing for other average programmers. And now Python is #1
| while Haskell is only #28. Like if you just skipped the "monad"
| terminology and called them "promises" or "futures" everybody
| would be less confused.
| avodonosov wrote:
| Explanations with bad analogies are really a very often problem.
|
| Although this author matched monads with burritos relatively
| well. Except for the purpose - we know the purpose of burritos,
| but this does not help to understand the purpose of monads (for
| programming, in particular).
|
| But sometimes a concept is named after a bad analogy by the
| concept authors (and probably even invented after that bad
| analogy, although maybe the authors just use poor name because
| they fail to clearly recognise the essence of their solution).
| Like mixins. I satirise that in my Mixin FAQ
|
| Q: What is a mixin?
|
| A: Mixin allows to inject functionality into classes. Mixins
| first appeared in the Flavors system and were inspired by an ice
| cream shop offering a basic flavor of ice cream (vanilla,
| chocolate, etc.) with a choice of optional "mix-in" ingredients
| like nuts, cookies, candies, etc.
|
| Q: Can I mix-in a ServerSocket into a ColorPicker?
|
| A: Yes, why not.
|
| Q: How will it work?
|
| A: Like ice cream with cookies.
| frabjoused wrote:
| Is something that is so inherently hard to explain while giving
| it justice truly practical or even worth it? If you are in a room
| with 10 devs, how many will have a deep understanding of monads?
| And if it is expected to be only a few, is it really constructive
| to have it in the codebase? Or is it just going to trip people up
| and be misapplied.
| williamcotton wrote:
| If your codebase is written in F#, OCaml or Haskell then it
| would be surprising if there were no use of monads as it is a
| pretty common design pattern in a functional language.
| bawolff wrote:
| I think the real question is more - is the language of category
| theory really worth it here.
|
| Monads as a concept is basically just a fancy version of a
| wrapper class (if you in OOP land). Do we really need the
| cognitive overhead of advanced mathematics to explain that?
| agentultra wrote:
| You can get by on intuition but you won't get far.
|
| If you want to limit yourself and make sure people keep
| reinventing the same concepts over and over, sure, avoid
| maths.
| djur wrote:
| You don't need to have a deep understanding of monads to use
| them. Plenty of languages are built on concepts that their
| users aren't expected to understand thoroughly.
| massysett wrote:
| Monads are easy.
|
| What's hard is higher-order functions, parametric polymorphism,
| and ad-hoc polymorphism via typeclasses. Understanding any one of
| these is hard. Understanding all three is harder. Understanding
| all three applied simultaneously is harder still. That's what
| monads are.
|
| On top of all that, understanding "monads" doesn't mean too much.
| IO does something, Maybe does something else, StateT something
| else.
|
| But once you understand all that, monads are easy. Maybe monad
| analogies helped somebody understand all that, but they didn't
| help me.
| williamcotton wrote:
| A Burrito Is a Monad (2024):
|
| https://www.williamcotton.com/articles/a-burrito-is-a-monad
| let burrito = tortilla >>= addMeat Chicken
| >>= addMissionBurritoIngredients >>= holdThe Cheese
| >>= addIngredient PicoDeGallo >>= addIngredient Salsa
| >>= addIngredient Guacamole >>= addIngredient SourCream
| davesque wrote:
| I always felt like the one thing I wanted in a monad tutorial was
| a list of things that _aren 't_ monads because they follow all
| the monad rules except for one, for each rule.
___________________________________________________________________
(page generated 2024-06-02 23:01 UTC)