Crosscut

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.