Тёмный

The Death of Monads? Direct Style Algebraic Effects 

Impure Pics
Подписаться 2,5 тыс.
Просмотров 19 тыс.
50% 1

Опубликовано:

 

4 окт 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 77   
@impurepics
@impurepics 5 месяцев назад
In a blog post form: www.unison-lang.org/docs/fundamentals/abilities/for-monadically-inclined/
@Slate245Ivanovo
@Slate245Ivanovo 5 месяцев назад
Was I just tricked into watching a Haskell vid by a funny thumbnail?
@mtaur4113
@mtaur4113 5 месяцев назад
A monad is a monoid in the category of endofunctors.
@Slate245Ivanovo
@Slate245Ivanovo 5 месяцев назад
@@mtaur4113 I always thought it to be a burrito though
@JoeTaber
@JoeTaber 5 месяцев назад
@@Slate245Ivanovo The channel's profile photo agrees with you.
@jean-michelgilbert8136
@jean-michelgilbert8136 5 месяцев назад
Yep. I have the same feeling of being tricked too. I usually avoid Haskell and FP. There's already enough new things happening in the C++ world.
@8panthermodern2
@8panthermodern2 5 месяцев назад
Just the RU-vid algorithm pushing another extremist ideology. Sure, it starts with the memes. "Monads, lol", you say to yourself. Next thing you know you are holding your scrum meetings hostage with long tirades about type theory.
@NostraDavid2
@NostraDavid2 5 месяцев назад
All I know about Monads (other than that they are a Monoid in the Category of Endofunctors) is that they are basically a black box that holds state (of your game, a file, anything, really). You pass that black box into a function. The function unwraps the black box and does something based on the input state, constructs a new black box to hold the new state and passes that black box to the next function. I have no idea if this explanation is even correct, but it's what my peabrain has come up with after watching 451 videos, and reading 2501 Wikipedia articles, about Monads and what REALLY TRULY FINALLY are.
@cgibbard
@cgibbard 5 месяцев назад
That's really only a description of the state monad in particular, where you implement stateful computations by using pure mathematical functions (i.e. the sort you learned about in math where there's only one possible output for any given input) by taking an initial state and transforming it into a final state along with some result. The monad abstraction also captures a broader pattern of defining some sort of "computations" having a result, where you have certain primitive operations that allow us to build a common library of "control flow" operations in terms of that. So you can, for instance, define how a for-each loop ought to work in any monad, as an ordinary library function. Then upon finding out that your parsing library defines a monad of parsers (which might in addition to implementing state, also implement backtracking), you get to make use of the for-each loop that was already defined in the library to concatenate together a bunch of parsers (and a lot of other useful control-flow-like things besides). The monad abstraction only really makes sense as an abstraction once you look at a bunch of examples. On top of that, the code for it in languages that aren't similar to Haskell (in particular, it kind of demands static typing + something like type classes that let you pick implementations of things based on the type of result they need to produce, not just the type of the input) is usually going to be ugly and/or crippled in some way which reduces the usefulness. They're super useful and good in Haskell, and I feel like this video strawmanned the monad code a good bit (look how ugly this is if I write it in a way that nobody does), but I wouldn't blame, say, a Ruby or Java programmer for not using monads, because you just don't have the right sort of polymorphism in those languages to get the benefit from it conveniently.
@samuraijosh1595
@samuraijosh1595 3 месяца назад
@@cgibbard Monads in Haskell seemed to be designed in such a way that you're punished for even using by them even though they exist as a potential option. The fact that all of your stateful computations have to always exist in the ST monad is just so not easy to deal with. Yes, sometimes you can extract the value from ST but if only it's a simple immutable type which doesnt have the state s token embedded in its kind signature. Very very annoying abstraction in my opinion. after trying to integrate some mutable types in complex type at the type level, I just gave up and opted for immutable alternatives.
@cgibbard
@cgibbard 3 месяца назад
@@samuraijosh1595 If the type of thing you're returning from ST has an 's' in it, that means it contains references to mutable variables. There are ways to smuggle such values out, but they are useless, because if you were to do another runST to get back into the ST monad to access them again, the 's' would be treated as distinct by the typechecker, and it wouldn't let you access them. This is what makes runST safe and doesn't cause it to just break the entire evaluation model of the language. If you want to return the contents of those mutable variables instead, you just want to use readSTRef at the end to get the values out. (If it's an array, you might instead use runSTArray.) But that said, ST is pretty niche indeed, and yeah, most of the time, you're better off just writing a functional program to compute what you were trying to compute, I super agree about that part. That says very little about whether monads in general are a good abstraction though. I think the first example of a monad which really convinced me that it's a good idea was parsing monads. You can have a type (Parser t) of parsers which consume some portion of an input string in order to produce results of type t, and combine those together using the monad operations, and stuff like forA which was ordinarily a for-each loop in stuff like IO or ST, turns into a way to concatenate a bunch of parsers together and collect the results. Other really nice examples often have to do with contexts where you want some effects, but can't or don't want to allow all of them. A monad for doing database or memory transactions that might need to be rolled back and retried later might want to prevent various other sorts of effects from occurring because you can't un-fire the missiles. I do a lot of work with functional reactive programming stuff using Reflex (building web and mobile apps mostly, some desktop on occasion). In that context, we have some monads where the actions are implicitly a function of the present time (but what that time actually is, is never mentioned or specified because the system as a whole at a low level is implementing things with IORefs and carefully providing the illusion that updates happen in lockstep globally and dealing with all the simultaneity). There, the monad operations serve as a way of sticking together things which vary over time in various senses to make more complicated things which vary over time. The simplest of those is probably (Behavior a) which is the type of things which vary over time, and have a value of type a whenever you'd care to look, but can't notify you of when they change: it's consistent with the laws of the system that they may even change continuously. Another is (Dynamic a) which is like a step function that only changes at discrete moments in time and you can tell when. Those are both monads. The real point of it all is that this idea of having a type of computations of some sort that will later be run to produce values is a fairly common functional programming abstraction. By recognizing it, we get to reuse things like all the control flow stuff in Control.Monad and gadgets like monad transformers, without needing to rebuild that stuff for each new monad, so it's quicker to get these sorts of domain-specific libraries fleshed out.
@capability-snob
@capability-snob 5 месяцев назад
My goodness. A video on algebraic effects 😮 Nicely done.
@JanilGarciaJr
@JanilGarciaJr 5 месяцев назад
Just found out about ocaml's effect handlers yesterday, the timing of this video is just amazing lol Unison looks really cool, I might check it out. I think algebraic effects are here to stay from the little I saw. I honestly can see mainstream languages implementing this 10/20 years from now.
@justinhj1
@justinhj1 2 месяца назад
Beautifully produced and content rich, thanks!
@georgH
@georgH 5 месяцев назад
The thumbnail cracked me 🤣🤣🤣
@OhsoLosoo
@OhsoLosoo 5 месяцев назад
No please guys don’t change anything. I’m just starting to get the hang of functional programming, I recently have began to study category theory & its implementation in computer science 😭😭😭
@impurepics
@impurepics 5 месяцев назад
You don't need to study category theory to write/understand functional programming. I would only recommend category theory if you think it's fun.
@nanman_chief
@nanman_chief 3 месяца назад
I'm not sure if this comment is a joke (sorry, I often misunderstand humor on the internet, so I need to check). If it's not a joke, I have some good news for you: Effect handlers are essentially based on category theory. They are just so well-packaged that you don't need to know what Yoneda lemma is to happily use them for programming. If you're deeply interested in the theory, you can read Gordon Plotkin papers "Algebraic Operations and Generic Effects" and "Handling Algebraic Effects".
@woobilicious.
@woobilicious. 5 месяцев назад
Your assessment that Haskell is non-strict and Monads "help" is wrong, The point of a Monad is to handle side effects/passing the "world" around on the side in a pure language, they allow you to turn a function "(World, a) → World" in to a "a → (World → World)", monads allow you to write functions that return functions with the world as the only argument, the IO Monad is not strict and only some calls force evaluation, the best way to think about it is that IO is a output based promise system, `a ← readLine` doesn't run *until* you use the `a` in some sort of output, they do a poor job of sequencing effects. And you will get intermittently familiar with forcing evaluation in the correct order using bang patterns (using !), unboxed types and `seq` and `deepseq` all have varying effects on thunk evaluation ordering. It's probably the biggest pain point of Haskell.
@apteropith
@apteropith 5 месяцев назад
well, it's true for side-effects that are internal to haskell, where it knows all the dependencies, but that's a fair point that the language would need still extra help with IO side-effects, since there's little way for it to tell if one IO action is meant to be _externally_ "dependent" on another i wonder what the best way to handle that is! haskell is very neat and demonstrates some very good ideas, but i find it deeply imperfect in some spots (so i very quickly lost most of my interest in it, oops)
@samuraijosh1595
@samuraijosh1595 3 месяца назад
@@apteropith the monad abstractions Haskellers came up with to handle mutable types are fine in theory/concept but they're executed so badly in my opinion.
@locker47
@locker47 5 месяцев назад
Could you show an example of converting a piece of code that uses monadic effects into algebraic effects and show the pros/cons of each? I'm trying to wrap my head around the ergonomics of tagless final and algebraic effects (e.g., Cats vs. Kyo), and when should we prefer one over the other. If there is a blog post on this I would love to read it!
@apteropith
@apteropith 5 месяцев назад
i learned about monads in haskell a few years ago; while i did appreciate the power of the very fancy wrapping & unwrapping of values which monads can provide, my biggest takeaway was actually that the do-blocks with the bind operators are just a form of continuation-passing style, and should never have been confined to monads the bind operator really should default to simpler function-composition when a monad is not present; there is little reason for it not to, and not doing so damages the flexibility and utility of the do-block's syntax - i might go so far as saying it damages the elegance of the language
@Heater-v1.0.0
@Heater-v1.0.0 5 месяцев назад
Wow! I have been programming for 40 years. On all kinds of projects from time embedded systems to desktop CAD systems. In all kind of languages from assembler up. Ten years ago I first heard the word "monad". Despite multiple efforts at understanding it I still don't get it. Now this, I have no clue what the words even mean or why one would want such a thing. Luckily such cognitive overhead is not required to actually get useful things done.
@hath995
@hath995 5 месяцев назад
Monads are the minimal structure needed to do function composition of wrapped/decorated data types. You can compose easily a function from integer to string and a function string to boolean to get a function from integer to boolean for example. Now if you had functions from integer to Boxed and one from string to Boxed, where Boxed is some container type like Array or Optional then you can't compose these functions naturally. Roughly a monad is just an interface on your objects that provides a method called chain or flatMap that can take a Boxed and a function from T to Box to produce a Boxed.
@nythrox3047
@nythrox3047 5 месяцев назад
Thank you for bringing up the important stuff
@ywenp
@ywenp 5 месяцев назад
5:00 That is a bit of a strawman and you know it :) That's what the syntactic sugar of Haskell's do-notation is for, and it's very straightforward. Don't get me wrong: the rest of your points remain valid, but the drawbacks of using monads don't lie in the syntactic department. You could say though that's is a bit of a bummer to have two different syntaxes for pure code and monadic code, but this gives the advantage of making it immediately clear when some part of the code is not using a standard control flow (which is kind of an important thing to know when you look at code). 15:34 If by "static control flow" you mean "being able to see the whole graph of computations before actually running it" (given you use build systems as an example, I have a sense this is what you mean), then you cannot do that with Monads either. Monadic computations are opaque by essence, they produce a dynamic computation graph just like direct style. You need other control flow structures for that (namely Applicative functors or Arrows).
@impurepics
@impurepics 5 месяцев назад
Any extra syntax (or even sugar) is a cognitive overhead. And some people think that do-notation is even worse. We emulate strict languages and the idea of execution during the evaluation (one more thing to think about) to build programs as values, which will then be executed. Another syntax - another level overhead. You're right. In the video, I said monads "and friends" because I didn't want to bring another player all of a sudden. I realized it wasn't a good idea, in the blog post I explicitly bring up Applicatives.
@ywenp
@ywenp 5 месяцев назад
> Any extra syntax (or even sugar) is a cognitive overhead. Yes, it's true. But it's just one criterion out of many over which to evaluate such a design choice. In any case, my point was that it does the job of tidying up monadic code so you don't have to do the heavy lambda-juggling you were showing.
@isodoubIet
@isodoubIet 5 месяцев назад
If it were a strawman, there wouldn't be as many monad tutorials as there are, nor would there be tens as many people commenting some variation of "I still don't get it" underneath every single one. One of the most fun things to do is to ask what are Monads in a Haskell forum and watch the magic happen as people start fighting over one another's misconceptions.
@jenreiss3107
@jenreiss3107 5 месяцев назад
I really like the fused-effects library, as fusion laws allow the effect handler to fuse effect types so that evaluation only requires a single AST traversal, rather than the O(n) for more standard free monads. granted, it is built on a giant tower of abstractions that is very tough to grok, but once you do, it is incredibly powerful
@generalyoutubewatching5286
@generalyoutubewatching5286 18 дней назад
This one video made me subscribe!!! Love how u pointed out that Haskell was lazy and hence needs monad for io
@impurepics
@impurepics 18 дней назад
@@generalyoutubewatching5286 Thanks, I’m glad you enjoyed it; bunch of people hated that part 😀
@DrewryPope
@DrewryPope 5 месяцев назад
Laziness in Haskell on the Tweag channel is very good
@impurepics
@impurepics 5 месяцев назад
Agree
@federicoagustinsawadyoconn2716
@federicoagustinsawadyoconn2716 4 месяца назад
Some things I read in the comments or see in the video make me realize that some poeple analyze Haskell as if its computing model were the same as other traditional languages, when it is not. Referential transparency, in the computing model that Haskell chooses to have, is extremely important, so it is not that optional. That is the main reason why the language is lazy. And it is the main reason why one also chooses to program in Haskell. Algebraic structures like monads or applicative functors are excellent in terms of maintaining equational reasoning more than other options, so they are not criticizable in the same way as a feature in a imperative language. They are not just a feature that solves something from a utilitarian point of view neither, because they are a mathematical solution for mantaining clear reasoning about pure code, which in Haskell is more important than in other languages. I know that many want features in Haskell that are also utilitarian, which is not bad, but please understand that the language was not designed for that, so you have to be aware of what I mentioned before when analyzing some of the pain points of the language.
@luvincste
@luvincste 5 месяцев назад
i didn't really understand much of this
@herrbonk3635
@herrbonk3635 Месяц назад
You are not supposed to.
@diribigal
@diribigal 5 месяцев назад
This reminds me of "Hold" in Wolfram Language where delaying evaluation (really substitution) is not weird, but the syntax overhead is a lot compared to the parentheses and ticks shown in this video. I have to check out Unison now!
@zackyezek3760
@zackyezek3760 5 месяцев назад
What modern programming languages really need is explicit syntax for defining tasks- atomic chunks of work with explicit inputs and outputs, the dependencies between them, plus any other specific runtime or state machine conditions the actual machine running the code should honor (e.g. error handling). Basically, doing for the state machine of a program- the control flow, async logic, parallel processing- what the introduction of objects (“classes” or “object oriented programming”) did for the data. Manually writing threads or low level async handoffs like semaphores and locks is really the state machine equivalent of directly writing assembly. Monads are like the structs in the original K&R C; they’re a significant and powerful improvement upon straight assembly and primitive types, but far from the massively more powerful (and complex) full blown objects of C++ or Python classes. It’s why their rampant (ab)use is everywhere, why so much custom boilerplate is piled atop them, and why a lot of that code is reminiscent of the old school C boilerplate you write to obtain de facto vtables and ‘member functions for C structs. Because it’s the equivalent of full classes that we need for the state machine, and we don’t have those yet.
@8panthermodern2
@8panthermodern2 5 месяцев назад
Just the RU-vid algorithm radicalizing another generation
@i-am-the-slime
@i-am-the-slime 5 месяцев назад
Very good effects. I handled them like a champ.
@hantuchblau
@hantuchblau 5 месяцев назад
Great video! I still find it funny that java has almost everything you need. Checked exceptions for effect tracking, thread local state for handlers, the new virtual thread stuff for control flow manipulation. Pity java surface syntax cannot write down type unions in most places, though. One point I didn't understand is why 'user-defined effects' were rated better for Abilities than for Monads. In my experience multishot delimited continuations are hard to make efficient, so you gotta work much harder to build good nondeterministic effects. Many implementations just give up and forbid multishot effects entirely. With mtl-style final embeddings CPS nondeterminism just works.
@hansisbrucker813
@hansisbrucker813 5 месяцев назад
I wonder if it can be implemented in Common Lisp using macros 🤔
@u9vata
@u9vata 5 месяцев назад
Good content - but for solving the same things, I would any day take somthing like zig comptime instead or metaprogramming in general... Too taxing on the programmer to do it these ways still.
@wildwestrom
@wildwestrom 5 месяцев назад
I gotta figure out how I could translate this concept into Rust code. Maybe it'll result in better code?
@estebanmarin002
@estebanmarin002 5 месяцев назад
wow, loved the explaination
@dansheppard2965
@dansheppard2965 5 месяцев назад
Mercury's "modes" always seemed a neat middle ground for side-effects. I'm not sure why they haven't caught on.
@ZeroG
@ZeroG 5 месяцев назад
I do not understand what is meant by "effect handlerl
@impurepics
@impurepics 5 месяцев назад
Sorry, didn't have time to go into it. Here are a few good pointers: * www.unison-lang.org/docs/fundamentals/abilities/using-abilities-pt2/ * v2.ocaml.org/manual/effects.html * koka-lang.github.io/koka/doc/book.html#sec-handlers * effekt-lang.org/docs/concepts/effect-handlers
@mskiptr
@mskiptr 5 месяцев назад
I'm at 7:00 and I have to say it's a really nice overview, but I absolutely cannot agree with the conclusions so far
@MikkoRantalainen
@MikkoRantalainen 4 месяца назад
15:52 I would argue that neither monads for "abilities" are teachable. Definitely not easy to teach as direct style procedural programming.
@poklet
@poklet 5 месяцев назад
Do these methods compose well? For example if an existing codebase was written in a monadic style, is it possible to add code with Abilities or Direct-Style? If they do compose, what’s the mental overhead like in juggling all these styles in one code base?
@impurepics
@impurepics 5 месяцев назад
Depends on the language/implementation. Shouldn't be a big problem, as long as there are functions to convert from one to another. For example, in Unison, you can convert the "monadic" Either to the Exception ability and vice versa. So, if you have a function that returns an Either and another that has Exception, and want to use/compose them together, you might need to convert one of them first (e.g., using Either.toException). But, yeah, mixing styles always comes with overhead. share.unison-lang.org/@unison/base/code/releases/2.20.0/latest/terms/@5mqjoauctm02dlqdc10cc66relu40997d6o1u8fj7vv7g0i2mtacjc83afqhuekll1gkqr9vv4lq7aenanq4kf53kcce4l1srr6ip08
@Nikolas_Davis
@Nikolas_Davis 5 месяцев назад
2:05 shouldn't these be "\_" instead of "\\_" ? (Absolute noob in haskell; still, I think that's a typo)
@ZeroG
@ZeroG 5 месяцев назад
How is this different than what I can do in Swift already, using closures?
@capability-snob
@capability-snob 5 месяцев назад
Effect handlers may or may not choose to return back to the caller, hence the comparison to exception handling and call/cc.
@JanilGarciaJr
@JanilGarciaJr 5 месяцев назад
How is it similar to closures?
@mattmmilli8287
@mattmmilli8287 5 месяцев назад
This is just a methodology that applies to any language ?
@BenHutchison
@BenHutchison 5 месяцев назад
I'm sceptical of the claim that writing effect handlers is easier than monads. Better leave such claims for a future video where you have time to go into the topic and hopefully show some evidence for your claims. Which I personally think will in the long arc of history end up being recognised as "about equivalent" to monads.
@impurepics
@impurepics 5 месяцев назад
Yeah, I'd like to go deeper into the topic. For now, I assumed that an average viewer/reader either has no experience writing production/real-world monads or already knows that it's not that easy (I'm not talking about monad-tutorials-like monads). So, the bar for the effect handlers is relatively low. Unison docs already has a good section on writing handlers: www.unison-lang.org/docs/fundamentals/abilities/writing-abilities/
@asdfghyter
@asdfghyter 5 месяцев назад
in my experience they are way easier to write. it’s generally straightforward, while monad transformer implementations are finicky and easy to get wrong (c.f. the many “ListT done right”) but the most important advantage in my opinion was missing: unlike monad transformers, effect systems generally aren’t order dependent, so you don’t need to be careful about stacking the transformers in the right order
@JorgetePanete
@JorgetePanete 5 месяцев назад
I'm having a really hard time understanding your words and the automatic subtitles aren't helping
@impurepics
@impurepics 5 месяцев назад
I'm working on the blog post version. I'll share in a few days.
@impurepics
@impurepics 5 месяцев назад
You can read it here: www.unison-lang.org/docs/fundamentals/abilities/for-monadically-inclined/
@hindigente
@hindigente 5 месяцев назад
Went in thinking this was about category theory. :D
@maxmustermann5590
@maxmustermann5590 2 месяца назад
I was told you were the burrito made me spit out my coffee my guy
@mojeimja
@mojeimja 5 месяцев назад
this all looks horrible :)
@herrbonk3635
@herrbonk3635 Месяц назад
Indeed. As complex as possible, instead of the opposite.
@angeloceccato
@angeloceccato 5 месяцев назад
Figoooooo, great video¡¡¡
@Taylor-rx4yb
@Taylor-rx4yb 5 месяцев назад
I love monads! But I am also a mathematician and I'm realizing this video isn't actually for me lol
@vpatryshev
@vpatryshev 13 дней назад
This talk is really confusing, since it does not give an impression that the speaker knows what monads are. Weird.
@impurepics
@impurepics 13 дней назад
@@vpatryshev knowing what monads are and knowing why monads are used are two different things. I assumed people watching are familiar with the former, and the later is important for talking about a bigger picture
@TaranovskiAlex
@TaranovskiAlex 5 месяцев назад
"a guy in a lab coat with a shank"...
Далее
New Gleam Just Dropped
25:33
Просмотров 83 тыс.
How do non-euclidean games work? | Bitwise
14:19
Просмотров 2,4 млн
iPhone 16 & beats 📦
00:30
Просмотров 162 тыс.
Китайка стучится Домой😂😆
00:18
МАЛОЙ ГАИШНИК
00:35
Просмотров 556 тыс.
What is a Monad? - Computerphile
21:50
Просмотров 604 тыс.
Okay but WTF is a MONAD?????? #SoME2
18:18
Просмотров 67 тыс.
What the Heck Are Monads?!
21:08
Просмотров 72 тыс.
A high-level overview of PureScript
10:06
Просмотров 7 тыс.
Programming with Math | The Lambda Calculus
21:48
Просмотров 198 тыс.
iPhone 16 & beats 📦
00:30
Просмотров 162 тыс.