Hacker News new | ask | show | jobs
by noelwelsh 28 days ago
You're right, they are related. One difference is simply lineage. Capabilities come out of the erights / security world (e.g. [0]), while dependency injection comes from the XP / agile / Martin Fowler world. More interesting is that to do capabilities correctly you need some type system extensions, namely capture checking. Essentially, this means you delimit where a program can hold a reference to a value derived from a capability. So if you have a function that allocates memory, you can say "there are no references to any allocated memory outside this function call" and hence no use-after-free bugs. It gives a form of resource management that is simpler than Rust's lifetimes. See [1] and [2]. (Technically it's a modal type system versus Rust's substructural type system.) To my mind it's an obvious thing for Zig to add.

Shameless plug. If you're interested in more on this, for a programmer's rather than academic perspective, this is going into my book [3]. I'm writing the chapter of capability passing right now.

Back to writing!

[0]: https://blog.acolyer.org/2016/02/16/capability-myths-demolis...

[1]: https://effekt-lang.org/tour/captures

[2]: https://docs.scala-lang.org/scala3/reference/experimental/cc...

[3]: https://functionalprogrammingstrategies.com/

1 comments

So it's essentially low level dependency injection where it's not just about the interface but the system and it's resources too, right?

I will take a look at your content, these topics interest me a lot.

That's a reasonable way of looking at it, but capabilities are not restricted to low-level system properties. Here's a terminal UI system built around three main capabilities:

- layout (adding components to the component tree) - event (handling user input events) - react (reacting to changes in reactive values)

https://github.com/creativescala/terminus/tree/main/ui/share...

This is the case study I'm using for the book chapter.