Improvements to switch

Chloé chloekek at use.startmail.com
Sun Apr 28 09:31:40 UTC 2024


On 4/28/24 01:58, Basile B. wrote:
> On Saturday, 27 April 2024 at 14:58:19 UTC, IchorDev wrote:
>> On Tuesday, 16 April 2024 at 16:00:48 UTC, Basile B. wrote:
>>> About this, the main point is rather
>>>
>>> ```d
>>> /*-->*/ const /*<--*/ int myvalue = switch(code) {
>>>     // ...
>>> };
>>> ```
>>>
>>> "ah finally you can define a const var decl that relies on branching" 
>>> (without using the conditional expression...)
>>
>> You can already do that.
>> ```d
>> const string myValue = (){
>>     switch(code){
>>         case 1:    return "what";
>>         case 2, 3: return "ok";
>>         default:   return "no";
>>     }
>> }();
> 
> Sure but the matching AST is unnecessarily complex. A function literal, 
> plenty of return statements, at least 1 capture. Consequently the path 
> borrowed by the compiler is much more complex, it has to do things that 
> would not be done with the expression: return type inference, block 
> exits, etc. Then without optimizations enabled that does not have the 
> equivalent runtime performances.
> 

Specifically promoting switch to an expression would be a wasted 
opportunity to generalize this to other types of statements, such as try 
statements.

Here are some examples in pseudo-D of how that could be useful. In these 
examples, a hypothetical do keyword could prefix any statement and turn 
it into an expression, and a yield statement would provide the result of 
evaluating that expression:

     // no need to (default-)initialize file first
     auto file = do try {
         yield open(path);
     } catch (ErrnoException ex) {
         if (ex.errno == ENOENT)
             return;  // return from caller
         throw ex;
     };
     // use file without catching ErrnoException
     file.write("hello");

Or foreach statements:

     const value = do {
         foreach (item; someOpApplyStruct)
             if (f(item))
                 yield item;
         throw new NotFoundError;
     };

If the do-ed statement would run off the end (as with a non-void 
function lacking a return statement) that would be an error.

Besides initializing variables, another advantage of promoting 
statements to expressions directly instead of through a called lambda is 
that you can have control flow out of the expression into another 
statement, such as by break, continue, or return statements.



More information about the dip.ideas mailing list