May 12, 2021

On Monday, 10 May 2021 at 22:58:41 UTC, deadalnix wrote:

>

Sure, but look at this thread. D is crumbling under the weight, not of the number f feature, but of the fact that a large portion of them simply are unsound.

At this point, the decision made is to push the madness on the user. Fair enough, but if the standard lib devs are not willing to put up with it, why in hell would you expect anyone else to? Just look at what's in the C++ standard lib or boost and compare to your average C++ project to see the kind of gap in term of motivation to put up with bullshit exists between standard lib devs and Joe coder. It's not even close.

This stuff ain't working properly so let's just given getting to work at all is not how you iterate toward a great useful product.

Well, this thread is 11 pages and show no sign of winding down.
In the meantime, has anyone looked at the code that sparked this outrage ?

As I mentioned in the PR, the issue wouldn't have happened if the fmt template parameter was a string and not an alias.

>

Q: why is fmt an alias and not a simple string ?
A: No real reason.

The way I see it, the issue is valid, the fix wasn't. format API should have accepted a string and let the compiler perform any allowed implicit conversion, instead of taking exactly the type via alias.

I wish our most competent contributors would find it more interesting to direct their attention to Github or promote the language to their large Twitter following over engaging in flamewar.

May 12, 2021

On Wednesday, 12 May 2021 at 05:25:59 UTC, Mathias LANG wrote:

>

On Monday, 10 May 2021 at 22:58:41 UTC, deadalnix wrote:

>

...

Well, this thread is 11 pages and show no sign of winding down.
In the meantime, has anyone looked at the code that sparked this outrage ?

...

I wish our most competent contributors would find it more interesting to direct their attention to Github or promote the language to their large Twitter following over engaging in flamewar.

I support bringing these types of discussions to github (not Reddit/Twitter) instead where people can respond to a comment directly, or through thumbs up or down and at least edit their comments rather than piling on emails sequentially. Or a different type of discussion platform entirely.

(That said I am with Adam Ruppe's take on this matter)

May 12, 2021
On Friday, May 7, 2021 9:39:40 AM MDT Andrei Alexandrescu via Digitalmars-d wrote:
> On 5/7/21 11:33 AM, Adam D. Ruppe wrote:
> > On Friday, 7 May 2021 at 15:25:30 UTC, Andrei Alexandrescu wrote:
> >> Enums derived from strings should not be supported as strings in the standard library.
> >
> > I don't think the stdlib should special case much of anything.
> >
> > Special casing enums is a mistake. If the user wants it treated as a string, they can cast it to a string.
>
> yes
>
> > Special casing static arrays is a mistake. The user can just slice it out the outside.
>
> Yes
>
> > Special casing alias this is a mistake. The user can pass what they meant to pass.
>
> YES
>
> > The phobos templates should work like all other templates - on the exact type passed. Other functions work with the normal overloading and implicit conversion rules.
> >
> > Kill all the special cases!
>
> YES!!!

Agreed. While implicit conversions can at times be useful, they cause a ton of problems when templates are involved. Ideally, we should accept no implicit conversions of any kind with templated code. And honestly, I wish that the language had fewer implicit conversions in it. In particular, I think that implicitly slicing static arrays was a big mistake, and we've had a number of issues in Phobos because of it when trying to later generalize functions that originally just took strings.

- Jonathan M Davis



May 12, 2021
On Tuesday, May 11, 2021 12:37:20 PM MDT Meta via Digitalmars-d wrote:
> On Tuesday, 11 May 2021 at 16:44:03 UTC, Andrei Alexandrescu
>
> wrote:
> >> Again with moving the goalposts.
> >
> > To clarify: you can't make up your own definitions as you go so as to support the point you're making at the moment. You can't go "oh, call it something else than a type, my point stays". No. Your point doesn't stay.
> >
> > By the same token you can't make up your own definition of what subtyping is and isn't. Value types and reference types are well-trodden ground. You can't just claim new terminology and then prove your own point by using it.
>
> I apologize for injecting myself into this conversation, but with all due respect, what the hell are you talking about? Everything Deadalnix is saying makes perfect sense - it's basic type theory, and yet you're accusing him of moving goalposts and making up definitions, etc. The problem is that `isSomeString` doesn't respect the LSP and the template constraints on the relevant stdlib functions for enums are a hack to work around that. End of story. if `isSomeString` was defined sensibly, these template constraint hacks would not have to exist.
>
> All the bluster about `popFront` on enum strings, etc. is completely irrelevant, and is a red herring anyway (as was already explained).
>
> I'm sorry for being so blunt, but this conversation is painful to read.

Having isSomeString accept types that implicitly converted to string would be a disaster. Templates do not operate on implict conversions - or even on subtypes. They operate on the exact type they're given. You can, of course, write a template constraint which checks for implicit conversions, but you still don't get the implicit conversion when the template is instantiated. You get the original type. This has a number of implications, but in general, it leads to bugs if templates check for implicit conversions instead of exact types. In particular, any templated function which checks for an implicit conversion then needs to force the implicit conversion, or it will likely not work properly - be it because you get compilation errors, or because the original type compiles with the same code but does not behave the same way as the type from the implicit conversion which was not actually made.

In fact, IIRC, at one point, isSomeString _did_ work with enums, and we fixed it so that it didn't, because it was causing problems. Also, IIRC, it was my fault that it was ever made to work with enums, and I very much regret that.

In general, implicit conversions have no business in template constraints. Obviously, there are exceptions to that, but in general, there will be fewer bugs if the conversions are done explicitly by the code instantiating the template. The reason that it's done in Phobos as much as it is is primarily because of code that was originally not generic which was later templatized (often because it took string and was changed to work on multiple string types or to work on general ranges of characters). And in most cases where we've tried to templatize functions without breaking code, we've had problems because of the implicit conversions that worked before. std.traits.isConvertibleToString is one such abomination which came out of that (its use usually results in code that slices local variables and escapes them, which is really bad). IIRC, that was done by Walter, and if he's making mistakes like that with regards to implicit conversions and templated code, what do you think the average D programmer is doing?

The main reason for bringing up popFront and enums is to show that that enums with a base type of string are not actually strings, and treating them as if they were causes serious problems. There are of course places where that sub-typing results in implicit conversions, but templates do not work that way, and trying to force it is very problematic. The proliferation of template constraint and static if complexity that Andrei is complaining about with regards to stuff like format is the result of that, and it's the kind of code that's very hard to get right. Simply not trying to support those implicit conversions with templated functions _significantly_ reduces the complexity of such code with the only cost being that the code instantiating the template will have to use cast(string) on the enum value.

- Jonathan M Davis



May 12, 2021

On Wednesday, 12 May 2021 at 05:25:59 UTC, Mathias LANG wrote:

>

Well, this thread is 11 pages and show no sign of winding down.
In the meantime, has anyone looked at the code that sparked this outrage ?

As I mentioned in the PR, the issue wouldn't have happened if the fmt template parameter was a string and not an alias.

>

Q: why is fmt an alias and not a simple string ?
A: No real reason.

The way I see it, the issue is valid, the fix wasn't. format API should have accepted a string and let the compiler perform any allowed implicit conversion, instead of taking exactly the type via alias.

I wish our most competent contributors would find it more interesting to direct their attention to Github or promote the language to their large Twitter following over engaging in flamewar.

If formats expects a string, then it is indeed the right thing to accept a string :)

