4 ms·
> Effect handlers let you define advanced control abstractions, like exceptions, async/await, iterators, parsers, ambient state, or probabilistic programs, as a
by jitl 3y ago
> Effect handlers let you define advanced control abstractions, like exceptions, async/await, iterators, parsers, ambient state, or probabilistic programs, as a user library in a typed and composable way.
> Perceus is an advanced compilation method for reference counting. This lets Koka compile directly to C code without needing a garbage collector or runtime system! This also gives Koka excellent performance in practice.
Effectful functional language that compiles to C? Sounds great.
- phoe-krk 3y agoAlso, as a Lisp programmer, I absolutely loved reading the section at https://koka-lang.github.io/koka/doc/book.html#sec-handlers https://koka-lang.github.io/koka/doc/book.html#sec-handlers - it's essentially like using the Common Lisp condition system, making me feel at home, except it's more generalized (e.g. masking individual condition handlers is not generally possible in CL) and also working in a strongly statically typed environment.
- nerdponx 3y agoAs far as I understand the PL theory involved, it's statically-typed delimited continuation, which I think is even more general than the CL condition system.
- kazinator 3y agoIn CL, you can control the visibility of restarts. In the restart-bind construct, there is a :test-function which serves as a predicate that determines whether the restart is visible. (Unfortunately, this function is referred to as a condition). While restarts can be visible or not, I believe there is no such mechanism for handlers. However, handlers can be effectively invisible/transparent by declining to handle a condition, which they can do simply by returning instead of perpetrating a non-local transfer. Also, there doesn't seem to be an API in Common Lisp for calculating the handlers visible at a given point for a condition of a given type. So that means that the ability of a handler to decline a condition is pretty much as good as a visibility mechanism.
- nerdponx 3y agoI've only played around with it a little bit, but it really is a cool language. I particularly enjoyed this presentation, which is what sold it to me as a good idea worth spending some time on: https://youtu.be/6OFhD_mHtKA https://youtu.be/6OFhD_mHtKA OCaml 5.0 also interestingly includes an effect handler system: https://v2.ocaml.org/manual/effects.html https://v2.ocaml.org/manual/effects.html
- jitl 3y agoI’ve been following the road to OCaml 5 and the effect system is nice, but getting to have effects without bringing in a garbage collector seems quite special. I’m working on a C-WASM wrapper library, and one issue I struggle with in C code is dealing with async IO outside the WASM module. I haven’t looked deep into the FFI story of this new language but it would directly solve this problem that currently needs the ASYNCIFY Binaryen transform which adds a 2x size increase and 50% performance penalty. Can Koka call C in an effect? Can it suspend a stack if C calls into it? I can presumably drop koka into my existing C-WASM project with a few new Makefile rules. These are definitely places OCaml can’t go; by compiling to C Koka makes these advanced FP features much more attainable (at least, for me).
- naasking 3y agoThey have a C library for writing effect handlers in C, so you could potentially just use that directly: https://koka-lang.github.io/nodec/api/group__effect.html https://koka-lang.github.io/nodec/api/group__effect.html On GitHub: https://github.com/koka-lang/libhandler https://github.com/koka-lang/libhandler I believe it grew out of this prior work: https://news.ycombinator.com/item?id=14887341 https://news.ycombinator.com/item?id=14887341
- frigid 3y agoKoka is garbage collected. There are several terminology ambiguities in play: the documentation takes "garbage collection" to refer to tracing garbage collection as opposed to runtime cost of any sort, which while common in some circles seems less so common as a whole (this is extremely confusing, all the time). This runtime overhead is reference counting and so is going to be a whole lot nicer to deal with (especially re: C FFI) than tracing, but it does exist. The reason Koka's GC is interesting despite being based on reference counting is that its ownership system eliminates most of these reference checks at compile time - and additionally can tell whether to use atomic RC (slow but threadsafe for shared data) or non-atomic RC (fast but only threadsafe when data is moved across threads, not shared). This ownership analysis is very similar to what some other languages like Nim do (except Nim differs in not allowing atomic RC at all). The other strange terminology that is occasionally tossed around in Koka documentation is "garbage free": Koka takes this to mean that at any given point in the program, there is no memory waiting to be freed. This is because the ownership analysis lets the compiler know exactly where the last use (or possible last use) is and insert destructors accordingly. All of that has made Koka's GC algorithm fast and low-overhead enough that it's competitive with state-of-the-art tracing GCs (specifically, OCaml's GC). I haven't seen benchmarks comparing it to manual memory management or strict ownership systems but that's not terribly the point - manual memory management is unsafe and strict ownership is complicated + inexpressive on occasion. Koka's system might just be the best you can get, with those tradeoffs in mind. Anyway, this doesn't answer your question at all. Sorry. I hope it's interesting, though.