Live data from Hacker News

C++ : if constexpr isn't broken

brevzin.github.io

41–50 of 83 posts

Re: C++ : if constexpr isn't broken

#41
post #19

Earlier quoted context omitted.

Isn't every developer in a non-trivial software project a library developer? As soon as you have a common piece of functionality you want to reuse - that's a library.

I think that's dependent on language culture. Because the C++ community doesn't take language simplicity or comprehensibility seriously, there are lots of C++ developers who can't use or reason about surprisingly large parts of the language. So the community has rallied around the notion that "library" developers need to understand everything and that most developers will just glue together bits that the library devs…

>... the C++ community doesn't take language simplicity or comprehensibility seriously...

I think this is an unreasonable assertion and not borne our by a read of the committee discussions.

Re: C++ : if constexpr isn't broken

#42

Earlier quoted context omitted.

I disagree - I work in high-performance computing and I think in our case the complexity of C++ is actually mirroring that of the problem domain. Nothing else gives us the level of abstraction that C++ does, while still offering convenient ways to specify low-level performance semantics . I think for a while Fortran was pulling ahead for large-scale numerical computing, but the mess of different options for paralleli…

Looking at some C++ extension proposals, many are definitely a case of "devs gotta dev." Fortunately most of these don't have a chance in hell of making it in.

Yeah Stroustrup put his foot down this year on whacky proposals.

Re: C++ : if constexpr isn't broken

#43
post #20

Oh my. If only C++ would have used proper macros from the start...

I discussed this once with Stroustrup. He mourned that the word "macro" had been "polluted" (his word, though I completely agreed) by the preprocessor and said "templates was the best we could do within the constraints of C".

This was in the mid 90s and things are a lot better these days but still, I had better macro support writing Lisp in the 1970s.

Re: C++ : if constexpr isn't broken

#44

Earlier quoted context omitted.

Gradual typing is mostly a good thing for metaprogramming I think. Even if it was just a compromise for backwards compatibility I'd still take it over C#'s rather limited generics.

I think C# is a good language, but I also am not sure that it's a poster child for this particular language feature. (I mean this literally; I don’t have enough experience to really know how it compares to the usual suspects in this area.)

A bit of a test case for me, coming from the domain of games / 3D graphics programming, as to whether a language has a 'sufficiently powerful' generics feature set is whether it is possible to implement a generic 'short vector' type as used in any type of graphics programming. I think 'good' generics / metaprogramming support should let you meet most of these goals in a generic 'short vector' type:

- Support 'n' dimensional vectors (2, 3 and 4 are the only ones commonly used in 3D graphics and games).

