www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Herb Sutter's CppCon talk "Extending and Simplifying C++: Thoughts on

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
next sibling parent reply deadalnix <deadalnix gmail.com> writes:
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
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/31/21 8:46 PM, deadalnix wrote:
 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?
"Simplify C++ by adding to it" is the top-level message. It's a gambit.
Oct 31 2021
parent reply deadalnix <deadalnix gmail.com> writes:
On Monday, 1 November 2021 at 01:47:32 UTC, Andrei Alexandrescu 
wrote:
 On 10/31/21 8:46 PM, deadalnix wrote:
 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?
"Simplify C++ by adding to it" is the top-level message. It's a gambit.
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.
Nov 01 2021
parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.com> writes:
On 2021-11-01 17:41, Walter Bright wrote:
 On 11/1/2021 9:18 AM, deadalnix wrote:

 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:
There are easily found counterpoints even to your examples.
 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
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Monday, 1 November 2021 at 22:02:26 UTC, Andrei Alexandrescu 
wrote:
 On 2021-11-01 17:41, Walter Bright wrote:
 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.
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.org
Nov 01 2021
parent Walter Bright <newshound2 digitalmars.com> writes:
On 11/1/2021 3:07 PM, Paul Backus wrote:
 On Monday, 1 November 2021 at 22:02:26 UTC, Andrei Alexandrescu wrote:
 On 2021-11-01 17:41, Walter Bright wrote:
 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.
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.org
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.
Nov 01 2021
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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:
[...]
 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.
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 Abrash
Nov 01 2021
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 11/1/2021 3:02 PM, Andrei Alexandrescu 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.
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.
True, but hash tables are not basic types, structs, arrays or tuples!
 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[]) }
Maybe qualified ranges should be impossible to implement.
 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.
 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.
Show me where it isn't true and/or isn't useful.
Nov 01 2021
parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Tuesday, 2 November 2021 at 01:00:27 UTC, Walter Bright wrote:
 On 11/1/2021 3:02 PM, Andrei Alexandrescu 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.
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.
True, but hash tables are not basic types, structs, arrays or tuples!
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.
Nov 02 2021
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
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
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01.11.21 23:02, Andrei Alexandrescu wrote:
 
 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.
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/28
Nov 02 2021
prev sibling next sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Monday, 1 November 2021 at 21:41:29 UTC, Walter Bright wrote:
 On 11/1/2021 9:18 AM, deadalnix wrote:

 things 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?
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 than
Nov 01 2021
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/1/21 9:18 PM, deadalnix wrote:
 On Monday, 1 November 2021 at 21:41:29 UTC, Walter Bright wrote:
 On 11/1/2021 9:18 AM, deadalnix wrote:

 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?
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 than
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.
Nov 01 2021
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
parent deadalnix <deadalnix gmail.com> writes:
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:
 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).
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.
 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.
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.
 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
prev sibling parent Elronnd <elronnd elronnd.net> writes:
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
prev sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
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
prev sibling next sibling parent reply Araq <rumpf_a web.de> writes:
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
next sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
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
parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
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:
 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).
Note to those not familiar with it, this is frequently called exhaustiveness checking.
Nov 01 2021
prev sibling parent reply Meta <jared771 gmail.com> writes:
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:
 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...
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.
Nov 01 2021
next sibling parent deadalnix <deadalnix gmail.com> writes:
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
prev sibling parent reply ClapTrap <clap trap.com> writes:
On Monday, 1 November 2021 at 18:38:05 UTC, Meta wrote:
 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:
 I think it's relevant to our recent discussion on versioning, 
 and also for its considerations on language design.
Are you going to change your name to "Facebook"?
Nov 01 2021
parent Meta <jared771 gmail.com> writes:
On Monday, 1 November 2021 at 22:58:53 UTC, ClapTrap wrote:
 On Monday, 1 November 2021 at 18:38:05 UTC, Meta wrote:
 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:
 I think it's relevant to our recent discussion on 
 versioning, and also for its considerations on language 
 design.
Are you going to change your name to "Facebook"?
If only I had copyrighted my username!
Nov 01 2021
prev sibling next sibling parent reply Bruce Carneal <bcarneal gmail.com> writes:
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
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
prev sibling next sibling parent reply Arjan <arjan ask.me.to> writes:
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
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.com> writes:
On 2021-11-01 9:23, Arjan wrote:
 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...
Maybe because he's just the best technical speaker ever.
Nov 01 2021
parent Walter Bright <newshound2 digitalmars.com> writes:
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
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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
prev sibling parent reply bachmeier <no spam.net> writes:
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:
 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...
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.
Nov 01 2021
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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:
 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...
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.
LOL!!! T -- Never wrestle a pig. You both get covered in mud, and the pig likes it.
Nov 01 2021
prev sibling parent zjh <fqbqrr 163.com> writes:
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