November 19, 2022
On Saturday, 19 November 2022 at 12:57:33 UTC, Adam D Ruppe wrote:
> Actually, I do wish `with` in general had a way to refer back to the subject of it. Maybe we could add something there then it'd magically apply to the implicit with too.

Maybe something like this for symbols:

    with (alias me = SomeReallyLongName)

And this for expressions:

    with (auto me = some(complex, ex + pression))

Can be implemented by lowering to a normal block scope:

    {
        alias me = SomeReallyLongName;
        with (me)
        {
            // ...
        }
    }
November 19, 2022

On Saturday, 19 November 2022 at 14:22:16 UTC, Paul Backus wrote:

>

On Saturday, 19 November 2022 at 12:57:33 UTC, Adam D Ruppe wrote:

>

Actually, I do wish with in general had a way to refer back to the subject of it. Maybe we could add something there then it'd magically apply to the implicit with too.

Maybe something like this for symbols:

with (alias me = SomeReallyLongName)

And this for expressions:

with (auto me = some(complex, ex + pression))

Can be implemented by lowering to a normal block scope:

{
    alias me = SomeReallyLongName;
    with (me)
    {
        // ...
    }
}

This + trailing with (a la where)

November 19, 2022

On Friday, 18 November 2022 at 15:37:31 UTC, Mike Parker wrote:

>

Discussion Thread

This is the discussion thread for the first round of Community Review of DIP 1044, "Enum Type Inference":

[half feedback, half random brainstorming, so posting here to be safe]

I would like to suggest the following changes for consideration:

  • Replace the $ Identifier syntax with : Identifier, to match other languages like Ruby and Lisp.

  • The : Identifier syntax creates a value of a dynamic pseudo-type (a bit like typeof(null)).

    • The type's name is typeof(:Identifier).

    • The type has size 0 and holds a single value.

    • The type is implicitly convertible to any enum type which has a member with the same name as Identifier.

I think this is a more precise and immediately implementable definition of the mechanics. Not sure if a good thing or not, but this will also allow using :keywords stand-alone, like in Ruby/Lisp in a congruent manner. For the purposes at hand (enum type inference), it will also allow passing through the short-hand identifier to templated and auto functions.

It will not allow

myFn($a + $a); // passes A.b

to work, but I'm not sure that would be implementable anyway in a reasonable manner and provide justifiable value. I think the remaining examples in the DIP will continue to work.

On another point, since the DIP mentions the with approach, I'll mention that the workaround I've been using is to declare a short local alias for the enum type. At the top level (e.g. for variable/constant initializers), it can be done by wrapping the value in a CTFE function: https://gist.github.com/CyberShadow/54ca7a0fa594c2272cabf8677ff6e42f#file-game-d-L150

November 19, 2022

On Friday, 18 November 2022 at 22:47:19 UTC, bachmeier wrote:

>

On Friday, 18 November 2022 at 21:27:51 UTC, Nick Treleaven wrote:

>

The type name can be omitted for e.g. a function call, but then you can omit the types when passing a function literal to a typed function pointer parameter. Are you against function literal type inference too?

I'm not following.

I'm saying that the type inference works essentially the same as function literal type inference:

enum LongName
{
	a,b,c
}

LongName e;
void function(int) f;

void main()
{
	f = (int i){};
	f = (i){}; // infer parameter type

	e = LongName.a;
	e = $a; // infer parent type
}

Given that inference is simple in both cases, why disallow it in only one?

>

If I pull out the example from the Case statements example and fix it so it runs, I can do this without any changes to the language, but I'll grant that it requires typing one extra character:

import std.stdio: writeln;

enum WordLetterOfTheDay{ a,b,c,d/*...*/ }
alias w=WordLetterOfTheDay;

That alias is a good enough solution for a switch case with multiple case statements. It is however worse than the status quo when doing an assignment to a variable, because then you don't need to write the type again so a single use alias is not helping.

> >

The fact this feature is showing up in other systems languages is evidence it is useful.

Maybe. They're different languages.

Yes, though we have no way to avoid writing the type again for single uses.

November 19, 2022

On Friday, 18 November 2022 at 15:37:31 UTC, Mike Parker wrote:

>

Discussion Thread

The discord is talking allot about alt characters

