Jump to page: 1 26  
Page
Thread overview
I wish all qualifiers were revisited with an eye for simplification
Aug 02, 2020
Adam D. Ruppe
Aug 02, 2020
Stefan Koch
Aug 03, 2020
Stefan Koch
Aug 13, 2020
Jonathan M Davis
Aug 13, 2020
Jonathan M Davis
Aug 13, 2020
Manu
Aug 03, 2020
RazvanN
Aug 03, 2020
Alexandru Ermicioi
Aug 03, 2020
Simen Kjærås
Aug 03, 2020
Bruce Carneal
Aug 03, 2020
Manu
Aug 04, 2020
Timon Gehr
Aug 05, 2020
Manu
Aug 04, 2020
Sebastiaan Koppe
Aug 04, 2020
Simen Kjærås
Aug 04, 2020
Manu
Aug 04, 2020
Simen Kjærås
Aug 04, 2020
Manu
Aug 04, 2020
Sebastiaan Koppe
Aug 04, 2020
Timon Gehr
Aug 05, 2020
Manu
Aug 04, 2020
Manu
Aug 05, 2020
Manu
Aug 04, 2020
Timon Gehr
Aug 05, 2020
Manu
Aug 04, 2020
Ronny
Aug 04, 2020
Timon Gehr
Aug 04, 2020
rikki cattermole
Aug 14, 2020
Manu
Aug 15, 2020
Timon Gehr
Aug 15, 2020
Timon Gehr
Aug 25, 2020
Nick Treleaven
Aug 13, 2020
IGotD-
Aug 14, 2020
Simen Kjærås
Aug 14, 2020
IGotD-
Aug 24, 2020
Atila Neves
Aug 24, 2020
Timon Gehr
Aug 24, 2020
Timon Gehr
Aug 25, 2020
Manu
August 02, 2020
(Background: qualifiers were introduced following my horror when I started writing D1 code and saw that strings are represented as char[]. So structs with string members would look like:

struct Widget
{
    int x, y;
    char[] name, parentName;
    ...
}

I found it just shocking that following a Widget's construction whoever aliased the same strings the outside could change members of the Widget without Widget knowing. Of course, other D1 coders disliked that as well, so they'd defensively duplicate in the constructor:

struct Widget
{
    int x, y;
    char[] name, parentName;
    this(char[] n, char[] p)
    {
        name = n.dup;
        parentName = p.dup;
    }
    ...
}

thus ensuring proliferation of the garbage whether duplication was needed or not.

I found this absolutely maddening, to the extent I didn't think D could be ever used at any considerable scale while dragging this anchor behind it.

The second problem was Walter was adamant about using arrays of characters at strings. He found the notion of a library-defined string type (a la C++) an absolute abomination. Stubborn about it like I've never seen him before or after. So my unstoppable requests for a string type were met with the proverbial immovable refusal. Ironically, much of his argument came from an efficiency angle, yet the unnecessary duplication was way less efficient than some reference counting/small string optimization/etc scheme that a dedicated string type would use.

Then we figured things would work out if we arranged things such that people could NOT change individual characters of a string. That would allow sharing without the danger of long-distance influence. After many discussions with Walter, Bartosz, Eric, Brad, and myself, immutable and const were born.

Then followed the other qualifiers, in order: shared and inout.)

* * *

The result is... there: https://dlang.org/spec/const3.html. It has the images https://dlang.org/images/qualifier-combinations.svg and https://dlang.org/images/qualifier-conversions.svg and a large table and a lot of rules. Whenever I code anything generic, I find myself going back to those damn images and tables way more than anyone ought to. (And it's ironic... I made those. Woe to the relative newcomer.)

It's all too complicated, making generic D programming into 3D chess instead of the difficult endeavor it already is. And what does it buy us? Well, we don't need to define a string library type. Yowzers. (Actually we should if we want to get rid of the GC. But then Walter would oppose that. So - stalemate once again.)

