> The best we can do is to recover from a failure and maybe somehow retry what we were doing, but we can’t magically “go back” to where we were, and do something different. But with algebraic effects, we can. This is literally Common Lisp's condition system which a) decouples signaling conditions from handling conditions, b) allows you to execute arbitrary code in the place that signals, c) allows you to stack indepe…
The origin of "algebraic effects" appears to be this paper (Plotkin and Power): https://link.springer.com/article/10.1023%2FA%3A102306490896... Unfortunately I don't speak monad.
Algebraic Effects for the Rest of Us
61–70 of 106 posts
Re: Algebraic Effects for the Rest of Us
#62Algebraic effects are similar to Common Lisp restart handlers, but in addition, they also receive the continuation of the invoker. This means, you can use algebraic effect handlers to implement higher-order control features like coroutines, probabilistic programming, and nondeterminism (which you can't in Common Lisp). However, what most people get wrong: you do not need higher-order control if you just want to resum…
Re: Algebraic Effects for the Rest of Us
#63I doubt if you need any new language construct to introduce this. Could you not simply pass an error handling function/object with all your functions/methods, which is called when an error occurs? This function/object could then resolve the error or throw an exception if it cannot resolve the error. It is possible, and relatively easy, to chain such error handling functions/methods to implement complex error handling…
The article only gives a limited example of algebraic effects. The thing that is required for a condition system (ie good resumable exceptions) is lexical non-local transfer of control and doesn’t need algebraic effects (Common Lisp had a condition system but not algebraic effects in the late 1980s). Lexical non-local transfer of control is effectively the ability to write code which looks like (made up JS like synta…
Re: Algebraic Effects for the Rest of Us
#64Algebraic effects are similar to Common Lisp restart handlers, but in addition, they also receive the continuation of the invoker. This means, you can use algebraic effect handlers to implement higher-order control features like coroutines, probabilistic programming, and nondeterminism (which you can't in Common Lisp). However, what most people get wrong: you do not need higher-order control if you just want to resum…
As CL is programmable, I would not claim "which you can't in Common Lisp".
Re: Algebraic Effects for the Rest of Us
#65> The best we can do is to recover from a failure and maybe somehow retry what we were doing, but we can’t magically “go back” to where we were, and do something different. But with algebraic effects, we can. This is literally Common Lisp's condition system which a) decouples signaling conditions from handling conditions, b) allows you to execute arbitrary code in the place that signals, c) allows you to stack indepe…
Algebraic effects were introduced by Plotkin in 2001 (https://link.springer.com/chapter/10.1007/3-540-45315-6_1) as an extension of Moggi's 1991 work on monads (https://www.sciencedirect.com/science/article/pii/0890540191...), which in turn built on work from the 70s and 80s on understanding computing from the perspective of category theory.
The chief difference, IMO, is that Pitman defined terminology for a language feature in some LISP dialects, while Plotkin showed operational semantics for algebraic effects that are compatible with the denotational semantics (ie, adequacy). Pitman wrote his paper using the AI Labs' practical experience with LISP for the benefit of other LISP practitioners. Plotkin wrote his paper using previous work on lambda calculus and category theory for the benefit of programming language theorists.
Plotkin may have been unaware of CL's conditions system, but since conditions do not have formal semantics, and their behaviour is not particularly useful for probablistic non-determinism (the main thrust of Plotkin's effects article), I doubt that being aware of it would have made him any less motivated or likely to do the work he did.
Dolan et al (https://link.springer.com/chapter/10.1007/978-3-319-89719-6_...) discuss algebraic effects for concurrency in the setting of a dialect of OCaml, and reference CL conditions (amongst other things) as related work. It's a very brief mention observing only that conditions fail to convey the full continuation as a value to handlers, making them unsuited to the use case at hand.
TL;DR: no, conditions aren't the same thing, and if they were, they lack the rigour to be useful without the work that went into algebraic effects.
Re: Algebraic Effects for the Rest of Us
#66Earlier quoted context omitted.
That's a much nicer, forward pointing comment and it's good to know there's previous act. I've read some bitterness between the lines.
Probably just bitterness from the general trend of reinventing everything in computer science, all the time. People who are unaware of former work on any given topic are forced to reinvent it, poorly. People who are aware of it are forced to watch everyone else reinvent them. Without any sarcasm, communication is a hard and unsolved problem in general.
Re: Algebraic Effects for the Rest of Us
#67Re: Algebraic Effects for the Rest of Us
#68Am I the only one, that thinks that that is not a good feature. Instead A calling B calling C and having a well defined hierarchy and encapsulating complexity you have A calling B calling C calling maybe B calling maybe C again. I mean I see real value in have unidirectional call graphs because they are some much more easier to reason about. I feel like this is another gimmick to break abstractions and increase archi…
Effects are about doing a computation dependent on wider context: IO, thread scheduling, non-deterministic computations, mutable references.
Now, in your example `A calling B calling C and having a well defined hierarchy and encapsulating complexity` you already have effects: threads are being scheduled by OS/runtime, IO is performed, memory cells are written.
The only difference your avg. imperative language with A calling B have is that Effects are implicitly baked into the language, while algebraic effects let you define your own effects as well.
So instead of `async val` you could simply do `(perform Async val)`, which would return val in the context of fiber scheduler (aka will do the necessary scheduling for continuing the computation). With effects you could extend your language with new effectful semantics without descending into metaprogramming hell/fixing the language.
In fact, you could think of Effects as of Monads, but composable.
Re: Algebraic Effects for the Rest of Us
#69Earlier quoted context omitted.
Smalltalk also had resumable exceptions, and I remember implementing then in ruby too, with callcc, but I think algebraic effects are more general and by focusing on exceptions the author has sort of hidden that, even if he kept saying it's just an example.
Like reikonomusha said, CL's condition system is pretty general in itself. The naming choice isn't an accident - the thing that's being "raised" is a "condition" (of which "error" is just a subtype), and what you do with a condition is "signal" it. In CL, most of the time it's used for exception handling, but I've seen code using this system for tasks not related to errors. As a simple example, you can imagine data p…
Re: Algebraic Effects for the Rest of Us
#70"Imagine that you’re writing code with goto, and somebody shows you if and for statements."
10 for a = 0 to 10
20 if a = 5 then goto 40
30 next
40 end
50 print "5"
60 goto 30
I lack imagination.
That said, algebraic effects sounds interesting indeed.