But that discussion goes further than this, and is necessary, IMO.

May 12, 2021
On 5/11/21 9:46 PM, deadalnix wrote:
> This whole model in C++ is unsound. It's easy to show. In you above example, the this pointer, typed as Widget*, points to an instance of a subclass of Widget. If you were to assign a Widget to that pointer (which you can do, this is a pointer to a mutable widget), then any references to that widget using a subtype of Widget is now invalid.

All of this is bizarrely incorrect. Care to elaborate?
May 12, 2021
On 5/11/21 10:04 PM, deadalnix wrote:
> On Wednesday, 12 May 2021 at 01:06:29 UTC, Walter Bright wrote:
>> On 5/11/2021 5:04 PM, Andrei Alexandrescu wrote:
>>> Another unpleasant issue:
>>>
>>>      enum Y : string { f7 = "%d" }
>>>      writeln(typeof(Y.f7.representation).stringof);
>>>
>>> prints immutable(ubyte)[], not immutable(char)[]. So not even Y.f7.representation is usable. Sigh.
>>
>> The representation of a named enum is its base type.
>>
>> The representation of a string type is immutable(ubyte)[].
>>
>> It's consistent.
> 
> Y.f7 is of type Y. It's representation is string, not immutable(ubyte)[]
> 
> typeof(Y.f7.representation) ought to be string.
> typeof(Y.f7.representation.representation) ought to be immutable(ubyte)[]
> 
> Unless I'm missing something, that wold b the consistent behavior. Unless representation is supposed to recurse up to the bottom turtle?

`representation` is a library function, so in a way we get to have a say in what it does. I would have expected it doesn't go all the way to primitive types, but if it does, that's not necessarily incorrect.
May 12, 2021
On Wednesday, 12 May 2021 at 02:41:31 UTC, 12345swordy wrote:
> On Wednesday, 12 May 2021 at 02:30:50 UTC, deadalnix wrote:
>> On Wednesday, 12 May 2021 at 02:21:06 UTC, 12345swordy wrote:
>>> Yes. A is being replace with the new instance of A that happens to have the same value here. There is no guarantee that they will share the same address.
>>>
>>> - Alex
>>
>> You might want to reconsider how sure of yourself you are.
> The code you posted, do not support your claim what so ever. When I am talk about address I am literally talking about virtual memory address here, such as 0x40000 or something similar to that. You do not know what the actual virtual memory address of variable of 'a' for class 'b', as the GC takes it care of it for you.
> So when A is being replace with the new instance of A that happens to have the same value that is being replace, the virtual memory that A holds from the function parameter currently holds will change.
>
> -Alex

Before posting that email was the best time to run the code, look at the output and deduce what it means.

The second best time is now.

In any case, I will disengage from that subthread with you, because it has reached its conclusion, and the point has been demonstrably made with actual code.

Arguing about what the code does really is pointless when you can simply run it and look at the result.
May 12, 2021
On 5/11/21 10:36 PM, Meta wrote:
> Last I checked, strings are reference types, in the same way that Java objects are reference types.

Just by means of clarification, that's not true because the length is stored with the pointer. This occasionally trips folks starting with D.
May 12, 2021
On 5/11/21 10:36 PM, Meta wrote:
> ++x still fulfills the contract that the derived enum has inherited from `int`: `++: int -> int`.

No, that would be ref int -> ref int, which has consequences.