October 23
On Wed, Oct 23, 2024 at 06:10:07PM +0000, Anton Pastukhov via Digitalmars-d-learn wrote:
> On Wednesday, 23 October 2024 at 18:05:15 UTC, monkyyy wrote:
> > 
> > Its intended and probably the right decision, but good luck finding relivent docs.
> 
> What's the motivation behind it? For me, it looks like a weird edge case but I'm just probably missing something here

The key here is to understand that "alias" != "macro".  If you're looking for a way to shorten long expressions, `alias` is not what you're looking for.


T

-- 
Shin: (n.) A device for finding furniture in the dark.
October 23
On Wednesday, October 23, 2024 11:18:47 AM MDT Anton Pastukhov via Digitalmars-d-learn wrote:
> On Wednesday, 23 October 2024 at 14:50:44 UTC, Paul Backus wrote:
> > On Wednesday, 23 October 2024 at 12:46:24 UTC, Paul Backus wrote:
> >
> > You can't use an `alias` to refer to a member variable like this. When you write
> >
> >     alias myAlias = myStruct.test;
> >
> > ...it is silently rewritten by the compiler to
> >
> >     alias myAlias = MyStruct.test;
> >
> > So, in reality, there is no difference between the two versions.
>
> Is it intended behavior? Is it documented somewhere? I'm looking here https://dlang.org/spec/declaration.html#alias and it states: "An AliasDeclaration creates a symbol name that refers to a type or another symbol". `myStruct.test` is a symbol.

It aliases the symbol, but a member function does you no good without an object to go with it. For the alias of a member function to actually be properly callable, it would need more than just the symbol. It would actually need to reference the object itself in some fashion, and that's simply not how aliases work. All they really do is provide an alternate name for a symbol.

Really, it should probably just be illegal to alias a member function from a variable rather than the type, because the fact that it's allowed and then treated like it's an alias from the type causes confusion like you're experiencing. However, it's likely allowed for similar reasons to why it's legal to call static member functions on an instance rather than requiring that they be called on the type (which I'm inclined to argue was a bad design decision, but it's what we have).

- Jonathan M Davis



October 23
On Wednesday, 23 October 2024 at 19:10:05 UTC, Jonathan M Davis wrote:
> On Wednesday, October 23, 2024 11:18:47 AM MDT Anton Pastukhov via Digitalmars-d-learn wrote:
>> On Wednesday, 23 October 2024 at 14:50:44 UTC, Paul Backus wrote:
>> > On Wednesday, 23 October 2024 at 12:46:24 UTC, Paul Backus wrote:
>> >
>> > You can't use an `alias` to refer to a member variable like this. When you write
>> >
>> >     alias myAlias = myStruct.test;
>> >
>> > ...it is silently rewritten by the compiler to
>> >
>> >     alias myAlias = MyStruct.test;
>> >
>> > So, in reality, there is no difference between the two versions.
>>
>> Is it intended behavior? Is it documented somewhere? I'm looking here https://dlang.org/spec/declaration.html#alias and it states: "An AliasDeclaration creates a symbol name that refers to a type or another symbol". `myStruct.test` is a symbol.
>
> It aliases the symbol, but a member function does you no good without an object to go with it. For the alias of a member function to actually be properly callable, it would need more than just the symbol. It would actually need to reference the object itself in some fashion, and that's simply not how aliases work. All they really do is provide an alternate name for a symbol.
>
> Really, it should probably just be illegal to alias a member function from a variable rather than the type, because the fact that it's allowed and then treated like it's an alias from the type causes confusion like you're experiencing. However, it's likely allowed for similar reasons to why it's legal to call static member functions on an instance rather than requiring that they be called on the type (which I'm inclined to argue was a bad design decision, but it's what we have).
>
> - Jonathan M Davis