- Support a choice of underlying element type (at least float, double and int but it's handy to be able to support custom types like a fixed point or rational type too).

- Support operator overloading for natural expression of things like adding two vectors.

- Be very close or identical in performance to the equivalent hand written variant for every combination of dimension / element type (excluding optimizations for particular SIMD element widths etc.)

- Not be significantly worse for debugging than the equivalent hand written code (this is as much a tooling issue as a language issue).

It's possible to meet all of these requirements in modern C++ without using any particularly exotic metaprogramming functionality. It's impossible in C#. I don't know of any other language that meets these requirements as well as C++ although I'm not really familiar with the facilities offered by e.g. Rust.

Re: C++ : if constexpr isn't broken

#45

Earlier quoted context omitted.

I think C# is a good language, but I also am not sure that it's a poster child for this particular language feature. (I mean this literally; I don’t have enough experience to really know how it compares to the usual suspects in this area.)

A bit of a test case for me, coming from the domain of games / 3D graphics programming, as to whether a language has a 'sufficiently powerful' generics feature set is whether it is possible to implement a generic 'short vector' type as used in any type of graphics programming. I think 'good' generics / metaprogramming support should let you meet most of these goals in a generic 'short vector' type: - Support 'n' dime…

Makes sense, yeah. I think that's reasonable. You can do this in Rust (https://www.nalgebra.org/vectors_and_matrices/ as an example), but one caveat: the n-dimensionality aspect isn't as nice (see the "Type-level integers" section of that doc) until "const generics" lands; that's completely orthogonal from the "generics" vs "templates" discussion, except that it's easier to implement (from the compiler's perspective) via templates.

Re: C++ : if constexpr isn't broken

#46

Earlier quoted context omitted.

Gradual typing is mostly a good thing for metaprogramming I think. Even if it was just a compromise for backwards compatibility I'd still take it over C#'s rather limited generics.

I think C# is a good language, but I also am not sure that it's a poster child for this particular language feature. (I mean this literally; I don’t have enough experience to really know how it compares to the usual suspects in this area.)

.NET's and thus C#'s generics are very well designed but they rely on the design of .NET as a whole being a managed language, so it can get away with a slightly more sophisticated runtime representation.

An example of this is that generics are "reified". This is to say that you can treat each instantiation as a unique type at runtime. This is not the same as monomorphisation though, as there are rules used to promote code sharing and avoid overly aggressive specialization. For example, boxed type parameters will generally share all code paths until the JIT decides to specialize a specific call site. Value types tend to gain a lot more from immediate inlining since autoboxing (another peculiar feature of .NET) can be avoided in more cases, so these are usually specialized upon reification (much closer to what you'd see in a template, though we're still limited to type parameters here).

In Java, the lack of user defined unboxed value types makes these distinctions less attractive and thus you see they opt for type erasure and reliance on clever JIT heuristics. They do miss out on things like type-specific static class members but I've only found a few uses for this in .NET (and even then it tended to surprise folks, main case was for a type safe structured logging system with efficient runtime control of trace points).

Having said all of that, the code bloat of C++'s templates causes issues with compile time, error message comprehension, and to some degree, cache efficiency but in return the programmer gets almost complete control over all of the trade-offs mentioned above. One can have templates duplicate code, or use abstract classes as interfaces for virtual dispatch, or even a mix where the template derives shared instances for certain types. This "we can have it all" mentality is a burden that may eventually be addressed by making the common cases easier to comprehend, debug, and compile.

I'm not necessarily going to wait for C++ to change but it's interesting to watch it make its way towards new goals while other languages mature enough to replace it in certain cases (Rust obviously but there are others like Zig which I think are worth watching).

Re: C++ : if constexpr isn't broken

#47
post #46

Earlier quoted context omitted.

I think C# is a good language, but I also am not sure that it's a poster child for this particular language feature. (I mean this literally; I don’t have enough experience to really know how it compares to the usual suspects in this area.)

.NET's and thus C#'s generics are very well designed but they rely on the design of .NET as a whole being a managed language, so it can get away with a slightly more sophisticated runtime representation. An example of this is that generics are "reified". This is to say that you can treat each instantiation as a unique type at runtime. This is not the same as monomorphisation though, as there are rules used to promote…

Thanks, this matches my understanding, but I was not confident that it was correct.

Re: C++ : if constexpr isn't broken

#48
post #41

Earlier quoted context omitted.

I think that's dependent on language culture. Because the C++ community doesn't take language simplicity or comprehensibility seriously, there are lots of C++ developers who can't use or reason about surprisingly large parts of the language. So the community has rallied around the notion that "library" developers need to understand everything and that most developers will just glue together bits that the library devs…

>... the C++ community doesn't take language simplicity or comprehensibility seriously... I think this is an unreasonable assertion and not borne our by a read of the committee discussions.

To clarify: of course they like simplicity when it costs nothing. But they consistently value other goods over simplicity.

For example: maintaining backwards compatibility. The community believes that it is more important that 20 year old C++ code run unmodified than that the language should be simplified. There's lots of stuff you could do to simplify the language but options dry up in a world where 20 year old code must be able to run unmodified.

So sure, the committee talks a lot about simplicity, but it isn't willing to sacrifice much.

Don't get me wrong: I'm glad that finally, in 2020, C++ will be almost but not quite as good as Common Lisp was at metaprogramming back in 1982. But it remains the case that eval-when and defmacro are both more powerful and dramatically simpler than anything the C++ committee has ever considered.

Re: C++ : if constexpr isn't broken

#49
post #41

Earlier quoted context omitted.

>... the C++ community doesn't take language simplicity or comprehensibility seriously... I think this is an unreasonable assertion and not borne our by a read of the committee discussions.

To clarify: of course they like simplicity when it costs nothing. But they consistently value other goods over simplicity. For example: maintaining backwards compatibility. The community believes that it is more important that 20 year old C++ code run unmodified than that the language should be simplified. There's lots of stuff you could do to simplify the language but options dry up in a world where 20 year old code…

Two other goals for C++ are 'zero-cost abstractions' and 'leaving no room for a lower level language'. It does better on both of these goals than Common Lisp and they are important reasons for its popularity (along with backwards compatibility and easy interop with C APIs).

Re: C++ : if constexpr isn't broken

#50
I used to be a C++ guy from the early 90s 'till about 2010. Every few months, I think "I should really learn the new C++ hotness", and then I read something like this. It's like a bunch of priests arguing about how best to fit a bunch of ugly angels on a pointless pin. It just feels so pointless.

If you must use C++, just use another language to generate the C++. All this template mumbo jumbo. Who says your meta-programming language has to be the same as your target language?

I used to spend some time looking for the perfect vector (as in linear-algebra) library. Templatized for vector dimension, data-type, blah blah blah. Dude, just use Python to generate it. Duplication doesn't violate DRY if the duplication is generated from a single higher-level source.

Doing meta-programming in C++ is a really limited way of thinking.

Post reply on HN