Far as I can tell, the power/weight ratio of qualifier is very poor. I wish a DIP would revisit qualifiers with a stated intent to simplify them as much as possible. Whenever I code generically I invariably run into these issues:

* Whatever I do, however I twitch, immutable finds the opportunity to lodge itself in a soft part of my body and cause constant pain. This doesn't work, that doesn't work. No solution for "tail immutable" - mutable references to immutable class instances can't be done without contortions. Can't assign to out immutable class references, though there's no reason for that (see Adam's recent post).

* No matter how I dice any significant piece of code, there will be five casts from immutable and/or back that I can't rid of and lose sleep at night trying to convince myself are justified.

* Every time "inout" comes within a radius of a mile of what I'm doing, it starts to stink like a skunk. I wish I could get a restraining order. I can't instantiate "inout" variables, so writing any tests or constraints becomes an advanced matter of defining functions and crap. I get frustrated, I protest to this forum, and immediately a cabal is raised under Timon's leadership. The cabal convinces me that inout is actually great and that I'm an idiot. I do get convinced, which is more of a proof that Timon is very good, than a testament to the conviviality of inout. Then I leave and get back to my code, and it stinks of inout again. And I hate it and myself for having to deal with it.

* Nobody - probably not even Timon - knows what "shared" does or is supposed to do and not do. The most I got from Walter ever is "shared is intentionally restricted so you can't do much without a cast". Yet the definition of "much" and the conditions under which casting is legit are not anywhere to be found.

* And of course, "shared" gladly partakes in qualifier combinations, thus spreading its stink around in a combinatorial manner. Believe it or not, the type "const inout shared T" exists. Of course, nobody knows what it really means or how it could be used.

A "Define All Qualifiers" DIP would be a radical improvement of the state of affairs.
August 02, 2020
On Sunday, 2 August 2020 at 20:50:14 UTC, Andrei Alexandrescu wrote:
> The cabal convinces me that inout is actually great and that I'm an idiot.

inout is great, but you are also not wrong about it. It has frustrating arbitrary limitations that should really just get lifted.

Steven designed it conservatively thinking it was a good idea at the time but agrees now it was a mistake to limit it like this.

Simplest step we could do is define inout == const if used for a local variable in a non-inout function. I think that'd eliminate the majority of the headache.

The `is` expression should be more strict, but a local declaration should just fallback to const for practicality.

> Believe it or not, the type "const inout shared T" exists. Of course, nobody knows what it really means or how it could be used.

I don't even have an idea lol
August 02, 2020
On 8/2/20 5:30 PM, Adam D. Ruppe wrote:
> On Sunday, 2 August 2020 at 20:50:14 UTC, Andrei Alexandrescu wrote:
>> The cabal convinces me that inout is actually great and that I'm an idiot.
> 
> inout is great, but you are also not wrong about it. It has frustrating arbitrary limitations that should really just get lifted.

