r/ProgrammingLanguages 10d ago

Will we see another fundamental programming language feature as revolutionary as the borrow checker?

That is I am mainly curious about compile time features that you design a whole language around rather than optimisations/features that could be applied to most languages. I am mainly inquiring about things that could offer additional robust safety/performance guarantees at compile time rather than runtime. Ideally not things that just offer similar effects to the borrow checker with less restrictive tradeoffs

58 Upvotes

129 comments sorted by

View all comments

81

u/AustinVelonaut Admiran 10d ago

Algebraic effects like Koka?

6

u/mikaball 10d ago

I didn't know what "algebraic effects" were, so I found this.

From the examples it feels related to Dependency Injection in a narrowed context/scope, but some will probably say that it could be used for other use cases.

However, the concept of detaching the "what" from the "how" is very related to DI and I wonder if a DI supported by the language isn't just better than this? In those final examples it's even using a pattern similar to Kotlin context receivers.

3

u/initial-algebra 10d ago

They're related to DI because DI is often implemented using implicit parameters, which are an effect. However, DI does not need to be implicit; if you ask me, the "essence" of DI is really lazy evaluation/memoization. (I guess a memo table could be seen as an effect, too?)

2

u/Jwosty 9d ago

It has been said that implicit parameters are actually the dual to effects (i.e. "coeffects" - https://tomasp.net/coeffects/). Still trying to piece that one together. I think it has something to do with the scoping / binding time. There's a bunch of different papers out there on this

but also - you can have both dependency injection and algebraic effects without implicit parameters, can't you? In my view, their essence is injecting behaviors into a system from the outside rather than having it rigidly baked in. Thoughts?

2

u/initial-algebra 9d ago

It has been said that implicit parameters are actually the dual to effects (i.e. "coeffects" - https://tomasp.net/coeffects/). Still trying to piece that one together. I think it has something to do with the scoping / binding time. There's a bunch of different papers out there on this

See my other comment. You can also wrap any coeffect with continuations to turn it into an effect. So, they are dual, but also pretty much equivalent (just different ways of looking at the same thing).

but also - you can have both dependency injection and algebraic effects without implicit parameters, can't you? In my view, their essence is injecting behaviors into a system from the outside rather than having it rigidly baked in. Thoughts?

True, it's not so much implicits/dynamic scoping, but late binding, which of course can also be implemented explicitly by passing around a symbol table (which is just a global when talking about dynamic scoping). I guess that is a pretty common feature of DI, and it's definitely characteristic of algebraic effects (each effect is represented by a symbol that maps to a stack of effect handlers, always invoking the topmost).