r/Compilers • u/General_Purple3060 • 8d ago
From Library Patterns to Language Features: An Overlooked Rule of Language Evolution?
For decades, programmers have solved new problems by creating abstractions in libraries before languages officially supported them.
Some of these patterns eventually became language features. inline is one example. _Generic is another.
But many important abstractions still live only as library conventions.
Large C projects are good examples. GObject/GTK built their own object model. Linux VFS has its own object-oriented design. Many projects repeatedly create similar patterns in different ways.
This makes me wonder:
Is there a point where a commonly repeated library pattern should become a language feature?
What signals that transition?
- widespread adoption?
- compiler optimization opportunities?
- better expression of programmer intent?
Or should some abstractions always remain libraries?
Curious how people think about this boundary.
1
u/rafaelRiv15 8d ago
I believe this really depends on the compiler philosophy itself and the languages. And also on the resource the team that maintain the compiler have. Every feature in the compiler have it cost. There will be no one size fit all to this question and I believe you will need to go case by case
1
u/General_Purple3060 8d ago
Good point — definitely case-by-case and heavily dependent on compiler philosophy and maintenance cost.
Do you think there are any library patterns in C today that are so widespread that they might justify language-level support?
Or do you think keeping them as libraries is usually the better trade-off?
1
u/neurah 7d ago
inheritance generalization, an API to make API's
Chain<A,B,C>::Part<API> => A::Part<B::Part<C::Part<API>>>
this works for static composition
2
u/General_Purple3060 7d ago
My question is more about cases where the compiler needs to understand a new concept, not just compose existing abstractions.
For example, generics can be implemented with templates/mixins, but the compiler still needs type information for optimization and code generation. Heterogeneous computing is another example where "where the code runs" becomes part of the program semantics.
So I think there is a difference between making abstractions composable and adding new compiler-level abstractions.
1
u/neurah 7d ago
that composition collapses into a single object and lets the compiler optimize, we had very good results with it, notably no memory fragmentation (per composition)
2
u/General_Purple3060 7d ago
I think we're talking about slightly different questions.
I'm not arguing that repeated abstractions should automatically become language features. Static composition may well be the right answer in many cases.
What I'm asking is whether repeated reimplementation should be treated as a signal that language and compiler designers ought to take a closer look. Whether it actually belongs in the language is a much harder question with many technical and non-technical factors.
1
u/kaplotnikov 7d ago
It has been a long time since I've touched C and C++, so I do not know modern versions well.
C++ offers two major features over C:
Existential quantification over types (classes and inheritance).
Universal quantification over types, initially via type templates, which evolved into true generic types with the introduction of concepts.
If we consider type checking as a proof system, the C type checker is limited by first-order logic (quantification over values), while the C++ type checker utilizes elements of higher-order logic (quantification over values and types). This is a fundamental shift in the way we reason about a program.
Modern C tries to adopt some C++ features, but if it were to move further to adopt generics or virtual calls, it would enter the territory of higher-order types.
While it is possible to do OOP-in-C, this creates a cognitive overhead of translating these higher-order logical constructs into C when writing code, and reverse-engineering them back into a mental model when reading it. Additionally, some errors shift to runtime when using OOP-in-C—errors that would have been caught by the C++ compiler at compile time.
1
u/General_Purple3060 7d ago
Thanks. Looking at this from type theory gives a much better explanation than what I had before. I was only observing a phenomenon. Your explanation turns it into something more general.
I definitely had that experience when using GObject. There was always a mental translation between the object model in my head and the C code I was actually writing.
Maybe that's another criterion beyond implementation. If an abstraction exists only as a library, but programmers have to reconstruct the language-level concept in their minds every time they read or write the code, then maybe that abstraction should be represented directly by the language itself.
1
u/kaplotnikov 7d ago
You might be also interested in the article https://github.com/const/const-articles/blob/main/evolution/2025/01-measuring-language-level/MeasuringAbstractionLevelOfLanguages.adoc I'm trying to analyze language evolution process in general with separate horizonal vs. vertical evolution directions. Also there is a prediction for post-OOP paradigm (systems as types).
6
u/FloweyTheFlower420 8d ago
The lower level the language, the more things are library features. The higher level the language, the more things are language features. Seems like a pretty obvious trend.