Alternative Possibility - Implicit with

Walter Bright newshound2 at digitalmars.com
Sat Nov 19 08:49:31 UTC 2022


The contextual inference only takes place in certain contexts. Perhaps we can 
run with that idea. Let's take case statements:

   enum WordLetterOfTheDay{ a,b,c,d/*...*/ }

   void main(){
     auto letterToday = WordLetterOfTheDay.b;

     import std.stdio;
     switch(letterToday){
         case $a:
             writeln("Apple");
             break;
         case $b:
             writeln("Bicycle");
             break;
         case $c:
             writeln("Caterpillar");
             break;
         case $d:
             writeln("Didgeridoo");
             break;
         /*...*/
     }
   }

and recognize that the SwitchExpression is of type WordLetterOfTheDay. 
Implicitly enclose the switch body with a `with (WordLetterOfTheDay)` resulting in:

   enum WordLetterOfTheDay{ a,b,c,d/*...*/ }

   void main(){
     auto letterToday = WordLetterOfTheDay.b;

     import std.stdio;
     switch(letterToday){
         case a:
             writeln("Apple");
             break;
         case b:
             writeln("Bicycle");
             break;
         case c:
             writeln("Caterpillar");
             break;
         case d:
             writeln("Didgeridoo");
             break;
         /*...*/
     }
   }

Note the disappearance of the `$`, and use of the leading `.` operator retains 
its existing meaning.

Applying the same to Initializers and assignments:

   enum A{ a,b,c,d }

   struct S{ A one, two; }

   void main(){
     A    myA1 = b;      // myA1 = A.b
     A    myA2 = b | c;  // myA2 = A.c
     auto myA3 = b;      // error, b is undefined

     S myS;
     myS.one = c; // myB.one = A.c
     myS.two = d; // myB.two = A.d
   }

To Return statements:

   enum A{ a,b,c,d }

   A myFn(){
     return c; //returns A.c
   }

   auto myBrokenFn(){
     return c; // error, c is undefined
   }

Argument lists:

   Only works if there are no overloads.

Array literals:

   enum A{ a,b,c,d }

   // (A)
   A[4] x = [a, b, c, d];
   // (B)
   auto y = [A.a, b, c, d]; // error, b is undefined
   auto z = [A.c, 64, b, b]; // error, b is undefined

Now, suppose instead you write:

   enum A{ a,b,c,d }

   A b = c;
   A[4] x = [a, b, c, d];

Is the `b` A.b or A.c? A.b since the `with` has a narrower scope than the local 
`b`. If the user wants the local `b`, he will need to rename it.

Advantages of this scheme:

1. doesn't need the special `$` which people don't seem to like, and using `.` 
conflicts with existing use

2. makes use of the already present `with` semantics

3. seems to have a natural feel to it




More information about the Digitalmars-d mailing list