Yes that would help a lot.
August 02, 2020
On Sunday, 2 August 2020 at 20:50:14 UTC, Andrei Alexandrescu wrote:
> (Background: qualifiers were introduced following my horror when I started writing D1 code and saw that strings are represented as char[]. So structs with string members would look like:
 [lots of stuff]

const inout shared T is simply the same as const shared T.

shared means simply: this is not thread local,
therefore this thing might be used by other threads
therefore you read or write it in an expression directly.
You can however have a function take a shared argument and leave
the scheduling or locking or whatever synchronization you use,
to enact an operation in a safe way.


August 02, 2020
On 8/2/20 6:55 PM, Stefan Koch wrote:
> On Sunday, 2 August 2020 at 20:50:14 UTC, Andrei Alexandrescu wrote:
>> (Background: qualifiers were introduced following my horror when I started writing D1 code and saw that strings are represented as char[]. So structs with string members would look like:
>   [lots of stuff]
> 
> const inout shared T is simply the same as const shared T.

Sadly no: https://run.dlang.io/is/etdPtP

> shared means simply: this is not thread local,
> therefore this thing might be used by other threads
> therefore you read or write it in an expression directly.
> You can however have a function take a shared argument and leave
> the scheduling or locking or whatever synchronization you use,
> to enact an operation in a safe way.

Yes, the intent was generous. The realization, not quite. However, I did learn from Walter that a number of invalid operations on shared numerics have now been disabled. However, copying a shared int into an int is allowed and as far as I know with no special treatment:

https://run.dlang.io/is/ZP124F

At least on ARM that should generate a read barrier.
August 03, 2020
On Monday, 3 August 2020 at 01:23:26 UTC, Andrei Alexandrescu wrote:
> On 8/2/20 6:55 PM, Stefan Koch wrote:
>> [...]
>
> Sadly no: https://run.dlang.io/is/etdPtP
>
>> [...]
>
> Yes, the intent was generous. The realization, not quite. However, I did learn from Walter that a number of invalid operations on shared numerics have now been disabled. However, copying a shared int into an int is allowed and as far as I know with no special treatment:
>
> https://run.dlang.io/is/ZP124F
>
> At least on ARM that should generate a read barrier.

No it should not.
With the right -preview switch it won't compile.

The programmer is to ensure that atomics or other needed syncronisation primitives are used.
August 03, 2020
On Sunday, 2 August 2020 at 20:50:14 UTC, Andrei Alexandrescu wrote:

> * Whatever I do, however I twitch, immutable finds the opportunity to lodge itself in a soft part of my body and cause constant pain. This doesn't work, that doesn't work. No solution for "tail immutable" - mutable references to immutable class instances can't be done without contortions. Can't assign to out immutable class references, though there's no reason for that (see Adam's recent post).
>

Maybe a library implementation of `TailMutable(T) if (is(T == immutable) || is(T == const))` for reference types can fix this without causing breakage and leaving immutable/const transitivity intact.


August 03, 2020
On Monday, 3 August 2020 at 03:14:15 UTC, RazvanN wrote:
>
> Maybe a library implementation of `TailMutable(T) if (is(T == immutable) || is(T == const))` for reference types can fix this without causing breakage and leaving immutable/const transitivity intact.

There is already Rebindable structure for that.
August 03, 2020
On Sunday, 2 August 2020 at 20:50:14 UTC, Andrei Alexandrescu wrote:
> * Nobody - probably not even Timon - knows what "shared" does or is supposed to do and not do. The most I got from Walter ever is "shared is intentionally restricted so you can't do much without a cast". Yet the definition of "much" and the conditions under which casting is legit are not anywhere to be found.

Shared today is a half-baked implementation of a half-thought idea. Manu wrote[0] almost two years ago what it should be: you can't read or write from a shared object, and only shared methods may be called on it. This was made into a DIP[1], and is half-way(?) implemented in the compiler as -preview=nosharedaccess. The semantics are effective and easy to understand.

--
  Simen

[0]: https://forum.dlang.org/post/mailman.4299.1539629222.29801.digitalmars-d@puremagic.com
[1]: https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1024.md
August 03, 2020
On 8/3/20 7:45 AM, Simen Kjærås wrote:
> On Sunday, 2 August 2020 at 20:50:14 UTC, Andrei Alexandrescu wrote:
>> * Nobody - probably not even Timon - knows what "shared" does or is supposed to do and not do. The most I got from Walter ever is "shared is intentionally restricted so you can't do much without a cast". Yet the definition of "much" and the conditions under which casting is legit are not anywhere to be found.
> 
> Shared today is a half-baked implementation of a half-thought idea. Manu wrote[0] almost two years ago what it should be: you can't read or write from a shared object, and only shared methods may be called on it. This was made into a DIP[1], and is half-way(?) implemented in the compiler as -preview=nosharedaccess. The semantics are effective and easy to understand.
> 
> -- 
>    Simen
> 
> [0]: https://forum.dlang.org/post/mailman.4299.1539629222.29801.digitalmars-d@puremagic.com 
> 
> [1]: https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1024.md

Found out about that after I wrote my diatribe. Thanks!
« First   ‹ Prev
1 2 3 4 5 6