%, €, 🃏, ?, .

With 🃏 being the best suggestion

November 19, 2022

On Saturday, 19 November 2022 at 17:47:16 UTC, monkyyy wrote:

>

The discord is talking allot about alt characters

%, €, 🃏, ?, .

With 🃏 being the best suggestion

Would it be categorically insane to try to implement this with no punctuation identifier at all?

November 19, 2022
On Saturday, 19 November 2022 at 08:49:31 UTC, Walter Bright wrote:
> The contextual inference only takes place in certain contexts.

I like this.  This is much better than introducing a whole new set of
lookup rules with all sorts of complicated unexpected interactions with
existing lookup behaviour.


> Perhaps we can run with that idea. Let's take case statements:
[...]
> and recognize that the SwitchExpression is of type WordLetterOfTheDay.

Exactly!!!  The type of SwitchExpression already tells you what type the
case labels must be. So there is no need to have to repeat the enum type
name over and over again, for every case label.  Just have the compiler
implicitly convert:

        switch (x) { ... }

to:

        switch (x) with(typeof(x)) { ... }

when x is an enum value, and that solves this particular case.


> 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.

Yes, this is a much better solution.


> 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

+1, this makes sense.


[...]
> To Return statements:
>
>   enum A{ a,b,c,d }
>
>   A myFn(){
>     return c; //returns A.c
>   }
>
>   auto myBrokenFn(){
>     return c; // error, c is undefined
>   }

Also makes sense.


> Argument lists:
>
>   Only works if there are no overloads.

There's another use case to address: default parameter declarations.

Current syntax:

        enum LongEnumName { abc, def, ghi }
        int myFunc(LongEnumName x = LongEnumName.abc) { ... }

Desired syntax:

        enum LongEnumName { abc, def, ghi }
        int myFunc(LongEnumName x = abc) { ... }

i.e., the RHS of a default parameter should be treated just like the
initialization of an enum variable, there should be an implicit `with`.

Also common in my code:

        enum LongEnumName { abc, def, ghi }
        int myFunc(LongEnumName x = LongEnumName.init) { ... }

Desired syntax:

        enum LongEnumName { abc, def, ghi }
        int myFunc(LongEnumName x = init) { ... }


> Array literals:
>
>   enum A{ a,b,c,d }
>
>   // (A)
>   A[4] x = [a, b, c, d];

Nice.


[...]
> 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.

Makes sense.


> 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

Yes, this proposal is much better. Adding the `$` or `.` syntax just
seems to have much farther-reaching consequences and interactions with
existing features than is justifiable for something that's arguably
merely syntactic sugar.  Leveraging the existing `with` construct is a
much less-intrusive, IMO superior approach.


T

--
Questions are the beginning of intelligence, but the fear of God is the beginning of wisdom.

November 19, 2022
On 11/19/2022 10:26 AM, H. S. Teoh wrote:
>> Implicitly enclose the switch body with a `with (WordLetterOfTheDay)`
>> resulting in:

Upon more reflection, the implicit `with` should only enclose the case expression, not the other statements in the switch body.


>> Argument lists:
>>
>>   Only works if there are no overloads.
> 
> There's another use case to address: default parameter declarations.
> 
> Current syntax:
> 
>          enum LongEnumName { abc, def, ghi }
>          int myFunc(LongEnumName x = LongEnumName.abc) { ... }
> 
> Desired syntax:
> 
>          enum LongEnumName { abc, def, ghi }
>          int myFunc(LongEnumName x = abc) { ... }
> 
> i.e., the RHS of a default parameter should be treated just like the
> initialization of an enum variable, there should be an implicit `with`.

Yes, should work the same as other initializations.

November 19, 2022
On 11/19/2022 9:56 AM, cc wrote:
> Would it be categorically insane to try to implement this with no punctuation identifier at all?

Insane:

https://www.digitalmars.com/d/archives/digitalmars/D/Discussion_Thread_DIP_1044--Enum_Type_Inference--Community_Review_365880.html#N365938
November 20, 2022
On Saturday, 19 November 2022 at 08:49:31 UTC, Walter Bright wrote:

> 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

Looks much better to me. The number one reason for me is that it does not add tons of complexity/readability issues for new users.