October 08, 2020
On 10/8/20 3:15 PM, Paul Backus wrote:
> On Thursday, 8 October 2020 at 17:55:21 UTC, Steven Schveighoffer wrote:
>>
>> I did getMember already.
> 
> You did getMember for a type, not a variable. getMember for a type evaluates to a symbol, but getMember for a variable evaluates to an expression.

I wrote:

alias foomember = someTInstance.getMember("foo");

with the assumption that someTInstance was an instance of T. I didn't specify it was a runtime variable, but I did intend for that to be the case.

It's not possible to use a template to get an alias to a runtime member, so it would have to be something different that is allowed in typefunctions. But I assume the "alias" type that is inside a typefunction can be able to handle this, as you can *pass in* an alias to a runtime member, you just can't *return* an alias to a runtime member (well, you can, but it doesn't retain it's runtime component).

> 
>> I'm not sure that's 100% true for type functions -- they aren't in there yet.
> 
> In order to do everything that __traits can do, type functions would have to be polymorphic, which is contrary to their design goals.

__traits are a way to introspect what already exist. At least the *traits* part of __traits (not __traits(compiles)). This doesn't mean it's polymorphic necessarily.

I can see for instance, __traits(getMember, x, "foo") returning an alias to the foo member inside a type function. It can't fetch a *usable value* from that alias. So for example, if x.foo is an integer, you can't get at the integer. But you can get at an alias to that member to do further introspection (i.e. check if it has a certain UDA, etc.)

In the land of reification for example, you could have a "getMember" method that uses pre-built information to fetch an alias to the member you are concerned about, which could carry along the type information about that member, and it's offset, and whatever else you need to then `dereify` the result.

__traits are like a window into the compiler's already-existing type information system. I can't see why we couldn't allow access to those things for type functions.

-Steve
October 08, 2020
On 10/8/20 8:23 PM, Steven Schveighoffer wrote:
> as you can *pass in* an alias to a runtime member, you just can't *return* an alias to a runtime member

Ugh, actually, you can only pass in an alias to a variable. Why you can't pass in an alias to a member doesn't make a lot of sense to me.

But still, the compiler should be able to handle this.

-Steve
October 09, 2020
On 10/8/2020 2:38 AM, Jacob Carlborg wrote:
> Oh, god, no. We already have way too many special magic members. We don't need any more. `__traits` is great because it has it's own namespace. It occupies just one keyword and you can add all the identifiers in the world without the risk of breaking existing code.

Exactly right. It's also there to avoid the need for inventing special syntax for all the weird things it does.
October 09, 2020
On 10/8/2020 7:04 AM, Steven Schveighoffer wrote:
> It's literally special cased in the code:
> 
> https://github.com/dlang/dmd/blob/013eccaf113e6f23784c615d3ec66434c3629197/src/dmd/expressionsem.d#L5418 

Good point. Remove the `is` version.
October 09, 2020
On 10/8/2020 7:19 AM, Steven Schveighoffer wrote:
> I think the AliasSeq pattern still runs through the template machinery, which is not a good thing. But perhaps this can be addressed orthogonally.

Nah, it short-circuits that machinery. Recognizing the AliasSeq pattern and doing it directly was a huge win.

We can do the same as necessary for __traits if it comes to that.
October 10, 2020
On Saturday, 10 October 2020 at 00:16:32 UTC, Walter Bright wrote:
> On 10/8/2020 7:19 AM, Steven Schveighoffer wrote:
>> I think the AliasSeq pattern still runs through the template machinery, which is not a good thing. But perhaps this can be addressed orthogonally.
>
> Nah, it short-circuits that machinery. Recognizing the AliasSeq pattern and doing it directly was a huge win.
>
> We can do the same as necessary for __traits if it comes to that.

It was not a huge win.

In certain circumstances it won.
On others it lost.

Bypassing the cache is not good.
October 10, 2020
On Saturday, 10 October 2020 at 00:13:15 UTC, Walter Bright wrote:
> On 10/8/2020 7:04 AM, Steven Schveighoffer wrote:
>> It's literally special cased in the code:
>> 
>> https://github.com/dlang/dmd/blob/013eccaf113e6f23784c615d3ec66434c3629197/src/dmd/expressionsem.d#L5418
>
> Good point. Remove the `is` version.

I agree.
October 11, 2020
On Thursday, 8 October 2020 at 12:43:48 UTC, RazvanN wrote:
> Therefore, in this case I suggest that we deprecate `is(S == module)`

We could just ghost it. Deprecation would be fine except people tend to remove deprecated things after a while, breaking legacy code.

> (since a module is not a type anyway)

Absolutely, it is very jarring if a conceptual feature is broken like this.

>> is ( Type == TypeSpecialization )

A module/package clearly isn't a type, so either the docs are wrong or is(mod == module) is wrong. All the other keywords are types, as the design intended:

>> If TypeSpecialization is one of struct union class interface enum function delegate const immutable shared module package then the condition is satisfied if Type is one of those.

> and implement an isModule template in std.traits.

Don't template wrappers create bloat when instantiated? For a module name, probably not important. But the principle of wrapping every __traits might not scale well.
October 11, 2020
On Thursday, 8 October 2020 at 13:04:18 UTC, Stefan Koch wrote:
> On Thursday, 8 October 2020 at 12:54:49 UTC, Adam D. Ruppe wrote:
>> I kinda wish we had a template lambda.
>
> you mean alias compiles (__top A) = ((__top x) => __traits(compiles, x)(A); ?

Not sure what __top is, but the compiles trait is special in that it can't be wrapped in a template (it's not really a trait of a symbol or expression like its type, but a deeper semantic analysis of an expression).

'Template lambda' is really anonymous templates:
enum(alias Sym) => __traits(isModule, Sym)
October 11, 2020
On Sunday, 11 October 2020 at 11:30:00 UTC, Nick Treleaven wrote:
> On Thursday, 8 October 2020 at 13:04:18 UTC, Stefan Koch wrote:
>> On Thursday, 8 October 2020 at 12:54:49 UTC, Adam D. Ruppe wrote:
>>> I kinda wish we had a template lambda.
>>
>> you mean alias compiles (__top A) = ((__top x) => __traits(compiles, x)(A); ?
>
> Not sure what __top is, but the compiles trait is special in that it can't be wrapped in a template (it's not really a trait of a symbol or expression like its type, but a deeper semantic analysis of an expression).
>
> 'Template lambda' is really anonymous templates:
> enum(alias Sym) => __traits(isModule, Sym)

__top is the top type.
that which can hold anything.
symbols, complete expressions, types, values, tuples.
anything.