# C++ 20's concepts are typeclasses and make object-based polymorphism obsolete - shockingly!

**URL:** <https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128>\
**Category:** Uncategorized\
**Created:** [July 27, 2023, 11:06pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128 "2023-07-27T23:06:26Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![rubenmoor](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/rubenmoor/32/2075_2.png) [@rubenmoor](https://discourse.haskell.org/u/rubenmoor)\
**Post date:** [July 27, 2023, 11:06pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/1 "2023-07-27T23:06:26Z")

</div>

I am a haskelly guy who turned game developer and find myself inside the depths of C++.

[![](https://img.youtube.com/vi/gTNJXVmuRRA/maxresdefault.jpg "Using Modern C++ to Eliminate Virtual Functions - Jonathan Gopel - CppCon 2022") ](https://www.youtube.com/watch?v=gTNJXVmuRRA&t=2425s)

So I found this quite funny and maybe someone here finds it funny/interesting, too.

Polymorphism in C++ is usually embodied by inheritance with virtual functions, i.e. I create a new type, called class in C++ of course, that implements the “virtual functions” of some other type (the “parent class”). This, arguably, is the defining chracteristic of object-oriented programming (I know that defining object-orientation is contentious and for good reasons).

In this talk, which is quite pleasant to watch and really interesting, the speaker puts a bold statement on his last slide. You don’t actually need to watch it, to participate in my amazement: with modern C++ you don’t need virtual.

Less cryptic, he is saying

**The feature called _concepts_ of the new C++ standard, which really is the same as type-classes in Haskell, makes inheritance (object-oriented polymorphism) redundant.**

I am not spiteful. Usually C++ developers are well aware that their toolbox isn’t sexy. There are usually practical reasons, most often just a huge legacy codebase that is still worth maintaining somehow.

But yes, I find it funny what kind of detour C++ takes to (somehow, a little bit) abondon object-orientation. Given that modern C++ also allows modules (finally!), encapsulation, which would be the second-most important characteristic of object-oriented programming (my opinion) doesn’t imply the use of C++ classes anymore, either.

* * *

In other news: Modern C++ has support for “lazy lists” in the form of ranges and function composition (not for functions in general, though).

So does that mean, Haskell guys can just switch to C++ and excel there, too? Well of course some of them can … but don’t expect to use any of those modern C++ features. As I said, the reason why C++ is employed are quite often legacy code-bases. Modern C++ is backwards compatible (there really wouldn’t be a point, otherwise) but you can’t count on the specific C++ compiler to actually support the modern world. Less can you count on support of your coworkers and bosses, who can’t read your code anymore, once you get serious with concepts.

Also, the legacy of old-world C++ still weighs heavily. Backwards compatiblity implies awfully strange syntax and a good deal of keyword recycling in the new features. It’s like doing type artihmetic in Haskell until you discover Idris 😉

---

<div class="post-metadata">

**Author:** ![jhenahan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/jhenahan/32/3578_2.png) [@jhenahan](https://discourse.haskell.org/u/jhenahan)\
**Post date:** [July 27, 2023, 11:25pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/2 "2023-07-27T23:25:36Z")

</div>

Periodically I peer in on the C++ communities and marvel at some of the really cool things they’ve invented in order to avoid learning FP (joke).

In seriousness, I have seen some really nice demo code using concepts, and while it doesn’t read like C++ at all, it does seem like a language I could reach for in anger when I needed it.

---

<div class="post-metadata">

**Author:** ![rubenmoor](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/rubenmoor/32/2075_2.png) [@rubenmoor](https://discourse.haskell.org/u/rubenmoor)\
**Post date:** [July 27, 2023, 11:30pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/3 "2023-07-27T23:30:33Z")

</div>

What robs me of fun some of the days is the endless stream of null-pointer exceptions. Their conceptual origin lies partly in the design of the language but **could** be addressed by better library design, too. So unfortunately, libraries with interfaces that don’t drive you insane aren’t that common in the C++ ecosystem.

So in the end, C++ would be fun if it weren’t for the legacy code. And if it weren’t for the legacy code, C++ wouldn’t be.

---

<div class="post-metadata">

**Author:** ![jhenahan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/jhenahan/32/3578_2.png) [@jhenahan](https://discourse.haskell.org/u/jhenahan)\
**Post date:** [July 27, 2023, 11:42pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/4 "2023-07-27T23:42:57Z")

</div>

This is my lament with Scala’s insistence on Java compat. The number of times I’ve seen a codebase using

```haskell
Option(SomeJavaThingThatCouldBeNull).getOrElse(null)

```

is truly upsetting.

---

<div class="post-metadata">

**Author:** ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)\
**Post date:** [July 28, 2023, 9:25am UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/5 "2023-07-28T09:25:38Z")

</div>

> [@jhenahan](#):
>
> Periodically I peer in on the C++ communities and marvel at some of the really cool things they’ve invented in order to avoid learning FP (joke).

> [@](#):
>
> When FP just pass all the functions and data required for specialization of generic algorithm, OOP provides interfaces, virtual functions, anonymous classes, delegates and lots of other interesting ways to hide the fact of lack of first-class functions `:)`
> 
> Bulat Ziganshin.

* * *

> [@rubenmoor](#):
>
> The feature called _concepts_ of the new C++ standard, which really is the same as type-classes in Haskell […]

- What extra advantages do concepts provide over plain ol’ ~~[_function_](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.628.7053&rep=rep1&type=pdf)~~ [procedure overloading](https://www.cs.fsu.edu/~myers/c++/notes/functions2.html)?

- Or will that feature be (eventually) subsumed by the concept system?

---

<div class="post-metadata">

**Author:** ![rubenmoor](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/rubenmoor/32/2075_2.png) [@rubenmoor](https://discourse.haskell.org/u/rubenmoor)\
**Post date:** [July 28, 2023, 8:55pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/6 "2023-07-28T20:55:47Z")

</div>

Concepts allow to define a hierarchy between them, quite similar to the way type classes do (and object-based polymorphism, too)

Also, concepts are more flexible in that they allow a difference in the return type. And next to function overloading, concepts allow class overloading.

---

<div class="post-metadata">

**Author:** ![rubenmoor](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/rubenmoor/32/2075_2.png) [@rubenmoor](https://discourse.haskell.org/u/rubenmoor)\
**Post date:** [July 28, 2023, 9:07pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/7 "2023-07-28T21:07:27Z")

</div>

Interesting thought by the way. I have never though of function overloading as such a powerful concept. And while it’s limited, it it quite powerful now that you made me think of it.

One could argue, Haskell typeclasses are just overloaded functions where the instance is an implict parameter. (ignoring the problem with the return type)

And indeed, being more **explicit** about Instances would alleviate the orphaned instance problem in Haskell

---

<div class="post-metadata">

**Author:** ![jaror](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/jaror/32/3271_2.png) [@jaror](https://discourse.haskell.org/u/jaror)\
**Post date:** [July 28, 2023, 9:29pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/8 "2023-07-28T21:29:12Z")

</div>

> [@rubenmoor](#):
>
> Haskell typeclasses are just overloaded functions

They needn’t be overloaded, the implicit parameter itself could be parameterized. E.g.:

```haskell
data Monoid_ a = Monoid_ { mempty_ :: a, mappend_ :: a -> a -> a }

mappend :: Monoid_ a -> a -> a -> a
mappend = mappend_

```

See [Haskell for all: Scrap your type classes](https://www.haskellforall.com/2012/05/scrap-your-type-classes.html) for more.

> [@rubenmoor](#):
>
> And indeed, being more **explicit** about Instances would alleviate the orphaned instance problem in Haskell

It would also fundamentally change the nature of type classes. Also, orphan instances are not really the problem. The problem is that GHC only checks instances at usage sites, while it should be checking instances when importing.

I’d strongly recommend reading Section 4 of the [Non-Reformist Reform for Haskell Modularity by Scott Kilpatrick](https://people.mpi-sws.org/%7Eskilpat/papers/kilpatrick-thesis-nov-2019-publication.pdf) for a much more detailed discussion of this topic.

I am interested to hear how C++ has tackled this issue. Does it allow explicit instantiation of concepts?

---

<div class="post-metadata">

**Author:** ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)\
**Post date:** [July 28, 2023, 9:44pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/9 "2023-07-28T21:44:44Z")

</div>

> [@rubenmoor](#):
>
> Also, concepts are more flexible in that they allow a difference in the return type.

Function overloading can work with varying return types:

> [@](#):
>
> (page 63 of 144)
> 
> ```
> + : number × number → number
> + : set α × set α → set α
> ```
> 
> [The Implementation of Practical Functional Programming Languages](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.628.7053&rep=rep1&type=pdf) (1990)

* * *

> [@jaror](#):
>
> I am interested to hear how C++ has tackled this issue.

`:-D` …that was my next query, considering that [Haskell overloading is _DEXPTIME_-complete](http://www2.in.tum.de/bib/files/Seidl94Haskell.pdf).

---

<div class="post-metadata">

**Author:** ![simonpj](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/simonpj/32/890_2.png) [@simonpj](https://discourse.haskell.org/u/simonpj)\
**Post date:** [July 28, 2023, 10:07pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/10 "2023-07-28T22:07:36Z")

</div>

> **The feature called _concepts_ of the new C++ standard, which really is the same as type-classes in Haskell, makes inheritance (object-oriented polymorphism) redundant**

You might enjoy my talk [Classes, Jim, but not as we know them](https://www.youtube.com/watch?v=tqx9_MQbQ_c). It was first presented at ECOOP 2009.

My thesis in the talk is that

- OO and inheritance is one way to achieve _polymorphism_: writing one blob of code that works on arguments of various types.
- Parametric polymorphism (as in Haskell or ML) is another way to achieve polymorphism.
- As it happens though, OO languages have adopted parametric polymorphism (which they call generics) as well. The result is quite complicated.

My slightly tongue in cheek conclusion is this: once OO languages have adopted the full glory of parametric polymorphism, the scaffolding of inheritance and subtyping will be increasingly redundant. So maybe we can do without it. Which is kind of what you are saying too.

I’m not sure I truly believe this: subtyping is an appealing thing. But Haskell (which has no subtyping) gets a long long way without it.

The talk has more!

---

<div class="post-metadata">

**Author:** ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)\
**Post date:** [July 28, 2023, 11:35pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/11 "2023-07-28T23:35:35Z")

</div>

> [@simonpj](#):
>
> My slightly tongue in cheek conclusion is this: once OO languages have adopted the full glory of parametric polymorphism, the scaffolding of inheritance and subtyping will be increasingly redundant.

Dependent types in C++? Hey, why not! It has just about everything else…

---

<div class="post-metadata">

**Author:** ![graninas](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/graninas/32/983_2.png) [@graninas](https://discourse.haskell.org/u/graninas)\
**Post date:** [July 29, 2023, 6:33am UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/12 "2023-07-29T06:33:50Z")

</div>

Concepts in C++ have been indeed inspired by Haskell’s type classes. This is only one thing the modern C++ has adopted from Haskell, in addition to many others (ranges, monad-like expected and optional types etc).

I have the talk “Like in Haskell: Final Tagless and eDSL on concepts”. The slides are [available here](https://docs.google.com/presentation/d/1TOCsNYEYnT0VXcGQOZETxEv5W8SsXIa_G7z4BQbHsxg/edit?usp=sharing).

---

<div class="post-metadata">

**Author:** ![sol](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/sol/32/3299_2.png) [@sol](https://discourse.haskell.org/u/sol)\
**Post date:** [July 31, 2023, 12:15am UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/13 "2023-07-31T00:15:51Z")

</div>

There has been a lot of talk recently about Haskell losing market-share to languages like Rust.

And that maybe be true, but on the other hand, if you look at the trajectories of other languages: Rust, Swift, Scala, Java, Javascript, Python, C++, etc. It’s pretty easy to claim that “Haskell Won”. Almost all improvements to other languages over the last few decades are basically just them adopting features from Haskell. Lambdas won. Static typing won. Type classes won. Parametric polymorphic won. The list goes on.

All of the other languages are racing to become more like Haskell without breaking their existing niches.

---

<div class="post-metadata">

**Author:** ![graninas](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/graninas/32/983_2.png) [@graninas](https://discourse.haskell.org/u/graninas)\
**Post date:** [July 31, 2023, 12:28am UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/14 "2023-07-31T00:28:06Z")

</div>

Haskell has indeed influenced a lot of languages, but it’s not the only FP language that did this. There is Lisp, there is Erlang, there is Clojure. There are many other languages with a lot of interesting features.

Parametric polymorphism was widely known before Haskell. As well as lambdas and static typing.

No, static typing is far from winning.

In general, the fact that many Haskell ideas came into other languages, doesn’t help Haskell that much.

Haskell has failed successfully.

---

<div class="post-metadata">

**Author:** ![hellwolf](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/hellwolf/32/3020_2.png) [@hellwolf](https://discourse.haskell.org/u/hellwolf)\
**Post date:** [July 31, 2023, 7:34am UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/15 "2023-07-31T07:34:52Z")

</div>

I feel obliged to share Stroustrup’s own words: [Bjarne Stroustrup - Object Oriented Programming without Inheritance - ECOOP 2015 - YouTube](https://youtu.be/xcpSLRpOMJM)

Yes, even he thinks that we might not need those subtyping related scaffolding after all.

---

<div class="post-metadata">

**Author:** ![rubenmoor](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/rubenmoor/32/2075_2.png) [@rubenmoor](https://discourse.haskell.org/u/rubenmoor)\
**Post date:** [August 2, 2023, 6:37pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/16 "2023-08-02T18:37:10Z")

</div>

I would offer that there is this ghost called object-orientation. For me, replacing any discussion of object-orientation with the discussion of well-defined concepts, is a huge step forward.

I learned a couple of new words in this thread. And those replace the confusing umbrella notion of object-orientedness. And modern C++ doesn’t rely on that anymore, either.

---

<div class="post-metadata">

**Author:** ![graninas](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/graninas/32/983_2.png) [@graninas](https://discourse.haskell.org/u/graninas)\
**Post date:** [August 2, 2023, 6:51pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/17 "2023-08-02T18:51:33Z")

</div>

People outside of the FP world also consider it to be confusing. And the degree of this confusion is much higher for Haskell with its math-inspired jargon.

My long-standing position is that OOP doesn’t deserve what haskellers usually say about it. OOP is a rich toolbox. OOP has many facets, as FP does. OOP has many good applications and is very driven by pragmatism.

I do not support the common Haskell narrative that OOP is BS.

---

<div class="post-metadata">

**Author:** ![rubenmoor](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/rubenmoor/32/2075_2.png) [@rubenmoor](https://discourse.haskell.org/u/rubenmoor)\
**Post date:** [August 2, 2023, 7:01pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/18 "2023-08-02T19:01:06Z")

</div>

ah well, to me, functional programming vs. object-oriented programming is a false dichotomy.

and in order to bring about an argument, or: in order to have an opinion whether or not object-oriented programming “is BS”, we would first have to agree on what it is.

We can talk about subtype polymorphism, for example. (that’s one of the new words I learned)

---

<div class="post-metadata">

**Author:** ![anon58422685](https://avatars.discourse-cdn.com/v4/letter/a/67e7ee/32.png) [@anon58422685](https://discourse.haskell.org/u/anon58422685)\
**Post date:** [August 2, 2023, 7:26pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/19 "2023-08-02T19:26:12Z")

</div>

Would it be very rude if I hijacked this thread for a question of my own? There are such knowledgeable people gathered here. This might be my only chance to learn.

@rubenmoor says:

> [@rubenmoor](#):
>
> I know that defining object-orientation is contentious and for good reasons

From what I have seen so far, there are two kinds of definitions:

- Null definition. This is most often seen.
- The definition from the book _A Theory of Objects_ by Martín Abadi and Luca Cardelli.

The latter definition is fairly long. It proceeds by enumeration of features, such as method lookup and subclass relation, and an object oriented language they define _(though they do not say it)_ as a [family resemblance](https://en.wikipedia.org/wiki/Family_resemblance).

After thinking for a while, I figured a few possible definitions out for myself.

1. If a language allows to syntactically localize a type with memory claiming and freeing _(constructors and destructors)_, then it is object oriented. Historically, this seems to be the killer feature of C++ that let it overcome C — you can forget what exactly you allocated in the heap and how to free it, because C++ remembers this for you. Then, Haskell is not object oriented because it has no notion of memory claiming and freeing to begin with.

2. An object is a constant space simulation of a discrete dynamical system, or an automaton, or a computation with state. An object oriented language is such that supports these constant space simulations. Labels for state transitions are called _«methods»_. Haskell would be object oriented with its _«state monad»_ type, but simulations of this type are generally not constant space. The magical `ST` monad and various mutable vector types seem to make Haskell truly object oriented but there are only a few types of objects and it is hard to make more.

3. An object oriented language is such that has automatic subtyping. I have found that object oriented _«classes»_ are essentially product types _(there being methods notwithstanding)_. We can equip a set of typed labels defining an object with the power set lattice structure and derive inheritance from that. For example, _{a: String, b: Integer}_ is a super-type of _{a: String, b: Integer, c: Boolean}_. In Haskell, we cannot automatically cast between these types, so Haskell is not object oriented by this definition. If we equip all records with the `Has` class thing, then maybe we can get automatic subtyping and then Haskell would be object oriented by this definition.

Does either of these definitions make sense?

My background is 95% Haskell, so I do not have a lot of practical experience with object oriented languages. For example, I have never needed to inherit something, and it is a mystery for me as to why someone would design a language to specifically support inheritance. But I understand the pain of not having extensible records — I wanted to have them, I know I could make them with type level magic, but I also know it would be a syntactic disaster. So, I am trying to understand the discourse about object oriented stuff from the experience that I do have.

I apologize again if this intrusion is not welcome.

---

<div class="post-metadata">

**Author:** ![Probie](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/probie/32/3232_2.png) [@Probie](https://discourse.haskell.org/u/Probie)\
**Post date:** [August 2, 2023, 8:19pm UTC](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128/20 "2023-08-02T20:19:16Z")

</div>

“Object orientation” is an idea, nothing more. It’s worth distinguishing between “object orientation” and an “object oriented language” You can write object oriented code in regular C (for example GObject from glib, or QObject which is used internally in qemu), it’s just that an object oriented language has first class support for it.

Of course, like everyone else, I haven’t defined what “object orientation” is. I define “object orientation” as “having things called objects which have fields and use dynamic dispatch”. I’ve picked this definition because it’s the only member of the intersection of what everyone claims is “object orientation” that I can think of.

Anything around “automatic subtyping” doesn’t make sense in a dynamically typed language, and there are many object oriented languages which are dynamically typed (for example, the one for which the term was coined - Smalltalk). As for subclasses? Inheritance is optional - Golang gets by without it since “composition” is often adequate. Even classes are optional - JS gets by without them and is often called object-oriented, and I don’t think that’s a misnomer since I’ve seen a lot of GoF design patterns appear in JS code. If we look at the lisp-y object systems like CLOS or goops we also see that methods don’t have to be directly attached to objects (if they are attached directly to objects, implementing multiple dispatch is much harder).

[Next page](https://discourse.haskell.org/t/c-20s-concepts-are-typeclasses-and-make-object-based-polymorphism-obsolete-shockingly/7128.md?page=2)
