Esoteric C++ Contest 2018
zygoloid.github.io
zygoloid.github.io
http://b.atch.se/posts/non-constant-constant-expressions/
"Implementing f() to make the following snippet compile without the static_assert being fired looks impossible, doesn't it?
// <insert solution here>
int main () {
constexpr int a = f();
constexpr int b = f();
static_assert (a != b, "fail");
}
We all "know" that an expression that is usable in a constant-expression can neither depend on, nor change, the global state. This lack of dependency must inherently mean that it will yield the same value upon each invocation having the same set of arguments... right?Up until about a week ago I "knew" this to be true, and I honestly thought the above was not possible to implement without triggering undefined-behavior (ie. writing a program that the ISO C++ Standard would consider ill-formed).
As it turns out, I was very wrong."
It's such a important, transformative and widely used language, but due to the age and the "let's put everything in without ever removing anything because backwards compatability!" mentality has created a monster.
[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p017...
Anybody can create a some shiny new language or maintain a beautiful unused language.
I made another comment here on this item, that it feels like a lot of the recent developments in programming languages are more along the lines of showing off how much complexity you can add, rather than solving the real problem itself. It's a "do less with more" mindset, the complete opposite of what I believe in.
The author promised an iPad for the winner and got 40 entries.
What fraction of the money set aside for a competition should be spent on publicity and how much on the prize? Talking about programming/related competitions here.
I think that Bjarne might mean "modern C++", but I'm more a fan of "C with classes", and I think the latter is more appropriate for many domains. I would say those are the two main dialects (with modern C++ being split being library writers using templates and library consumers.)
The old Google C++ style guide is good, but it seems to be morphing more into modern C++ lately. It's basically C with:
- The ability to add methods to structs
- Basic single inheritance.
- Collection and string classes
- Scope based resource management.
https://stackoverflow.com/questions/3073642/official-c-langu...
No exceptions, no IO streams (except in one place), no implicit constructors, no operator overloading, multiple inheritance, etc.
So I woudn't say there are 5 or 6 languages, but it definitely feels like that sometimes. I think the lack of a single string type, single error handling mechanism, and single deallocation mechanism are the things that make it feel like more than one language in a single codebase.
Not having exceptions is a big similarity. Go slices and StringPiece are essentially the same idiom. There's a lot of vector<> and map<> which leads to builtin arrays and maps, rather than having arbitrary user-defined data structures (i.e. no operator overloading). gofmt was definitely inspired by Google's code review process.
Template libraries work well, until they don't, at which point you get many pages of confusing error messages containing absurdly long identifier names; and the cause is often something as simple as one missing, wrong, or extra character. Sometimes it even crashes the compiler...
Behold, I present you this fucking monstrosity (Directly from the RAJA matrix multiplication tutorial):
using EXEC_POL9 =
RAJA::KernelPolicy<
RAJA::statement::CudaKernel<
RAJA::statement::Tile<1, RAJA::statement::tile_fixed<CUDA_BLOCK_SIZE>, RAJA::cuda_block_y_loop,
RAJA::statement::Tile<0, RAJA::statement::tile_fixed<CUDA_BLOCK_SIZE>, RAJA::cuda_block_x_loop,
RAJA::statement::For<1, RAJA::cuda_thread_y_loop, // row
RAJA::statement::For<0, RAJA::cuda_thread_x_loop, // col
RAJA::statement::Lambda<0>, // dot = 0.0
RAJA::statement::For<2, RAJA::seq_exec,
RAJA::statement::Lambda<1> // dot += ...
>,
RAJA::statement::Lambda<2> // set C = ...
>
>
>
>
>
>;
And that's just for matrix multiplication. I cannot imagine how fucking terrifying it will to write something more complicated than that. If I were to write (and debug) this mindfucking mess of templated code, I would rather escape this trainwreck and go back to writing CUDA/OpenCL code...It's just a Lisp-like language with a slightly different syntax for S-expressions. Ugly, like all Lisps, but nothing 'monstrous'.
C++ templates are far from user-friendly, but they're literally (literally) just Lisp S-expressions with a Lisp syntax and semantics.
I understand complaining about templates like the ranges example also posted in this thread, but I am curious to hear what you think is the alternative for this specific example.
If you want a template challenge, try (without looking it up) writing your own iostream class. iostream is one of those things that's present in even beginner examples but when you look at how it works a whole load of complexity unravels.
However, properly designed templates with enough attention put into exposing functionality beat non-templated approaches right off the bat.
Example: http://eigen.tuxfamily.org/dox/TopicInsideEigenExample.html
My personal rule is to never nest more than two templates. You can have a template inside a template, but anything deeper than that should be refactored or at least split up into typedefs for readability.
1. You have to interface with older libraries that overuse terrible behavior.
2. The hallmark of a junior developer is an overuse of features. Using a subset takes discipline.
3. Some things are just permanently broken or so hidden you don't even realize you are using a "feature".
That's why I'm just going to stick with Rust. I have no interest in the "let's put a wig and lipstick on the C++ pig" train.
P.S. I'm an atheist.
With a cocktail of alphanumeric overloadable operators, lambdas, variadic templates and small identifiers, all badly spaced, It would not be difficult to achieve super unreadable code with it.
They just need to figure out a way to add implicit arguments like $@, $?, @_ and we'll get a more esoteric C++. Note that $_ is a valid identifier in C++.