So true. Not an expert C++/D programmer here but enough to see this man is a genius. The more I see this kind of videos the more amazed I am. And a great lecturer.
You can sometimes tell the cleanliness of an idea by how easy it is to explain vs. the functionality introduces. D’s “static if”, with introspection, is extremely capable. I don’t use D, but I am a big proponent of HLL code generators (i.e. generating C++ or C, not assembly), and inspired by this talk I reimplemented an emulator I work on in D. It was originally written in C with heavy preprocessor use (not much in the way of tricks, it was a straightforward way to reduce repetition). The D code is about 1/3 size of C and does nothing fancy really - the resultant D is, other than code generation - at the C level. It’s just a big switch statement in a single function, plus helper functions. But they get generated imperatively and are way easier to debug and reason about then the multilevel macros needed by the C code. Even though I don’t use D and don’t really know it, the D code I (re)wrote is something I could easily understand a decade later. It reads in a straightforward manner and self documents perfectly. The C code is littered with documentation comments since it’s otherwise harder to comprehend. I’ve also tried a C++ implementation using all the tricks I know of, and no matter what I did, it was unbearable to look at, even if I wrote lots of supporting library code. C++ was in fact harder to read than C with macros, and I do use C++ daily. The one thing that perhaps could be done to D’s code generation is to generate token streams, not strings, and to have a way of writing token streams without excessive adornment. Say that you had `:< int name1 = val1; >:` in the generator code. That sequence of tokens would be substituted at compile time with values that the enclosing compile-time scope contains (presumably name1 and val1). This addresses single token substitution. For token sequences you’d do something like `auto seq1 = :< int foo; int bar; int baz; >:`. And put it in `:< struct sname { seq1; } >:`. This is a step above strings. Those token sequences are otherwise unconstrained - they are like “auto” token sequences. If you wanted to constrain a sequence, you could give it an AST type. Say, `ast::stmt_block blk1 = :< { printf("hello world "); } >:;` Then the compiler would enforce that, after substitutions, this is a valid statement block *within each context it itself is substituted in*. E.g. if you tried to stick one into a decl_list, the typecheck would fail before the compiler even had to run your generator code and have it fail at its runtime (compile time for the compiler is runtime for code generating code). To me, this smells better than strings, reads just as well as strings would, and can be as flexible as strings if you reused preprocessor ##. E.g. `std::vector decls; for (auto mbr : {"foo", …}) decls.push_back(:< int the_##mbr; >:;`);` This would leverage a lot of what every C++ user is familiar with: type safety (as lax or strict as you wish), templates, type_traits-like checks if you like those, etc. All that would be added is a singular new literal kind, and the rules that go with substituting into it.
Me last week when I watched this: "Who would need this unnecessarily complicated thing?" Me yesterday after coming across a problem this would easily solve: "Why isn't this in C++ already?"
@@llothar68 He left Facebook in August 2015 ( www.linkedin.com/in/erdani/ ). Facebook have D code, e.g. warp ( github.com/facebookarchive/warp ), flint ( github.com/facebookarchive/flint ).
@@llothar68 He doesn't work for Facebook anymore www.reddit.com/r/programming/comments/3ioy9b/andrei_alexandrescu_c_guru_leaves_facebook_to/ , and Facebook does use a little #Dlang forum.dlang.org/thread/l37h5s%242gd8%241%40digitalmars.com
He got called out by Nicolai Josuttis in the closing keynote: "It's your fault Andrei ... because you haven't been there" ua-cam.com/video/9-_TLTdLGtc/v-deo.htmlm36s
D seem to be C++'s "lab" language. I don't realistically believe that D will ever replace C++, but many of C++'s most prominent new features have first been implemented and experimented with in D.
This talk is about the "design by introspection" concept that could be easy to done in C++ if constexpr if did not introduce a new scope... He naturally uses "another language" to demonstrate that what he talks about is not some silly idea, but pretty much serious approach that is successful elsewhere...
He is so right about "if constexpr". This feature was intended to save us from all those hard-to-read SFINAE or tag dispatch dirty tricks, but it does so only in a very limited scope. I wish this feature was capable of, e.g., inheriting a class from some base classes depending on certain conditions, or conditionally defining some member fields or nested types in my classes. Hope they add it to the language someday.
For the question at 1:21:50 (and the one at 1:44:30), we really want an interface for `Hook` that implementers extend and then mark methods as `override` to get spell check. Better than requiring unit tests because it is written once, by the author of checked_int, and reused many times by implementers, giving them spell check for free. Yes, implementers should have unit tests, but we live in a world where that doesn't always happen, and the library should do as much as it can to make it difficult to use it incorrectly.
Concepts are boolean-like, and so can be used for feature querying. If you define a concept that requires an expression like "someObject.someMethod(args)" to be valid, you can use that in if constexpr conditionals.
Just a small note on "Hello world" being 22MB. Well it is not 22MB, it is 0.7MB after pre-processing. It is probably a bit bigger before preprocessing tho (it needs to scan entire files that are included multiple times, unless it does recognize that entire source code is actually wrapped in ifdef+define, which preprocessor usually will do).
I guess in functional(ish) languages you could represent optional capabilities as a `doFoo: Option(a -> b)`: if you know how to doFoo, have a `Some()` and otherwise `None`. You could (e.g.) put this as part of a user-level vtable or whatever. At runtime you can inspect and branch on the (absence of) capabilities of the thing you're working with. Translating back to C++, it's as if you could not only have a `virtual f() = nullptr` but also ask if `f == nullptr` for your concrete type (I guess). I guess the big reason we're not already doing this today is that we don't have many libraries which consume optional capabilities, and most application code knows the capabilities of everything since an application kinda' by definition is the context into which everything else fits rather than something which fits into an unknown context. Can we incrementally move that way?
It's interesting to note that company structure predicts fault density too, not only code complexity or code size. Source: Google Scholar, couple of papers at least.
Andrei is codesigner of D programming language, which has all the features he is talking about for very long time. compile time function evaluation, mixins, type introspection, traits. And it does proved super useful in D programs and libraries. It reduced the code and made it generic a lot. It also opened some previously impossible things to be automated. A lot of features (~30 different ones) in C++11 and later actually did come from D, despite it being rarely mentioned.
At 1:05 Alex talks about documentation for SafeInt for C++ ... which he ridicules for being disproportionately long. I looked for this but can't find it. I believe that he got it mixed up with the documentation for my boost::safe_numerics library where the documentation reaches some 80 pages when rendered in PDF. I see the humor in the idea that such a simple idea ends up requiring 80 pages of explanation. But I don't think the criticism is entirely fair. No one needs to read all of that in order to use the library in an effective way. Probably one only needs to spend 10 min on it to get started or to use to find a bug on mysteriously crashing code. But if you want to move your program to a level where it attempts to demonstrate program correctness of portable code - you'll have to know a lot more and spend more time at it - and the information is there when you need it. BTW I find Andre's talks very entertaining and informative as well. This one is no exception - even though I'm not sure I'm on board with what he's proposing here.
The problem also occurs when you need to debug an issue. Going through complicated libraries makes bugs harder to find. Also in many cases compile time is important.
Is there some taboo about talking about D programming language on C++ conferences? All the recent good features of C++ and most (if not all) of the Andrei ideas presented in his talks in last 12 years did come from D programming language. Showing actual code and large scale results of using these features is better than abstract talk and synthetic examples, and is important for engineering and designing language and libraries.
We'll need a jOOQ for strings of C++: a higher-level abstraction for types and functions that can be serialized to legal C++. I don't want to work on strings, but I do want to work on `function.addParameter(parameter)`. Then after that, we'll want an EDSL for building those expressions.
current behavior of `if constexpr` is not bug, but feature. Before it there was proposal for `static if` that do not have scope but it was nuke from orbit. Biggest problem with no-scoped `static if` was that it can be viral, if you use: ``` struct X { static if (x) { int foo; } else { int bar; } } ``` Reasoning was something like that: Then rest of code that handle this type in generic way need another `static if` to handle this difference. Of corse this is possible using templates too but it lot of harder and because of this you need be real masochist to use this solution. For `static if` on beginning will be easy and clean but after some time complexity and need for boilerplate will grown (multiple new `static if` in multiple of places). Hard to say how much this reasoning is correct. But I think there is some truth in that.
Current behaviour of `if constexpr` basically makes it useless and redundant with compilers are already doing during optimization during normal `if` optimization.
@@movax20h No, no, no. In one branch of `if constexpr` can have INVALID code, try do this with normal `if`, you can change return type of function in arbitrarily way using it. Without it you would need write LOT of boilerplate to have same results.
True, but it makes you more aware and makes it look same inside function and outside functions. And same compiler machinery can be used for both essentially.
@@FooBar89 No, D doesn't have concepts. D has template constraints. The constraints participate in template overloading resolution, but they do not form a part of a type or signature, they can't be passed around as types or moved between modules / packages.
I code in c for fun, I use my own string list vector map types and functions. C++ is a mess and puts me off using it as its not fun and python is much better for high level programming, hopefully D becomes c++ without the ever growing bag of bricks it carries.
At 30:00 Andrei proves again that he is a genius. The amount of effort he has put in talk is very evident and is just amazing!!
So true. Not an expert C++/D programmer here but enough to see this man is a genius. The more I see this kind of videos the more amazed I am. And a great lecturer.
You can sometimes tell the cleanliness of an idea by how easy it is to explain vs. the functionality introduces. D’s “static if”, with introspection, is extremely capable. I don’t use D, but I am a big proponent of HLL code generators (i.e. generating C++ or C, not assembly), and inspired by this talk I reimplemented an emulator I work on in D. It was originally written in C with heavy preprocessor use (not much in the way of tricks, it was a straightforward way to reduce repetition). The D code is about 1/3 size of C and does nothing fancy really - the resultant D is, other than code generation - at the C level. It’s just a big switch statement in a single function, plus helper functions. But they get generated imperatively and are way easier to debug and reason about then the multilevel macros needed by the C code. Even though I don’t use D and don’t really know it, the D code I (re)wrote is something I could easily understand a decade later. It reads in a straightforward manner and self documents perfectly. The C code is littered with documentation comments since it’s otherwise harder to comprehend. I’ve also tried a C++ implementation using all the tricks I know of, and no matter what I did, it was unbearable to look at, even if I wrote lots of supporting library code. C++ was in fact harder to read than C with macros, and I do use C++ daily.
The one thing that perhaps could be done to D’s code generation is to generate token streams, not strings, and to have a way of writing token streams without excessive adornment. Say that you had `:< int name1 = val1; >:` in the generator code. That sequence of tokens would be substituted at compile time with values that the enclosing compile-time scope contains (presumably name1 and val1). This addresses single token substitution.
For token sequences you’d do something like `auto seq1 = :< int foo; int bar; int baz; >:`. And put it in `:< struct sname { seq1; } >:`. This is a step above strings. Those token sequences are otherwise unconstrained - they are like “auto” token sequences.
If you wanted to constrain a sequence, you could give it an AST type. Say, `ast::stmt_block blk1 = :< { printf("hello world
"); } >:;` Then the compiler would enforce that, after substitutions, this is a valid statement block *within each context it itself is substituted in*. E.g. if you tried to stick one into a decl_list, the typecheck would fail before the compiler even had to run your generator code and have it fail at its runtime (compile time for the compiler is runtime for code generating code).
To me, this smells better than strings, reads just as well as strings would, and can be as flexible as strings if you reused preprocessor ##. E.g.
`std::vector decls;
for (auto mbr : {"foo", …})
decls.push_back(:< int the_##mbr; >:;`);`
This would leverage a lot of what every C++ user is familiar with: type safety (as lax or strict as you wish), templates, type_traits-like checks if you like those, etc. All that would be added is a singular new literal kind, and the rules that go with substituting into it.
@@absurdengineering The AST injection is where C++ is heading, but it will take time.
Me last week when I watched this: "Who would need this unnecessarily complicated thing?"
Me yesterday after coming across a problem this would easily solve: "Why isn't this in C++ already?"
The funniest man in computer science.
i love this guy,i watch all his videos, good speak!
Interesting talk. For those that don't know, "another language" is D Lang, Andrei switched from C++ to D Lang a while back
AFAIK only for fun, he still works at Facebook and they use only C++ and not a single line of D
@@llothar68 He left Facebook in August 2015 ( www.linkedin.com/in/erdani/ ). Facebook have D code, e.g. warp ( github.com/facebookarchive/warp ), flint ( github.com/facebookarchive/flint ).
@@llothar68 He doesn't work for Facebook anymore www.reddit.com/r/programming/comments/3ioy9b/andrei_alexandrescu_c_guru_leaves_facebook_to/ , and Facebook does use a little #Dlang forum.dlang.org/thread/l37h5s%242gd8%241%40digitalmars.com
He got called out by Nicolai Josuttis in the closing keynote: "It's your fault Andrei ... because you haven't been there" ua-cam.com/video/9-_TLTdLGtc/v-deo.htmlm36s
D seem to be C++'s "lab" language. I don't realistically believe that D will ever replace C++, but many of C++'s most prominent new features have first been implemented and experimented with in D.
This talk is about the "design by introspection" concept that could be easy to done in C++ if constexpr if did not introduce a new scope... He naturally uses "another language" to demonstrate that what he talks about is not some silly idea, but pretty much serious approach that is successful elsewhere...
He is so right about "if constexpr". This feature was intended to save us from all those hard-to-read SFINAE or tag dispatch dirty tricks, but it does so only in a very limited scope. I wish this feature was capable of, e.g., inheriting a class from some base classes depending on certain conditions, or conditionally defining some member fields or nested types in my classes. Hope they add it to the language someday.
For the question at 1:21:50 (and the one at 1:44:30), we really want an interface for `Hook` that implementers extend and then mark methods as `override` to get spell check. Better than requiring unit tests because it is written once, by the author of checked_int, and reused many times by implementers, giving them spell check for free. Yes, implementers should have unit tests, but we live in a world where that doesn't always happen, and the library should do as much as it can to make it difficult to use it incorrectly.
Thanks for uploading!! Very interesting, thanks Andrei. Let's upgrade "constexpr if" :)
Interesting talk
Andrey is so right here - well at least we have "__if_exists" keyword in MSVC to emulate D-lang's "static if"
Concepts are boolean-like, and so can be used for feature querying. If you define a concept that requires an expression like "someObject.someMethod(args)" to be valid, you can use that in if constexpr conditionals.
Just a small note on "Hello world" being 22MB. Well it is not 22MB, it is 0.7MB after pre-processing. It is probably a bit bigger before preprocessing tho (it needs to scan entire files that are included multiple times, unless it does recognize that entire source code is actually wrapped in ifdef+define, which preprocessor usually will do).
I guess in functional(ish) languages you could represent optional capabilities as a `doFoo: Option(a -> b)`: if you know how to doFoo, have a `Some()` and otherwise `None`. You could (e.g.) put this as part of a user-level vtable or whatever. At runtime you can inspect and branch on the (absence of) capabilities of the thing you're working with.
Translating back to C++, it's as if you could not only have a `virtual f() = nullptr` but also ask if `f == nullptr` for your concrete type (I guess).
I guess the big reason we're not already doing this today is that we don't have many libraries which consume optional capabilities, and most application code knows the capabilities of everything since an application kinda' by definition is the context into which everything else fits rather than something which fits into an unknown context.
Can we incrementally move that way?
It's interesting to note that company structure predicts fault density too, not only code complexity or code size. Source: Google Scholar, couple of papers at least.
Read the Fine Manual. I totally agree. Yes, but we need the manual to be written by someone who knows and cares to produce usable code. :)
59:27 Even better: abs(INT_MIN) is negative.
C++ programmers discover of 1960-style meta-programming in 2018 the hard way.
Andrei is codesigner of D programming language, which has all the features he is talking about for very long time. compile time function evaluation, mixins, type introspection, traits. And it does proved super useful in D programs and libraries. It reduced the code and made it generic a lot. It also opened some previously impossible things to be automated. A lot of features (~30 different ones) in C++11 and later actually did come from D, despite it being rarely mentioned.
At 1:05 Alex talks about documentation for SafeInt for C++ ... which he ridicules for being disproportionately long. I looked for this but can't find it. I believe that he got it mixed up with the documentation for my boost::safe_numerics library where the documentation reaches some 80 pages when rendered in PDF. I see the humor in the idea that such a simple idea ends up requiring 80 pages of explanation. But I don't think the criticism is entirely fair. No one needs to read all of that in order to use the library in an effective way. Probably one only needs to spend 10 min on it to get started or to use to find a bug on mysteriously crashing code. But if you want to move your program to a level where it attempts to demonstrate program correctness of portable code - you'll have to know a lot more and spend more time at it - and the information is there when you need it.
BTW I find Andre's talks very entertaining and informative as well. This one is no exception - even though I'm not sure I'm on board with what he's proposing here.
The problem also occurs when you need to debug an issue. Going through complicated libraries makes bugs harder to find.
Also in many cases compile time is important.
Robert Ramey Better too mich docs than too little
Is there some taboo about talking about D programming language on C++ conferences? All the recent good features of C++ and most (if not all) of the Andrei ideas presented in his talks in last 12 years did come from D programming language. Showing actual code and large scale results of using these features is better than abstract talk and synthetic examples, and is important for engineering and designing language and libraries.
No, I think Andrei was just playing with the audience here. Its too obvious.
We'll need a jOOQ for strings of C++: a higher-level abstraction for types and functions that can be serialized to legal C++. I don't want to work on strings, but I do want to work on `function.addParameter(parameter)`. Then after that, we'll want an EDSL for building those expressions.
With features presented in this talks it can be easily implemented as a library.
"another language" ftw!
i like it how he expected the ...contraption to work when it was supposed to xD
An expert constantly expressing about if constexpr.
current behavior of `if constexpr` is not bug, but feature. Before it there was proposal for `static if` that do not have scope but it was nuke from orbit.
Biggest problem with no-scoped `static if` was that it can be viral, if you use:
```
struct X
{
static if (x)
{
int foo;
}
else
{
int bar;
}
}
```
Reasoning was something like that:
Then rest of code that handle this type in generic way need another `static if` to handle this difference. Of corse this is possible using templates too but it lot of harder and because of this you need be real masochist to use this solution. For `static if` on beginning will be easy and clean but after some time complexity and need for boilerplate will grown (multiple new `static if` in multiple of places).
Hard to say how much this reasoning is correct. But I think there is some truth in that.
Current behaviour of `if constexpr` basically makes it useless and redundant with compilers are already doing during optimization during normal `if` optimization.
@@movax20h No, no, no. In one branch of `if constexpr` can have INVALID code, try do this with normal `if`, you can change return type of function in arbitrarily way using it. Without it you would need write LOT of boilerplate to have same results.
In "static if" the keyword "static" is unnecessary when used in class/struct body scope.
True, but it makes you more aware and makes it look same inside function and outside functions. And same compiler machinery can be used for both essentially.
In D other language
I missed a critical point to understand what he's talking about, what is "DbI"?
Design by Introspection
Design By Introspection
(If we are not in Perl context where it used be DataBase Interface :) )
watch from 30th min. The type/class implementation gets assembled/combined during the compilation by introspecting the input/argument type.
goto talk;
Is there a generalisation of meta classes that would allow reflection?
Meta classes and reflection are two separate features.
starts somewhere @ 7:00
Nice ABBA joke :)
I understood that reference. Smart!
concepts are waste of time 1:45:12
D has them
@@FooBar89 No, D doesn't have concepts. D has template constraints. The constraints participate in template overloading resolution, but they do not form a part of a type or signature, they can't be passed around as types or moved between modules / packages.
The next big thing: Going back to C.
I code in c for fun, I use my own string list vector map types and functions.
C++ is a mess and puts me off using it as its not fun and python is much better for high level programming, hopefully D becomes c++ without the ever growing bag of bricks it carries.