Carbon Copy No.10: Generics Part II #6529
wolffg
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Carbon Copy, December 2025
Here is the new Carbon Copy, your periodic update on the Carbon language!
Carbon Copy is designed for those people who want a high-level view of what's happening on the project. If you'd like to subscribe, you can join announce@carbon-lang.dev. Carbon Copy should arrive roughly (sometimes extremely roughly) every other month.
Toolchain update
As this is the last Carbon Copy of the year, we thought it would be interesting to look back on the toolchain's progress in the past 12 months. Last year, we were celebrating the ability to solve Advent of Code problems in Carbon. This year, let's see how much better we can solve those same problems, by looking at the very first one. Here's what we had a year ago:
And here's what we have now. On the surface, it may appear that not much has changed, but digging deeper, there are major differences reflecting significant advances in the toolchain.
Spotlight: Generics Part II
In today's spotlight, more generics! Generics are Carbon's way of providing extensibility and abstraction to the language. As with most features in Carbon, generics are designed to be consistent, readable, and made of repeating patterns.
There are two major systems, (type-)checked generics and templates. This Spotlight, as with the previous one, focuses on checked generics, which are Carbon-idiomatic. Checked generics are better than templates for compilation speed and early error messages that point clearly at the problem.
Last time, we learned about checked generics through implementing an interface. We'll now cover two variations on that theme:
implvsextend implwhereclausesSometimes, you want a little more, sometimes you change your whole deal
This is a running code example, so let's start with some imports.
In our previous Carbon Copy spotlight, we made
impl Cat as Hairyto give aCatthe ability to beGroom()ed.Groomwas an interface. In this case, let's imagine something a little different with some possible name collisions.We need a ghost to be
Scary.Imagine another interface and an implementation, in the same style as above:
In both cases above, we've used
extend impl, which addsBooto the base's namespace. We can choose not extend the API by droppingextendfromimpl:Getting scarier
But what of a haunted comedy club?
When we try to
Booas we had above, we will have to be specific about what kind of booing we want:If you always meant to be scary, you can use an
aliasto pick that one.Lastly, you are allowed to shadow an implemented identifier:
Bottom line: You should use
extend implwhen you want to include the API in your own, andimplwhen ambiguity would make for confusing reading.This example code is available at https://godbolt.org/z/dnr8qjnxc.
Associated constants
A bear wants honey, but won't get honey from hornets.1 We'd like our bear to be able to open up a hive, but leave a hornet's nest alone. Let's set up some classes.
Now, bears open a lot of things: hives, clams, trash cans, and so on. Let's make a generic container interface that knows about being opened, and opens to contain specific things.
The type
Contentis constant for any particular implementation of this interface. The type is associated withContainerin its particularimplblock.We can see that below with a
whereclause:Now, let's open the hornet's nest:
If bears comes across a
Hive, that's great, but more generally we want them to be able to open anything that containsHoney:This code example is available in https://godbolt.org/z/odnovxnba.
It's worth contrasting this to C++.
InspectGoodiesworks on "Container.Content"whether or not the target type has it in its namespace (e.g.extend implsContainer instead of justimplingit). In C++ templates, it would always look in the namespace of the type of whatever object was passed in. Also, since Carbon is nominal, we can type check early, and bind to the rightOpenright away, or else fail right right away.Is this kind of like Rust? A bit, although
wheregoes in a different place. In Carbon, thewherekeyword acts as a binary operator within type expressions, often inline within parameter lists like[T:! Container where .Content = Honey], and when introducing a declaration in animpl. In Rust checked generics,whereclauses appear as bounds right before the{in a definition.Conclusion
extend implwhen you want to extend the API, and use associated constraints to make sure you're usingwhereto select types inline with type definitionsRecent proposals and issues
If you want to keep up on Carbon’s proposals and issues, follow "Last Week In Carbon". Check out the RSS feed!
Recently accepted proposals including:
Recently closed leads issues including:
Wrap-up
Don't forget to subscribe! You can join announce@carbon-lang.dev. If you have comments or would like to contribute to future editions of Carbon Copy, please reach out. And, always, join us any way you can!
This is our last newsletter of 2025. And happy holidays, whenever your holidays are, and we’ll see you next year!
See you at the airport,
Wolff, Josh, Richard, and the Carbon team
Footnotes
Wait, I hear you cry, can't some wasps make honey? And aren't hornets wasps? Yes, but the wasps that can make honey are not hornets. The real question is whether hornets are yellow with black stripes, or black with yellow stripes. ↩
Beta Was this translation helpful? Give feedback.
All reactions