www.digitalmars.com         C & C++   DMDScript  

digitalmars.dip.development - First Draft: Member of Operator

reply Richard (Rikki) Andrew Cattermole <richard cattermole.co.nz> writes:
The member of operator is a unified method for acquiring a member
of a context.

It rewrites into ``context.Identifier`` from ``:Identifier``.
Where the context expression is defined based upon usage. What it
requires to resolve to, depends upon the situation. Sometimes it
must be a type, others a value.

Latest:
https://gist.github.com/rikkimax/33d8cac529c1f4e4ea94b2d4b53cfcb5

Current:
https://gist.github.com/rikkimax/33d8cac529c1f4e4ea94b2d4b53cfcb5/2dba53e2a43f55bf4662036d7f18ff39ebfc3ef8

It supports returns, variable declarations, switch statements,
function calls argument-parameter matching, default
initialization of parameter, and comparison.

I have partially implemented it.

Missing in implementation is function parameter default
initialization and taking a type of a member of operator
``typeof(:Identifier)``. I was not originally going to do taking
of a type, but it is useful for sumtypes.

My motivation is for sumtypes. It allows a definition to be
compatible with library implementations as they do not require a
name.

Binary expressions are not supported, but they could be done with
a simple rewrite. A member of operator must appear as first term
in an expression and evaluate to the same type as the context.

This was pushed for by ryuukk, and thanks to IchorDev for doing
the idea thread to show a strong desire by the community!

This allows you to do inference upon a variable declaration!

```d
Enum var = :Identifier;
```

Which is equivalent to:

```d
Enum var = __traits(getMember, Enum, "Identifier");
```

In a switch statement!

```d
switch(var) {
      case :Identifier:
          break;
}
```

Function calls:

```d
void func(Enum e) {
}

func(:Identifier);
```

Even returns:

```d
Enum func() {
      return :Identifier;
}
```

It does not support binary expressions:

```d
int var = :max - 2; // Error
```
Sep 11
next sibling parent Dukc <ajieskola gmail.com> writes:
On Wednesday, 11 September 2024 at 11:08:18 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 The member of operator is a unified method for acquiring a 
 member
 of a context.

 [snip]
I like this as a whole. However, I'm unsure if prefix `:` is the best choice for implicit context operator. I can't immediately say no, but would like to see a bit of discussion whether there are better alternatives.
Sep 12
prev sibling next sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Wednesday, 11 September 2024 at 11:08:18 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 The member of operator is a unified method for acquiring a 
 member
 of a context.

 It rewrites into ``context.Identifier`` from ``:Identifier``.
It's used very common this sign (colon ```:```) wouldn't cause confusion or pending trouble? In fact The symbol in draft resembles the assignment operator in J language. The : symbol is used in both switches (to the right of the ```case```) and enums. The ```: symbol``` in enums is typically used to specify the underlying data type of the enum. This determines the data type in which the enum constants will be stored. For example, you can have an enum based on int, byte, short, or string. For instance in D, we can use the ```: symbol``` when defining an enum like this: ```d enum Days : byte { Sunday = 1 , Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } ``` In this case, using enums on the left and right means mental confusion. Similarly, in cases, on the right and left at the same time... **Last question:** Can we get rid of the parentheses like in the example below? Just like when using ```with(E)``` ```d T mul(uint e = 1, T)(T value) if (e < 3) { static if (e == E.Positive)    {        return 1 * value;    }    else static if (e == E.Superposition)    {        return 2 * value;    }    return 0; } enum E {    Negative, Positive, Superposition } import std.stdio; void main() {   4.mul!(E.Positive).writeln;  //4.mul!:Positive.writeln;   with (E) 4.mul!Superposition.writeln;    4.mul!2.writeln; } ``` SDB 79
Sep 12
next sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Thursday, 12 September 2024 at 18:39:54 UTC, Salih Dincer 
wrote:
 
 ```d
 enum Days : byte
 {
     Sunday = 1 , Monday, Tuesday, Wednesday, Thursday, Friday, 
 Saturday
 }
 ```
So will this save us from with() in this example? Because, attention, there will be colon next to each other: ```d void main() { with (Days)  {    auto days =   [    "Pazar": Sunday,    "Pazartesi": Monday,     "Salı": Tuesday,     "Çarşamba": Wednesday,    "Perşembe": Thursday,    "Cuma": Friday,      "Cumartesi": Saturday    ];    //assert(days["Cuma"] == :Friday);; } } ``` SDB 79
Sep 12
parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 13/09/2024 7:14 AM, Salih Dincer wrote:
 On Thursday, 12 September 2024 at 18:39:54 UTC, Salih Dincer wrote:
 ```d
 enum Days : byte
 {
     Sunday = 1 , Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
 }
 ```
