Live data from Hacker News

Defining interfaces in C++ with ‘concepts’ (C++20)

lemire.me

61–70 of 77 posts

Re: Defining interfaces in C++ with ‘concepts’ (C++20)

#61

Earlier quoted context omitted.

C++ templates have never used runtime dispatch

I assume you've checked the version control history of every C++ compiler in existence?

It would be extremely hard to implement templates with dynamic dispatch while maintaining the correct semantics.

Re: Defining interfaces in C++ with ‘concepts’ (C++20)

#62
post #47

Earlier quoted context omitted.

Again, wait until Rust gets 40 years of history deployments, distributed from the tiny 8 CPU, to HPC workloads and FPGAs, or stuff running on Mars. I doubt very much that Rust editions and backwards compatibility history will be able to survive 40 years with such diverse use cases, without introducing accidental complexity and corner cases along the way. This assuming that we can still use Rust and not Crab , as if R…

Rust is not designed for 8-bit CPUs like Tiny8. The smallest usize is allowed to be is 16 bits. In practice on these very tiny devices high level languages are total overkill. Grace's original "compiler" concept makes sense, but today's assemblers are more than sufficiently capable. You can literally memorise what all the individual memory locations (actually Tiny8 just admits they're registers, it's not as if it wou…

Wait, maybe you meant one of the other "8-bit" CPUs which actually have 16-bit address bus? That's kinda cheating but yes now we might actually want a programming language, we've got all this RAM to play with, we can make a stack, we can invent data structures, sure, Rust is fine with that setup. Or well, it's crippled, but not in any surprising ways you care about.

But it doesn't seem like there are interesting lessons here? Running the compiler on this sort of hardware was torment (I know, I'm old, I wrote my first software in the 1980s for a Commodore Vic 20, my program source code didn't fit in RAM so my parents had to buy a RAM expansion) but we just wouldn't do that today, we can cross compile from say, a Raspberry Pi, or even a real computer.

Re: Defining interfaces in C++ with ‘concepts’ (C++20)

#63
post #55
post #48

Earlier quoted context omitted.

I can't wait for C++64. But "just wait until Rust will repeat C++'s mistakes" is just pure speculation. Language evolution doesn't have to make the language worse. Java, JS, C#, or Ada are pretty old now, and have been doing fine. Rust is well prepared for a 40-year lifespan with its edition system.

You quite clearly are unware of the evolution pain points to move past Java 8, .NET Framework 4.8, and how the Java community embraces Java 20, or the C# one sees C# 12, and the rate they are adding new features. As for JS, everyone knows the mess of the Web ecosystem and frontend development. Ada is doing just fine, as most vendors are still adopting Ada 2012. Ada Core and PTC are the only ones with the latest versi…

But the ecosystem lagging years behind the latest version is a separate problem, and one that ironically the 6-week release cycle of Rust helps with: there are no major upgrades to fear, and small frequent releases make the ecosystem move with the compiler instead of having time to ossify and choose to stay on an old version (the same way nobody chooses to stay on an old Chrome, but people used to stick to good'ol versions of IE and Netscape).

Re: Defining interfaces in C++ with ‘concepts’ (C++20)

#64
post #63
post #55

Earlier quoted context omitted.

You quite clearly are unware of the evolution pain points to move past Java 8, .NET Framework 4.8, and how the Java community embraces Java 20, or the C# one sees C# 12, and the rate they are adding new features. As for JS, everyone knows the mess of the Web ecosystem and frontend development. Ada is doing just fine, as most vendors are still adopting Ada 2012. Ada Core and PTC are the only ones with the latest versi…

But the ecosystem lagging years behind the latest version is a separate problem, and one that ironically the 6-week release cycle of Rust helps with: there are no major upgrades to fear, and small frequent releases make the ecosystem move with the compiler instead of having time to ossify and choose to stay on an old version (the same way nobody chooses to stay on an old Chrome, but people used to stick to good'ol ve…

Lagging behind is only one issue, I explicilty mentioned the drama of newer updates that make many unconfortable given the rate that they now are coming with changes for the sake of it, just go read the comments on the C# 12 features announcements for a taste of it.

Re: Defining interfaces in C++ with ‘concepts’ (C++20)

#65

Earlier quoted context omitted.

I assume you've checked the version control history of every C++ compiler in existence?

It would be extremely hard to implement templates with dynamic dispatch while maintaining the correct semantics.

templates don’t exist after the front end. there is no ABI that allows them to exist in any object file. there is no object file format they could be embedded in, sans a string representation of the source they came from.

extremely hard is underselling it somewhat :)

Re: Defining interfaces in C++ with ‘concepts’ (C++20)

#66
post #25

> So what are concept good for? I think it is mostly about documenting your code. Emphasis mine. While it is somewhat good as documentation, sometimes static_assert with a custom diagnostic message is sometimes better for this purpose. The hidden power of concepts/constraints is the way it shapes overload sets. You can have something like: template void foo(R&& r) { /* some generic algorithm */ } template void foo(R&…

Indeed. I haven't found concepts to be very good at generating error messages. But they are great for documentation and to get rid of SFINAE hacks for overloading. The shorter template syntax is a bonus. edit: concepts should also allow for better IDE tooling, for example proper completion inside template functions; although it is supposed to work, I didn't notice it firing yet in clangd.

In Qt Creator I can see the interface defined by a concept upon autocomplete

Re: Defining interfaces in C++ with ‘concepts’ (C++20)

#67
post #18
post #14

Earlier quoted context omitted.

That's something I have been pondering for some time. I believe it's a false dichotomy. My thought is still that structural supersedes nominal . A nominal interface is just another constraint added to the list of constraints of an underlying structural interface?

In a nominal type system, a method x() is part of the interface X, while in a structural one it's part of the implementor of said interface. In Go there's a Human.HasOrgan(), not an AbstractBody.HasOrgan(). A consequence of this is that in Rust, which has a nominal system, you can implement two traits that contain a method with the same name and are required to disambiguate at the call site. In Go you can't do that,…

Fair. That's not really in contradiction too.

The additional naming constraint added to a structural interface would form a sort of namespace for methods.

I think in the comments below that someone likens this to tags in C++.

Re: Defining interfaces in C++ with ‘concepts’ (C++20)

#68
post #67
post #18

Earlier quoted context omitted.

In a nominal type system, a method x() is part of the interface X, while in a structural one it's part of the implementor of said interface. In Go there's a Human.HasOrgan(), not an AbstractBody.HasOrgan(). A consequence of this is that in Rust, which has a nominal system, you can implement two traits that contain a method with the same name and are required to disambiguate at the call site. In Go you can't do that,…

Fair. That's not really in contradiction too. The additional naming constraint added to a structural interface would form a sort of namespace for methods. I think in the comments below that someone likens this to tags in C++.

A nominal type system is not a more constrained version of a structural one. That statement would imply that any program written for the former would work using the latter as well, which is false. Name collisions would simply not resolve.

For it to work, you need to add a namespace to all the colliding methods (a simple one would be a prefix like people do in C).

A nominal system is a more constrained structural system in some ways, but the opposite is true as well, so it's not as simple as 'nominal is subset of structural'.

Re: Defining interfaces in C++ with ‘concepts’ (C++20)

#69
post #68
post #67

Earlier quoted context omitted.

Fair. That's not really in contradiction too. The additional naming constraint added to a structural interface would form a sort of namespace for methods. I think in the comments below that someone likens this to tags in C++.

A nominal type system is not a more constrained version of a structural one. That statement would imply that any program written for the former would work using the latter as well, which is false. Name collisions would simply not resolve. For it to work, you need to add a namespace to all the colliding methods (a simple one would be a prefix like people do in C). A nominal system is a more constrained structural syst…

Hmmh. You seem to be restating what was said above.

A nominal type system still is superseded by a structural type system.

The difference is in how a type is defined. Or what kind of constraints are in entailment said otherwise.

An interface enforces constraints. The difference here is merely that the current implementations only have either one of these type of interfaces. So for the structural type system, all methods are in the global namespace, somehow.

That's all. Because our current languages are this way doesn't mean that the two concepts cannot be reconciliated or that one is just better than the other.

Re: Defining interfaces in C++ with ‘concepts’ (C++20)

#70

Earlier quoted context omitted.

I assume you've checked the version control history of every C++ compiler in existence?

It would be extremely hard to implement templates with dynamic dispatch while maintaining the correct semantics.

Right. For starters, from the very beginning C++ has supported function templates which take native types. So you don't even necessarily have any kind of pointer you could add a vtable to even if you wanted to. Then add to that the guarantee[1] about pod types being directly compatible with C which as you say I don't see how it owuld be possible to do.

[1] which has always been strong even before there was an actual ISO/ANSI standard

Post reply on HN