Daily Note - 2025-06-16
Hey, I'm Hanno! These are my daily notes on Crosscut, the programming language I'm creating. If you have any questions, comments, or feedback, please get in touch!
Yesterday I presented an example of a trait in Rust. Here's that trait again:
trait Format {
fn format(self) -> String;
}
Now, let's define a struct with a method:
struct MyFormat {}
impl MyFormat {
fn format(self) -> String {
String::from("This is a placeholder.")
}
}
This method matches the one in the trait exactly. But if we tried to pass an instance of this struct to yesterday's function, that would not work! Traits in Rust are nominal. If we want to use a struct (or any other value), as an implementation of a trait, we have to implement that trait explicitly:
struct MyFormat {}
impl Format for MyFormat {
fn format(self) -> String {
String::from("This is a placeholder.")
}
}
Note how we need to mention Format
in the impl
block. This isn't right or
wrong. I'm not criticizing Rust here. I just want to note that this could be
different. We could type traits structurally, and accept any type as an
instance of a trait that meets its requirements. And in fact, many languages do
that. Popular examples would be TypeScript and Go.