digitalmars.D - Herb Sutter's CppCon talk "Extending and Simplifying C++: Thoughts on
- Andrei Alexandrescu (4/4) Oct 31 2021 I think it's relevant to our recent discussion on versioning, and also
- deadalnix (6/11) Oct 31 2021 Agreed on the destruction. But very good content by herb as usual
- Andrei Alexandrescu (2/15) Oct 31 2021 "Simplify C++ by adding to it" is the top-level message. It's a gambit.
- deadalnix (10/28) Nov 01 2021 Ok I can see that. On that front, I'd like to point at this
- Walter Bright (17/20) Nov 01 2021 Can you be more specific?
- Andrei Alexandrescu (28/45) Nov 01 2021 1a. Hash tables have a number of language magic hacks (particularly
- Paul Backus (10/16) Nov 01 2021 It's true, as far as it goes. `return` and `scope` are consistent
- Walter Bright (4/20) Nov 01 2021 That's the "return-scope-ref" ambiguity problem. I've put through a seri...
- H. S. Teoh (12/19) Nov 01 2021 Sometimes I feel like Walter has a private copy of dmd that behaves
- Walter Bright (5/45) Nov 01 2021 Maybe qualified ranges should be impossible to implement.
- Patrick Schluter (5/16) Nov 02 2021 I hear the sound of bagpipes in the background (see no true
- Walter Bright (3/5) Nov 01 2021 Perhaps that should be applied generally. If someone wants to do a DIP f...
- Timon Gehr (14/21) Nov 02 2021 I think DIP 1000 etc. is actually a prime example of non-orthogonal
- deadalnix (67/73) Nov 01 2021 Yes.
- Andrei Alexandrescu (3/91) Nov 01 2021 I quote this post in its entirety because I so much agree with it. Each
- Walter Bright (22/60) Nov 01 2021 Thank you. This is a great list. I would appreciate it if you could make...
- deadalnix (59/95) Nov 03 2021 As general answer, you request for bug report for these issues.
- Elronnd (8/13) Nov 01 2021 I agree with almost all of these, but this one especially.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (3/6) Nov 02 2021 Why? Shouldn't a tuple just be syntactical suger for a regular
- Araq (5/10) Nov 01 2021 What? Pattern matching doesn't scale/nest well because you think
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (9/12) Nov 01 2021 It scales, but how do you know if you remembered to test all
- Imperatorn (4/13) Nov 01 2021 Note to those not familiar with it, this is frequently called
- Meta (19/31) Nov 01 2021 Andrei is perfectly correct on this IMO, and it's telling that
- Bruce Carneal (10/15) Nov 01 2021 Many interesting discussion points in the video. It seems Sean
- =?UTF-8?Q?Ali_=c3=87ehreli?= (22/29) Nov 01 2021 I haven't watched the video yet.
- Arjan (5/10) Nov 01 2021 Why is it that always when I see Herb Sutter talk about C++, that
- Andrei Alexandrescu (2/13) Nov 01 2021 Maybe because he's just the best technical speaker ever.
- Walter Bright (2/3) Nov 01 2021 I agree with that. Herb is just amazing.
- H. S. Teoh (13/16) Nov 01 2021 It's like an abusive relationship that you can never break free of. ;-)
- bachmeier (3/15) Nov 01 2021 The same goes for Bjarne S, but then I open a C++ file in my text
- H. S. Teoh (5/20) Nov 01 2021 LOL!!!
- zjh (5/5) Nov 01 2021 Don't underestimate `C++`. Maybe `C++`'s implementation is not
I think it's relevant to our recent discussion on versioning, and also for its considerations on language design. https://youtube.com/watch?v=raB_289NxBk P.S. Destruction comes at https://youtu.be/raB_289NxBk?t=4727 :o)
Oct 31 2021
On Monday, 1 November 2021 at 00:20:33 UTC, Andrei Alexandrescu wrote:I think it's relevant to our recent discussion on versioning, and also for its considerations on language design. https://youtube.com/watch?v=raB_289NxBk P.S. Destruction comes at https://youtu.be/raB_289NxBk?t=4727 :o)Agreed on the destruction. But very good content by herb as usual nevertheless. I'm not sure in what way does that meshes with versioning. Could you unpack that for me?
Oct 31 2021
On 10/31/21 8:46 PM, deadalnix wrote:On Monday, 1 November 2021 at 00:20:33 UTC, Andrei Alexandrescu wrote:"Simplify C++ by adding to it" is the top-level message. It's a gambit.I think it's relevant to our recent discussion on versioning, and also for its considerations on language design. https://youtube.com/watch?v=raB_289NxBk P.S. Destruction comes at https://youtu.be/raB_289NxBk?t=4727 :o)Agreed on the destruction. But very good content by herb as usual nevertheless. I'm not sure in what way does that meshes with versioning. Could you unpack that for me?
Oct 31 2021
On Monday, 1 November 2021 at 01:47:32 UTC, Andrei Alexandrescu wrote:On 10/31/21 8:46 PM, deadalnix wrote:Ok I can see that. On that front, I'd like to point at this specific timestamp: https://youtu.be/raB_289NxBk?t=2775 have been done in D. D's feature just don't compose well because they aren't orthogonal with each other (and many are inconsistent). C++ used to be very much that way too, and but it is clear that this is something that has changed with C++11 onward.On Monday, 1 November 2021 at 00:20:33 UTC, Andrei Alexandrescu wrote:"Simplify C++ by adding to it" is the top-level message. It's a gambit.I think it's relevant to our recent discussion on versioning, and also for its considerations on language design. https://youtube.com/watch?v=raB_289NxBk P.S. Destruction comes at https://youtu.be/raB_289NxBk?t=4727 :o)Agreed on the destruction. But very good content by herb as usual nevertheless. I'm not sure in what way does that meshes with versioning. Could you unpack that for me?
Nov 01 2021
On 11/1/2021 9:18 AM, deadalnix wrote:in D. D's feature just don't compose well because they aren't orthogonal with each other (and many are inconsistent).Can you be more specific? Some examples of consistency in D: 1. basic types, structs, and arrays are interchangeable. But I couldn't add tuples to the list, because the function call ABI for structs is "special". Urgh. 2. The nature of how const, immmutable, and shared are applied to types is completely consistent, despite many requests to change that. 4. The way scope & return & ref apply to types is completely consistent. This enables me to advise that when people have problems understanding it, to rewrite their example code in terms of raw pointers, as it will behave the same. A counter-example: The original symbol lookup mechanism was completely consistent. It behaved exactly the same way for all scoped declarations. However, I was the only one who felt that way. I was never even able to get anyone to even *concede* that it was consistent, but they didn't like it that way. What we have today is special case two-pass lookup, with special handling for imports.
Nov 01 2021
On 2021-11-01 17:41, Walter Bright wrote:On 11/1/2021 9:18 AM, deadalnix wrote:There are easily found counterpoints even to your examples.been done in D. D's feature just don't compose well because they aren't orthogonal with each other (and many are inconsistent).Can you be more specific? Some examples of consistency in D:1. basic types, structs, and arrays are interchangeable. But I couldn't add tuples to the list, because the function call ABI for structs is "special". Urgh.1a. Hash tables have a number of language magic hacks (particularly concerning keys that have statically-sized array types) that are thoroughly inconsistent with the language rules.2. The nature of how const, immmutable, and shared are applied to types is completely consistent, despite many requests to change that.2a. Hash tables have any number of qualifier-related hacks that makes them impossible to implement as a library. 2b. Calls to built-in arrays remove the top-level qualifier in a way that is not accessible to user code. This makes qualified ranges impossible to implement: void fun(T)(T data) { import std; writeln(T.stringof); } void main() { immutable int a = 42; immutable int[] b = [ 69 ]; fun(a); // fine, prints immutable(int) fun(b); // prints immutable(int)[], not immutable(int[]) } 2c. There are a number of hacks in the compiler that give special treatment to shared numerics. Such is inaccessible to user code. Worse, they don't generate correct code. void main() { shared int i = 42; i = i + 2; // whatta? }4. The way scope & return & ref apply to types is completely consistent. This enables me to advise that when people have problems understanding it, to rewrite their example code in terms of raw pointers, as it will behave the same.I very much wish this is true and useful.
Nov 01 2021
On Monday, 1 November 2021 at 22:02:26 UTC, Andrei Alexandrescu wrote:On 2021-11-01 17:41, Walter Bright wrote:It's true, as far as it goes. `return` and `scope` are consistent in the way they apply to *types*. However, `ref` is not part of the type system--and when you add `ref` into the mix, that's when you start to see the special cases cropping up (see e.g. [Dennis's thread on the inconsistency of `return scope`][1]). [1]: https://forum.dlang.org/thread/nbbtdbgifaurxoknyeuu forum.dlang.org4. The way scope & return & ref apply to types is completely consistent. This enables me to advise that when people have problems understanding it, to rewrite their example code in terms of raw pointers, as it will behave the same.I very much wish this is true and useful.
Nov 01 2021
On 11/1/2021 3:07 PM, Paul Backus wrote:On Monday, 1 November 2021 at 22:02:26 UTC, Andrei Alexandrescu wrote:That's the "return-scope-ref" ambiguity problem. I've put through a series of PRs to correct that. It's almost done. The underlying type system is correct, it's a syntactical issue.On 2021-11-01 17:41, Walter Bright wrote:It's true, as far as it goes. `return` and `scope` are consistent in the way they apply to *types*. However, `ref` is not part of the type system--and when you add `ref` into the mix, that's when you start to see the special cases cropping up (see e.g. [Dennis's thread on the inconsistency of `return scope`][1]). [1]: https://forum.dlang.org/thread/nbbtdbgifaurxoknyeuu forum.dlang.org4. The way scope & return & ref apply to types is completely consistent. This enables me to advise that when people have problems understanding it, to rewrite their example code in terms of raw pointers, as it will behave the same.I very much wish this is true and useful.
Nov 01 2021
On Mon, Nov 01, 2021 at 06:02:26PM -0400, Andrei Alexandrescu via Digitalmars-d wrote:On 2021-11-01 17:41, Walter Bright wrote:[...]Sometimes I feel like Walter has a private copy of dmd that behaves differently from the one the rest of us use. `ref`, for example, due to its special treatment as a storage qualifier instead of a type constructor, is asymmetric w.r.t. other type ctors and therefore a source of endless special cases in generic code. It's just a royal pain to work with. And don't get us started on `auto ref`... T -- The best compiler is between your ears. -- Michael Abrash4. The way scope & return & ref apply to types is completely consistent. This enables me to advise that when people have problems understanding it, to rewrite their example code in terms of raw pointers, as it will behave the same.I very much wish this is true and useful.
Nov 01 2021
On 11/1/2021 3:02 PM, Andrei Alexandrescu wrote:True, but hash tables are not basic types, structs, arrays or tuples!1. basic types, structs, and arrays are interchangeable. But I couldn't add tuples to the list, because the function call ABI for structs is "special". Urgh.1a. Hash tables have a number of language magic hacks (particularly concerning keys that have statically-sized array types) that are thoroughly inconsistent with the language rules.Maybe qualified ranges should be impossible to implement.2. The nature of how const, immmutable, and shared are applied to types is completely consistent, despite many requests to change that.2a. Hash tables have any number of qualifier-related hacks that makes them impossible to implement as a library. 2b. Calls to built-in arrays remove the top-level qualifier in a way that is not accessible to user code. This makes qualified ranges impossible to implement: void fun(T)(T data) { import std; writeln(T.stringof); } void main() { immutable int a = 42; immutable int[] b = [ 69 ]; fun(a); // fine, prints immutable(int) fun(b); // prints immutable(int)[], not immutable(int[]) }2c. There are a number of hacks in the compiler that give special treatment to shared numerics. Such is inaccessible to user code. Worse, they don't generate correct code. void main() { shared int i = 42; i = i + 2; // whatta? }Shared memory reads/writes are no longer allowed. I don't think that's a hack.Show me where it isn't true and/or isn't useful.4. The way scope & return & ref apply to types is completely consistent. This enables me to advise that when people have problems understanding it, to rewrite their example code in terms of raw pointers, as it will behave the same.I very much wish this is true and useful.
Nov 01 2021
On Tuesday, 2 November 2021 at 01:00:27 UTC, Walter Bright wrote:On 11/1/2021 3:02 PM, Andrei Alexandrescu wrote:I hear the sound of bagpipes in the background (see no true scotsman). While it is true that hash tables are not basic, they are treated and advertised as such by the language itself.True, but hash tables are not basic types, structs, arrays or tuples!1. basic types, structs, and arrays are interchangeable. But I couldn't add tuples to the list, because the function call ABI for structs is "special". Urgh.1a. Hash tables have a number of language magic hacks (particularly concerning keys that have statically-sized array types) that are thoroughly inconsistent with the language rules.
Nov 02 2021
On 11/1/2021 3:02 PM, Andrei Alexandrescu wrote:2b. Calls to built-in arrays remove the top-level qualifier in a way that is not accessible to user code.Perhaps that should be applied generally. If someone wants to do a DIP for it, that would be good.
Nov 01 2021
On 01.11.21 23:02, Andrei Alexandrescu wrote:I think DIP 1000 etc. is actually a prime example of non-orthogonal language design, even if we ignore the issues with `ref` that have already been brought up. Lifetimes are not orthogonal to aggregates and function calls. To avoid such a situation, Rust allows explicit lifetime parameters. In general, if for type checking, the compiler tracks information that can't be passed along when calling functions or when storing data in a struct/class, there will inevitably be trouble. I have been guilty of implementing quick hacks like that myself in order to get code to type check before the paper deadline, but this kind of thing always comes back to bite users and ultimately the language designer. [1] [1] https://github.com/eth-sri/silq/issues/284. The way scope & return & ref apply to types is completely consistent. This enables me to advise that when people have problems understanding it, to rewrite their example code in terms of raw pointers, as it will behave the same.I very much wish this is true and useful.
Nov 02 2021
On Monday, 1 November 2021 at 21:41:29 UTC, Walter Bright wrote:On 11/1/2021 9:18 AM, deadalnix wrote:Yes. There are so many of them it's hard to list them all. I'm going to glance over a bunch on the top of my mind, feel free to ask more about any one of them if you want me to expand deeper. 1. enum binary ops and final switch. final switch assume an enum take a finite set of values as declared in the enum, but many more value can be obtained using binary ops. 2. type qualifier and delegates. Because the type system doesn't track the type qualifier of its capture, it is possible to have immutable or shared data refers to thread local ones through a delegate. 3. type qualifier transitivity and templates. template will consider types with different qualifier as disjoint, which seems like they should, until you try to write a container library or try to get range to interract with type qualifier. even remotely close. We don't have a decent set of collection to use because of it, and even worse, it's not even possible to write one. 4. Scope variables and closures. Closure capture sub scopes incorrectly. This is especially relevant in loops, because the variables captured are past their lifetime, leading to incorrect behaviors. 5. string autodecoding. The array type that behave like no other. 6. Identifier resolution and UFCS works prevent from effectively extending a type's behavior. This because as soon as the type is passed down to a template, then identifiers are now resolved in the template's context and all the UFCS extended interface becomes impossible to resolve. 7. Identifier resolution and mixin style codegen. mixin force a second round of identifier resolution, generated via T.stringof and alike, but these types may not resolve where the string is mixed in (for instance, when you mixin within a template). 8. 6 and 7 also do clash with visibility qualifiers, for the same reasons. Even when symbol resolve, they may end up being private. 9. Functional programming and attribute soup. Because it is not possible to define attribute in a way that depends to functions passed as argument, it is not possible to compose anything in a functional way without assuming that everything is impure, throw and uses the GC and more. This breaks inout in an unfixable manner as it becomes impossible to disambiguate: X foo(inout(Y) bar(...)) {} // Is the inout qualifier related to X or to bar's argument? Or both? 10. shared things are not constructible. dlang.org literally say you got to cast shared in and out, which is actually UB. 11. Function and first class function are different for no good reason. It's trivial to break a large portion of phobos by passing it functions that are not first class. 12. Sometime bool are integrals, sometime they aren't. Bonus point: one of the part of D that think bool are integral is DMD, and DMD won't hesitate to convert ints to bool if it can constant fold them into 0 or 1. But `isIntegral!bool` is false for instance. You will note that few of the above behavior are wrong per se. They are just different part of D making different assumptions about the underlying reality of D, which are often fine in isolation, but are mutually exclusive. For instance, there are good reasons for a bool to be an integral, and good reasons for it not to be. But there are no good reasons for DMD doig implicit conversion to bool as if was an integral, and `isIntegral!bool` being false. Each of them can be true, but both of them cannot be true at the same time. These are just a few that I can brain dump, but there are a ton more. I'd say except 3. that is the elephant in the room, the overall thing is more a death by a thousand cut rather thanthings have been done in D. D's feature just don't compose well because they aren't orthogonal with each other (and many are inconsistent).Can you be more specific?
Nov 01 2021
On 11/1/21 9:18 PM, deadalnix wrote:On Monday, 1 November 2021 at 21:41:29 UTC, Walter Bright wrote:I quote this post in its entirety because I so much agree with it. Each of these issues is something that has been overlooked for decades.On 11/1/2021 9:18 AM, deadalnix wrote:Yes. There are so many of them it's hard to list them all. I'm going to glance over a bunch on the top of my mind, feel free to ask more about any one of them if you want me to expand deeper. 1. enum binary ops and final switch. final switch assume an enum take a finite set of values as declared in the enum, but many more value can be obtained using binary ops. 2. type qualifier and delegates. Because the type system doesn't track the type qualifier of its capture, it is possible to have immutable or shared data refers to thread local ones through a delegate. 3. type qualifier transitivity and templates. template will consider types with different qualifier as disjoint, which seems like they should, until you try to write a container library or try to get range to interract with type qualifier. remotely close. We don't have a decent set of collection to use because of it, and even worse, it's not even possible to write one. 4. Scope variables and closures. Closure capture sub scopes incorrectly. This is especially relevant in loops, because the variables captured are past their lifetime, leading to incorrect behaviors. 5. string autodecoding. The array type that behave like no other. 6. Identifier resolution and UFCS works prevent from effectively extending a type's behavior. This because as soon as the type is passed down to a template, then identifiers are now resolved in the template's context and all the UFCS extended interface becomes impossible to resolve. 7. Identifier resolution and mixin style codegen. mixin force a second round of identifier resolution, generated via T.stringof and alike, but these types may not resolve where the string is mixed in (for instance, when you mixin within a template). 8. 6 and 7 also do clash with visibility qualifiers, for the same reasons. Even when symbol resolve, they may end up being private. 9. Functional programming and attribute soup. Because it is not possible to define attribute in a way that depends to functions passed as argument, it is not possible to compose anything in a functional way without assuming that everything is impure, throw and uses the GC and more. This breaks inout in an unfixable manner as it becomes impossible to disambiguate: X foo(inout(Y) bar(...)) {} // Is the inout qualifier related to X or to bar's argument? Or both? 10. shared things are not constructible. dlang.org literally say you got to cast shared in and out, which is actually UB. 11. Function and first class function are different for no good reason. It's trivial to break a large portion of phobos by passing it functions that are not first class. 12. Sometime bool are integrals, sometime they aren't. Bonus point: one of the part of D that think bool are integral is DMD, and DMD won't hesitate to convert ints to bool if it can constant fold them into 0 or 1. But `isIntegral!bool` is false for instance. You will note that few of the above behavior are wrong per se. They are just different part of D making different assumptions about the underlying reality of D, which are often fine in isolation, but are mutually exclusive. For instance, there are good reasons for a bool to be an integral, and good reasons for it not to be. But there are no good reasons for DMD doig implicit conversion to bool as if was an integral, and `isIntegral!bool` being false. Each of them can be true, but both of them cannot be true at the same time. These are just a few that I can brain dump, but there are a ton more. I'd say except 3. that is the elephant in the room, the overall thing is more a death by a thousand cut rather thanbeen done in D. D's feature just don't compose well because they aren't orthogonal with each other (and many are inconsistent).Can you be more specific?
Nov 01 2021
Thank you. This is a great list. I would appreciate it if you could make a bugzilla entry for each one, along with a piece of example code. Some specific comments below: On 11/1/2021 6:18 PM, deadalnix wrote:1. enum binary ops and final switch. final switch assume an enum take a finite set of values as declared in the enum, but many more value can be obtained using binary ops.Not sure what to say here. enums have more than one use: 1. enumerate all values of a particular type 2. enumerate some specific values of a particular type Only use final for case (1).2. type qualifier and delegates. Because the type system doesn't track the type qualifier of its capture, it is possible to have immutable or shared data refers to thread local ones through a delegate.This is simply a bug I haven't gotten around to fix.3. type qualifier transitivity and templates. template will consider types with different qualifier as disjoint, which seems like they should, until you try to write a container library or try to get range to interract with type qualifier. close. We don't have a decent set of collection to use because of it, and even worse, it's not even possible to write one.I beg of you and Andrei to produce a canonical example and place it in bugzilla. Perhaps I misunderstood Andrei when he said it would be resolved when we had copy constructors. Well, we have copy constructors now.4. Scope variables and closures. Closure capture sub scopes incorrectly. This is especially relevant in loops, because the variables captured are past their lifetime, leading to incorrect behaviors. 5. string autodecoding. The array type that behave like no other.That's actually not a problem with the language. It's a problem with Phobos, one I've been trying to kill with fire for 10 years no.9. Functional programming and attribute soup. Because it is not possible to define attribute in a way that depends to functions passed as argument, it is not possible to compose anything in a functional way without assuming that everything is impure, throw and uses the GC and more. This breaks inout in an unfixable manner as it becomes impossible to disambiguate: X foo(inout(Y) bar(...)) {} // Is the inout qualifier related to X or to bar's argument? Or both? 10. shared things are not constructible. dlang.org literally say you got to cast shared in and out, which is actually UB.Yes, that's correct. I know of *no* way to construct a shared object without going into system code. Just like there's no way to implement malloc() without dirty pointer manipulation. Note that in safe code neither can be done. I propose that this is not a further issue.12. Sometime bool are integrals, sometime they aren't. Bonus point: one of the part of D that think bool are integral is DMD, and DMD won't hesitate to convert ints to bool if it can constant fold them into 0 or 1. But `isIntegral!bool` is false for instance.Phobos has a number of incomprehensible isxxxxx() functions. They are not the language's fault, though. Nor are they my fault, as I never reviewed them. But they are my responsibility.For instance, there are good reasons for a bool to be an integral, and good reasons for it not to be. But there are no good reasons for DMD doig implicit conversion to bool as if was an integral, and `isIntegral!bool` being false. Each of them can be true, but both of them cannot be true at the same time.Of course. Part of the motivation for Phobos v2 is to get rid of that garbage.
Nov 01 2021
On Tuesday, 2 November 2021 at 03:38:02 UTC, Walter Bright wrote:Thank you. This is a great list. I would appreciate it if you could make a bugzilla entry for each one, along with a piece of example code. Some specific comments below:As general answer, you request for bug report for these issues. Most of them do have bug report, several of them you dismissed as being issues to begin with.On 11/1/2021 6:18 PM, deadalnix wrote:And here we are getting at the root of the problem. See, your use case 1 and 2 are all well and good. But an enum can't be both. It has to be one or the other. Pretending this is not a problem is exactly why these proliferate and this is by far the biggest tax on D's user time. Nothing comes close. Think about it. Any code using an enum now must make a guess as to what the rest of the program as a whole does. It is already bad within a given application, but it is impossible for a library writer, or generic code to even consider doing that without defeating its whole purpose. Types and other languages constructs are there to help the user by providing guarantee. invariant that the user knows won't be broken. When that is not the case, then these construct just become a tax on the user, which need to learn and know about them, but do not get any significant benefit from them. 1 and 2 are mutually exclusive. That's it, really. And for as long as you don't think this is a problem - while many people in this thread tell you it is - this will continue to proliferate.1. enum binary ops and final switch. final switch assume an enum take a finite set of values as declared in the enum, but many more value can be obtained using binary ops.Not sure what to say here. enums have more than one use: 1. enumerate all values of a particular type 2. enumerate some specific values of a particular type Only use final for case (1).It's really simple. Vector!T and Vector!(const T) are completely disjoint types. there is no way to get `const Vector!T` to be the same as `const Vector(const T)`. We aren't just talking about implicit conversion here, because this will break when things are passed by ref. There needs to be a way for both to be understood as having the same underlying reality by the compiler. Basically, ranges and collection needs to behave just like the builtin slice do, but as far as i know, there is no way to do this at the moment. ```d Vector!int v; void foo(ref vector!(const int) x) { // ... } foo(v); // There needs to be a way to make this work. ``` I invested a fair amount of time last month into trying to make a collection library for phobos, but there is just no way to make this work that anyone could come up with.3. type qualifier transitivity and templates. template will consider types with different qualifier as disjoint, which seems like they should, until you try to write a container library or try to get range to interract with type qualifier. comes even remotely close. We don't have a decent set of collection to use because of it, and even worse, it's not even possible to write one.I beg of you and Andrei to produce a canonical example and place it in bugzilla. Perhaps I misunderstood Andrei when he said it would be resolved when we had copy constructors. Well, we have copy constructors now.That's actually not a problem with the language. It's a problem with Phobos, one I've been trying to kill with fire for 10 years no.No, no, no and no. The standard library is part of the language. What does it change when I use D if the problem is in phobos or DMD? It doesn't. The impact is the same nevertheless: generic code needs to special case string or it is buggy.Yes, that's correct. I know of *no* way to construct a shared object without going into system code. Just like there's no way to implement malloc() without dirty pointer manipulation. Note that in safe code neither can be done. I propose that this is not a further issue.There is not at the moment. You need one more type qualifier indicating a unique access to a subgraph of object. Then promoting that edge to shared makes the object shared. Same goes for immutable. This also solve a ton of other problems, everything that is handled by the live proposal to begin with, but also consumer/producer type object sharing, and a ton more.Phobos has a number of incomprehensible isxxxxx() functions. They are not the language's fault, though. Nor are they my fault, as I never reviewed them. But they are my responsibility.Phobos is part of the language. And it disagrees with DMD. This is a problem. This very one has caused me to waste almost a full day of work a few weeks ago because DMD started to pick the wrong template overload in some test because it got smart enough to constant fold something to 1, then true.
Nov 03 2021
On Tuesday, 2 November 2021 at 01:18:02 UTC, deadalnix wrote:9. Functional programming and attribute soup. Because it is not possible to define attribute in a way that depends to functions passed as argument, it is not possible to compose anything in a functional way without assuming that everything is impure, throw and uses the GC and more.I agree with almost all of these, but this one especially. A side effect of the lack of attribute polymorphism is that instead of making things take function parameters, you make them templates with alias parameters, making template bloat even worse. For an idea of the impact this can have: I got a 10% improvement in compile time on a medium-sized codebase by using eager versions of std.algorithm in debug builds.
Nov 01 2021
On Monday, 1 November 2021 at 21:41:29 UTC, Walter Bright wrote:1. basic types, structs, and arrays are interchangeable. But I couldn't add tuples to the list, because the function call ABI for structs is "special". Urgh.Why? Shouldn't a tuple just be syntactical suger for a regular struct with special naming conventions (mangling)?
Nov 02 2021
On Monday, 1 November 2021 at 00:20:33 UTC, Andrei Alexandrescu wrote:I think it's relevant to our recent discussion on versioning, and also for its considerations on language design. https://youtube.com/watch?v=raB_289NxBk P.S. Destruction comes at https://youtu.be/raB_289NxBk?t=4727 :o)What? Pattern matching doesn't scale/nest well because you think Rust, Swift, Elixir programmers...
Nov 01 2021
On Monday, 1 November 2021 at 08:15:55 UTC, Araq wrote:What? Pattern matching doesn't scale/nest well because you Ocaml, Rust, Swift, Elixir programmers...It scales, but how do you know if you remembered to test all types? If you forgot one, you'll get a runtime-crash. So you need something more powerful, something that can statically verify that you cover all relevant types (like a formalization of a set of types). Then again, I am not really sure how often you need to test more than a handfull types in a well designed program, in which case if-then-else is sufficient…
Nov 01 2021
On Monday, 1 November 2021 at 16:26:47 UTC, Ola Fosheim Grøstad wrote:On Monday, 1 November 2021 at 08:15:55 UTC, Araq wrote:Note to those not familiar with it, this is frequently called exhaustiveness checking.What? Pattern matching doesn't scale/nest well because you ML, Ocaml, Rust, Swift, Elixir programmers...It scales, but how do you know if you remembered to test all types? If you forgot one, you'll get a runtime-crash. So you need something more powerful, something that can statically verify that you cover all relevant types (like a formalization of a set of types).
Nov 01 2021
On Monday, 1 November 2021 at 08:15:55 UTC, Araq wrote:On Monday, 1 November 2021 at 00:20:33 UTC, Andrei Alexandrescu wrote:Andrei is perfectly correct on this IMO, and it's telling that both you and Herb dodged the complaint in the exact same way by invoking an argument from authority (or maybe analogy?) - "Well these other successful languages do it so it must be okay". Herb goes one further and dismisses Andrei's rebuttal - that even if these other languages use pattern matching successfully, C++ does a lot of things differently and thus the (fallacious IMO) argument that other languages do this doesn't really hold up - with a pretty weak "we'll have to wait and see how it goes". Not that I'm ascribing any intentional malice or desire to ignore Andrei's complaint to Herb's reponse, but I think he dismissed it a little too easily given that even in my own personal experience, writing nested match (and nested try-catch) statements is ugly, messy, and an enormous pain that really limits how often I reach for them. That being said, I am a huge proponent of more "syntactically light" pattern matching features in a language as they can really make for some concise and powerful code.I think it's relevant to our recent discussion on versioning, and also for its considerations on language design. https://youtube.com/watch?v=raB_289NxBk P.S. Destruction comes at https://youtu.be/raB_289NxBk?t=4727 :o)What? Pattern matching doesn't scale/nest well because you Ocaml, Rust, Swift, Elixir programmers...
Nov 01 2021
On Monday, 1 November 2021 at 18:38:05 UTC, Meta wrote:Herb goes one further and dismisses Andrei's rebuttal - that even if these other languages use pattern matching successfully, C++ does a lot of things differently and thus the (fallacious IMO) argument that other languages do this doesn't really hold up - with a pretty weak "we'll have to wait and see how it goes".I don't think Herb dodged. It is right to look at what is successful in other languages. The fact something is successful in so many languages is a data point that cannot, and shouldn't, be ignored. However, Andrei is right when he point that there is a category of use case, typically in generic code, that is not well served by current mechanisms. This is not a problem in most language because C++ (and D), differs significantly in their approach there. You'll note that there are example in Herb's presentation that are also not well served by current D constructs, notably cascading match clauses. They ends up being done with very repetitive and error prone template constraints in D.
Nov 01 2021
On Monday, 1 November 2021 at 18:38:05 UTC, Meta wrote:On Monday, 1 November 2021 at 08:15:55 UTC, Araq wrote:Are you going to change your name to "Facebook"?On Monday, 1 November 2021 at 00:20:33 UTC, Andrei Alexandrescu wrote:I think it's relevant to our recent discussion on versioning, and also for its considerations on language design.
Nov 01 2021
On Monday, 1 November 2021 at 22:58:53 UTC, ClapTrap wrote:On Monday, 1 November 2021 at 18:38:05 UTC, Meta wrote:If only I had copyrighted my username!On Monday, 1 November 2021 at 08:15:55 UTC, Araq wrote:Are you going to change your name to "Facebook"?On Monday, 1 November 2021 at 00:20:33 UTC, Andrei Alexandrescu wrote:I think it's relevant to our recent discussion on versioning, and also for its considerations on language design.
Nov 01 2021
On Monday, 1 November 2021 at 00:20:33 UTC, Andrei Alexandrescu wrote:I think it's relevant to our recent discussion on versioning, and also for its considerations on language design. https://youtube.com/watch?v=raB_289NxBk P.S. Destruction comes at https://youtu.be/raB_289NxBk?t=4727 :o)Many interesting discussion points in the video. It seems Sean Baxter's "circle" C++ compiler is opening some eyes. A quick scan produced an older critique of circle wrt another C++ proposal: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2062r0.pdf. Those authors seem to embrace crippling, IMO, scope restrictions that circle does not. If you've looked at circle's capabilities and would care to comment wrt D, I think we'd all benefit. Separately, many thanks for your great work in D.
Nov 01 2021
On 11/1/21 3:45 AM, Bruce Carneal wrote:It seems Sean Baxter's "circle" C++ compiler is opening some eyes.I haven't watched the video yet. However, I had the privilege of having Sean Baxter as my only guest on one my D meetups. I had attended a C++ meetup where Sean introduced Circle. Basically, almost everything in Circle was already in D. Interestingly, he hadn't heard about D. So, he came to my meetup the next day. He may have found a couple of new things in D that Circle did not have.A quick scan produced an older critique of circle wrt another C++ proposal: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2062r0.pdf. Those authors seem to embrace crippling, IMO, scope restrictions that circle does not.Andrew Sutton happens to be one of the authors of an infamous paper: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3613.pdf That paper deprived C++ programmers of 'static if' for 8 years and counting. I am sure they will eventually come up with something better many years from now. I see their behaviour as undervaluing engineering. I think D and Circle are great engineer tools but C++ is seeking some kind of perfection. For example, yes, 'static if' can be shown to have problems and shortcomings but it is an incredibly useful and succesful feature. (Aside: There was another paper written years prior by known C++ personalities, proving "iterators are a better abstraction compared to ranges." (I can't find that paper anymore.) Ok, good proof! You go that way, and I will continue with my getting things done with ranges.) Ali
Nov 01 2021
On Monday, 1 November 2021 at 00:20:33 UTC, Andrei Alexandrescu wrote:I think it's relevant to our recent discussion on versioning, and also for its considerations on language design. https://youtube.com/watch?v=raB_289NxBk P.S. Destruction comes at https://youtu.be/raB_289NxBk?t=4727 :o)Why is it that always when I see Herb Sutter talk about C++, that long lost love for C++ suddenly re-emerges from the deep hurt past relationship...
Nov 01 2021
On 2021-11-01 9:23, Arjan wrote:On Monday, 1 November 2021 at 00:20:33 UTC, Andrei Alexandrescu wrote:Maybe because he's just the best technical speaker ever.I think it's relevant to our recent discussion on versioning, and also for its considerations on language design. https://youtube.com/watch?v=raB_289NxBk P.S. Destruction comes at https://youtu.be/raB_289NxBk?t=4727 :o)Why is it that always when I see Herb Sutter talk about C++, that long lost love for C++ suddenly re-emerges from the deep hurt past relationship...
Nov 01 2021
On 11/1/2021 6:39 AM, Andrei Alexandrescu wrote:Maybe because he's just the best technical speaker ever.I agree with that. Herb is just amazing.
Nov 01 2021
On Mon, Nov 01, 2021 at 01:23:45PM +0000, Arjan via Digitalmars-d wrote: [...]Why is it that always when I see Herb Sutter talk about C++, that long lost love for C++ suddenly re-emerges from the deep hurt past relationship...It's like an abusive relationship that you can never break free of. ;-) Me -- I call it quits on C++, clean break, no phone calls, no texts, no further contact, no shared assets. Been livin' happily ever after since. :-P Well, OK, not entirely no further contact, sometimes work obliges me to work with C++ again. But only on the rare occasion. I mostly work only with C these days, and for that I'm happy -- in spite of C's fundamental flaws, it's still a smaller, cleaner language than the mess that C++ is. T -- Never ascribe to malice that which is adequately explained by incompetence. -- Napoleon Bonaparte
Nov 01 2021
On Monday, 1 November 2021 at 13:23:45 UTC, Arjan wrote:On Monday, 1 November 2021 at 00:20:33 UTC, Andrei Alexandrescu wrote:The same goes for Bjarne S, but then I open a C++ file in my text editor and images of Scott Meyers take over my brain.I think it's relevant to our recent discussion on versioning, and also for its considerations on language design. https://youtube.com/watch?v=raB_289NxBk P.S. Destruction comes at https://youtu.be/raB_289NxBk?t=4727 :o)Why is it that always when I see Herb Sutter talk about C++, that long lost love for C++ suddenly re-emerges from the deep hurt past relationship...
Nov 01 2021
On Mon, Nov 01, 2021 at 10:39:52PM +0000, bachmeier via Digitalmars-d wrote:On Monday, 1 November 2021 at 13:23:45 UTC, Arjan wrote:LOL!!! T -- Never wrestle a pig. You both get covered in mud, and the pig likes it.On Monday, 1 November 2021 at 00:20:33 UTC, Andrei Alexandrescu wrote:The same goes for Bjarne S, but then I open a C++ file in my text editor and images of Scott Meyers take over my brain.I think it's relevant to our recent discussion on versioning, and also for its considerations on language design. https://youtube.com/watch?v=raB_289NxBk P.S. Destruction comes at https://youtu.be/raB_289NxBk?t=4727 :o)Why is it that always when I see Herb Sutter talk about C++, that long lost love for C++ suddenly re-emerges from the deep hurt past relationship...
Nov 01 2021
Don't underestimate `C++`. Maybe `C++`'s implementation is not very good. However, as an plain user, `C++` provides us with good results. I like `C++`. I write modern `C++` and feel very good. Of course, I also like `d`. I hope `C++` and `d` maintain the current benign competition.
Nov 01 2021