Daily Note - 2025-06-15
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 dropped a lot of jargon and ideas all at once. Let's slow down a bit and go through all that again, step by step, using Rust as an example. First, we're going to define a trait:
trait Format {
fn format(self) -> String;
}
What's happening here, is that we define a trait (which we call Format
). A
trait is just a way to talk about types abstractly. Here we say that for any
type that implements this trait, a function called format
must exist, which
takes a value of that type and returns a String
.
With this definition in place, we can now write a function that uses it:
fn my_fn(value: impl Format) -> String {
format!(
"I have a value here that looks like this: {}",
value.format(),
)
}
So here we have a function that accepts a value, and builds a new String
And
because this function uses the Format
trait we defined earlier, it accepts
any type for which the Format
trait is implemented.
Tomorrow, let's take a closer look at how this works in Rust, and how it could also work differently.