Thanks for the clarification. I understand that aliasing a delegate would be problematic because it's context-aware. In my case, however, I'm aliasing not a delegate and not even a free function, I'm aliasing a struct field of enum type, which holds no references to the context. In my book it should be perfectly ok and inability to do so looks like a bug for me. Other participants mentioned that there is some rationale behind that design, so I'm just trying to understand it before heading to Bugzilla

October 23
On Wednesday, 23 October 2024 at 18:39:15 UTC, H. S. Teoh wrote:
> On Wed, Oct 23, 2024 at 06:10:07PM +0000, Anton Pastukhov via Digitalmars-d-learn wrote:
>> On Wednesday, 23 October 2024 at 18:05:15 UTC, monkyyy wrote:
>> > 
>> > Its intended and probably the right decision, but good luck finding relivent docs.
>> 
>> What's the motivation behind it? For me, it looks like a weird edge case but I'm just probably missing something here
>
> The key here is to understand that "alias" != "macro".  If you're looking for a way to shorten long expressions, `alias` is not what you're looking for.
>
>
> T

Well, I'm looking at Ali's book http://ddili.org/ders/d.en/alias.html and it states that, among other things, aliases are used to shorten long expressions. Not sure how authoritative it is tho
October 23

On Wednesday, 23 October 2024 at 17:18:47 UTC, Anton Pastukhov wrote:

>

On Wednesday, 23 October 2024 at 14:50:44 UTC, Paul Backus wrote:

>

You can't use an alias to refer to a member variable like this. When you write

alias myAlias = myStruct.test;

...it is silently rewritten by the compiler to

alias myAlias = MyStruct.test;

So, in reality, there is no difference between the two versions.

Is it intended behavior? Is it documented somewhere? I'm looking here https://dlang.org/spec/declaration.html#alias and it states: "An AliasDeclaration creates a symbol name that refers to a type or another symbol". myStruct.test is a symbol.

Yes, it's intended.

A "symbol" in D means a named entity declared in the program's source code. While every instance of MyStruct has its own copy of the test member variable, there is only one declaration of MyStruct.test--and thus, only one symbol.

In this case, instead of an alias, you can use a local function:

MyStruct myStruct;
auto getTest() { return myStruct.test; }
auto idx = countUntil!(e => e == getTest())(...);
October 24

On Wednesday, 23 October 2024 at 15:25:48 UTC, Salih Dincer wrote:

>

If it were me, I would equip my type with aliases like below. But for some reason I don't understand, the enum Numbers works, while the enum Test which is of type string doesn't!

I figured out why it wasn't working. It turns out I had made a size_t comparison with a string. In this case, it's smart to move away from string altogether and use alias fun(S). Here's D's perfect syntax:

struct Zoo(size_t i)
{
  size_t count;
  static index = i;
}

void main()
{
  enum Animal { dog = 3, cow, fox, cat }

  Animal[] animals;
  with(Animal) animals = [dog, cow, fox, cat];

  alias myType = Zoo!(Animal.fox);
  alias fun(S) = e => e == S.index;

  import std.algorithm : countUntil;
  auto myStruct = myType(
    animals.countUntil!(fun!myType)
  );

  assert(myStruct.index == 5);
  assert(myStruct.count == 2);

  import std.stdio;
  myStruct.writeln(": ", animals);
  // Zoo!5LU(2): [dog, cow, fox, cat]
}

SDB@79

October 24
On Wednesday, 23 October 2024 at 18:39:15 UTC, H. S. Teoh wrote:
> The key here is to understand that "alias" != "macro".

Re-reading this topic today and indeed that was the missing piece. I was sure that alias is just a compile-time string replacement akin to C macros, just with some niceties such as type checking.

Thanks to everyone commenting in this topic. For my initial question, I just ditched aliases and use full names instead. The underlying issue was my misunderstanding of the meaning of `symbol` as independently-addressable entity, and another misunderstanding of how `alias` works in D (and the fact that it's actually not just a macro).
1 2
Next ›   Last »