I've been playing with the idea of platform agnostic libraries that allow you to inject platform things into. Logger is in our platform, Greeting is an external module.
StdoutWriter := [StdoutWriter].{
write! = |_self, msg| Stdout.line!(msg)
}
# Wraps Logger
LoggerWriter := [LoggerWriter].{
write! = |_self, msg| Logger.log!(msg)
}
# Create writer instances
stdout_writer : StdoutWriter
stdout_writer = StdoutWriter
logger_writer : LoggerWriter
logger_writer = LoggerWriter
# Example 1: Inject StdoutWriter into the Greeting module
Stdout.line!("Example 1: Greeting module with StdoutWriter")
Stdout.line!("---------------------------------------------")
Greeting.greet!(stdout_writer, "Alice")
Greeting.farewell!(stdout_writer, "Alice")
Greeting.introduce!(stdout_writer, "Bob", "engineer")
# Example 2: Inject LoggerWriter into the same module
Stdout.line!("Example 2: Same module with LoggerWriter")
Stdout.line!("-----------------------------------------")
Greeting.greet!(logger_writer, "Charlie")
Greeting.farewell!(logger_writer, "Charlie")
Greeting.introduce!(logger_writer, "Diana", "designer")
Yeah, things like this are exactly how to pass effects to generic libraries and packages
Over time, I expect many platforms to implement the same interfaces (or packages to map them to the same interfaces).
That way, you can have tcp interface for example and use it for many platforms implement it. Then many generic libraries can use it to implement tons of different protocols.
Thats what my thinking was. Have a common convention based interface that is compatible across platforms. I feel like that's going to be deeply needed with the one platform per app constraint
Yeah, for any effectful libraries, I think this will be fundamental
It is now easier with static dispatch
Cause you can use an object with static dispatch as an interface
Last updated: Jun 16 2026 at 16:19 UTC