So will this save us from with() in this example? Because, attention, there will be colon next to each other: ```d void main() {   with (Days)   {     auto days =     [       "Pazar": Sunday,       "Pazartesi": Monday,       "Salı": Tuesday,       "Çarşamba": Wednesday,       "Perşembe": Thursday,       "Cuma": Friday,       "Cumartesi": Saturday     ];     //assert(days["Cuma"] == :Friday);;   } } ``` SDB 79
No unfortunately. ``` KeyValuePair: KeyExpression : ValueExpression ``` ValueExpression is not first term, and there is no context. The first term restriction exists to keep the analysis as an easy test. I do not believe Walter would accept anything else due to past comments. It could be lifted in the future.
Sep 13
prev sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 13/09/2024 6:39 AM, Salih Dincer wrote:
 On Wednesday, 11 September 2024 at 11:08:18 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
 The member of operator is a unified method for acquiring a member
 of a context.

 It rewrites into ``context.Identifier`` from ``:Identifier``.
It's used very common this sign (colon ```:```)  wouldn't cause confusion or pending trouble? In fact The symbol in draft resembles the assignment operator in J language. The : symbol is used in both switches (to the right of the ```case```) and enums. The ```: symbol``` in enums is typically used to specify the underlying data type of the enum. This determines the data type in which the enum constants will be stored. For example, you can have an enum based on int, byte, short, or string. For instance in D, we can use the ```: symbol``` when defining an enum like this: ```d enum Days : byte {     Sunday = 1 , Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } ``` In this case, using enums on the left and right means mental confusion. Similarly, in cases, on the right and left at the same time...
See my follow up post, due to first term only, this does not conflict with other language features.
 **Last question:** Can we get rid of the parentheses like in the example 
 below? Just like when using ```with(E)```
 
 ```d
 T mul(uint e = 1, T)(T value) if (e < 3)
 {
      static if (e == E.Positive)
      {
          return 1 * value;
      }
      else static if (e == E.Superposition)
      {
          return 2 * value;
      }
      return 0;
 }
 
 enum E
 {
      Negative, Positive, Superposition
 }
 
 import std.stdio;
 void main()
 {
      4.mul!(E.Positive).writeln;
    //4.mul!:Positive.writeln;
      with (E) 4.mul!Superposition.writeln;
      4.mul!2.writeln;
 }
 ```
 
 SDB 79
The template parameter would need to be of type ``E`` not ``uint`` to provide a context. Its implemented using two tokens ``:`` and ``Identifier``. So knee jerk reaction is no, even if it was supported for templates. Hmm, grammar changes look ok, and I do need it to Type for casting of sumtypes... so maybe this is a good change even if I don't like it. ```diff TemplateSingleArgument: + MemberOfOperator Type: + MemberOfOperator ```
Sep 13
parent reply Salih Dincer <salihdb hotmail.com> writes:
On Friday, 13 September 2024 at 08:41:11 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 Its implemented using two tokens ``:`` and ``Identifier``. So 
 knee jerk reaction is no, even if it was supported for 
 templates.
I didn't know that they were implemented using ```:``` and ```Identifier```. So what is meant by tokens are that one is the Operator (i.e. the colon symbol) and the Identifier (the name of the enum), and the presence or absence of a space between them will not affect anything, right? In fact, this DIP means this: Previously, the r-value ​​was inferred with ```auto```, now they will be inferred with a operator that is already known on the left side. SDB 79
Sep 13
parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 14/09/2024 5:09 AM, Salih Dincer wrote:
 On Friday, 13 September 2024 at 08:41:11 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
 Its implemented using two tokens ``:`` and ``Identifier``. So knee 
 jerk reaction is no, even if it was supported for templates.
I didn't know that they were implemented using ```:``` and ```Identifier```. So what is meant by tokens are that one is the Operator (i.e. the colon symbol) and the Identifier (the name of the enum), and the presence or absence of a space between them will not affect anything, right?
Ah no, together the two tokens form the operator. What makes it an operator is that it rewrites into ``context.Identifier`` from ``:Identifier`` using a context.
 In fact, this DIP means this: Previously, the r-value ​​was inferred 
 with ```auto```, now they will be inferred with a operator that is 
 already known on the left side.
 
 SDB 79
Storage classes like ``auto`` are left alone, they are unchanged and do not support the member of operator. This is purely additive.
Sep 13
prev sibling parent IchorDev <zxinsworld gmail.com> writes:
On Wednesday, 11 September 2024 at 11:08:18 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 This was pushed for by ryuukk, and thanks to IchorDev for doing
 the idea thread to show a strong desire by the community!
So as we all know, I’m already a vocal advocate of this feature. I’d be using it for enums whether or not sumtypes get added, and I think it’s an important convenience/usability feature that a lot of people miss when switching to D from other more modern languages, myself included. I really hope its room for expansion will be fully utilised if it is greenlit:
 Binary expressions are not supported, but they could be done 
 with
 a simple rewrite.
Sep 15