←back to thread

97 points appliku | 1 comments | | HN request time: 0.199s | source
Show context
vips7L ◴[] No.45159540[source]
Maybe I’m not getting it, but isn’t this just interfaces and implementations from the OO world? For example their movie one is:

    interface MovieApi {
        List<Movie> getPopularMovies();
    }
    
What are effects providing over this?
replies(5): >>45159701 #>>45159720 #>>45160356 #>>45162050 #>>45194243 #
KPGv2 ◴[] No.45162050[source]
Implementing an interface results in a class that implements it. From then on, the fact your class implements that interface is entirely obscured from your code. In the case of tracking effects, this is clearly undesirable. (Also, in a language that doesn't have classes, implementing interfaces is difficult for me to think about.)

In the case of algebraic effects, they're functions with type signatures explicating the effects the function has. Those don't go away until somewhere nearer the edge of your program, outside the core, you say "by the way, use this to handle those effects"

Effect handlers also give you control over continuations so you can sequence effects explicitly, which is—speaking as someone who writes a lot of code in a language that has algebraic effects as a core part of the language (Unison)—really powerful. Deciding in some instance how you prioritize IO vs Exceptions, making a thrown error go away and replacing it with an HTTP effect that, wayyyy far away from this code handles all HTTP calls by attaching a self-signed certificate when doing the SSL handshake, or whatever, is very nice.

The more I write in this style, the more interesting techniques I come across.

replies(1): >>45162641 #
1. vips7L ◴[] No.45162641[source]
An interface is just a function signature. Perhaps it might be easier for you to think about as just a function:

    type MoviesApi = void => List[Movie]
I guess the difference is the tracking?