October 07, 2020
On Wednesday, 7 October 2020 at 20:01:53 UTC, Steven Schveighoffer wrote:
> If you want to determine if a given symbol is a module. Is there another way?

A module symbol should *only* be given through means specific to modules. Which means the code knows it is dealing with a module without any introspection.

So like __traits(getImports) would ONLY return modules. __traits(allMembers) would NEVER return modules.

That said I guess I can see the point for completeness' sake to make __traits(isModule, mixin(__MODULE__)) return true.... but I don't see why you'd ever use that since it would be obvious in the code itself.

Perhaps useful if you get an aliased module though.

> Yeah, that's a problem we should fix. There was an almost-released fix which made __traits(allMembers, mod) return the full name of the modules, which I don't think was right either.

That would be slightly less bad than it is now (a module should ALWAYS be referred to by its full name) but it is still the wrong place to put it.

D modules do not have parents. They may be associated with a package, but the package is not its parent in the strict sense since you can compile them independently.

> Not sure what this was supposed to mean.


Check this out:

```
module wtf.useless;

static if(is(wtf.useless MOD == module))
static if(is(__traits(parent, wtf.useless) PKG == package))
        static assert(0); // NOT TRIGGERED!
```

Yet:

// this prints "package wtf"
pragma(msg, __traits(parent, wtf.useless).stringof);


And:

module wtf.useless;

pragma(msg, wtf.stringof); // works


Yet:

static if(is(wtf.useless MOD == module))
static if(is(wtf PKG == module))
        static assert(0);

Error: module wtf.useless from file wtf.d must be imported with 'import wtf.useless;'

(notice no line number either)

Unless you make wtf/package.d. Then it thinks it is a module instead of a package.


Oh and check this out:

pragma(msg, wtf.useless.stringof); // module useless


Good luck `import useless;`. Obviously won't work. It is right now *impossible* to get a module name back in the general case.

tbh, I don't even know what dmd is doing here. There seems to be no logic to it whatsoever.

If the language is going to pretend modules are children of packages (which they aren't and it shouldn't!!!!!), it should at least do so consistently. As it sits now, stuff that was possible a couple versions ago is now just hopelessly broken now.
October 07, 2020
On Wednesday, 7 October 2020 at 20:19:57 UTC, Paul Backus wrote:
> Couldn't you unconditionally lower <Node>.__isModule to __traits(isModule, <Node>) regardless of what type of node it is, and rely on the existing error messages for incorrect trait arguments? You don't have to worry about shadowing "real" properties, because anything that starts with "__" is a reserved identifier.

struct Wrapper(alias sym)
{
    import std.format: format;

    template opDispatch(string name, Args...)
    //Not DRY, probably a better way to do this
    if (__traits(compiles, mixin(`__traits(%s, sym, Args)`.format(name))))
    {
        enum opDispatch = mixin(`__traits(%s, sym, Args)`.format(name));
    }
}

void main()
{
	import std.stdio;

    writeln(Wrapper!(std).isPackage);
}
October 07, 2020
On Wednesday, 7 October 2020 at 20:37:47 UTC, Meta wrote:
> On Wednesday, 7 October 2020 at 20:19:57 UTC, Paul Backus wrote:
>> Couldn't you unconditionally lower <Node>.__isModule to __traits(isModule, <Node>) regardless of what type of node it is, and rely on the existing error messages for incorrect trait arguments? You don't have to worry about shadowing "real" properties, because anything that starts with "__" is a reserved identifier.

>     if (__traits(compiles, mixin(`__traits(%s, sym, Args)`.format(name))))
>     {
>         enum opDispatch = mixin(`__traits(%s, sym, Args)`.format(name));
>     }
> }


As a little side notion.
Avoid the use of std.format.format at CTFE.
It's very expensive.
And please cache the string :)
October 07, 2020
On Wednesday, 7 October 2020 at 20:41:19 UTC, Stefan Koch wrote:
> On Wednesday, 7 October 2020 at 20:37:47 UTC, Meta wrote:
>> On Wednesday, 7 October 2020 at 20:19:57 UTC, Paul Backus wrote:
>>> Couldn't you unconditionally lower <Node>.__isModule to __traits(isModule, <Node>) regardless of what type of node it is, and rely on the existing error messages for incorrect trait arguments? You don't have to worry about shadowing "real" properties, because anything that starts with "__" is a reserved identifier.
>
>>     if (__traits(compiles, mixin(`__traits(%s, sym, Args)`.format(name))))
>>     {
>>         enum opDispatch = mixin(`__traits(%s, sym, Args)`.format(name));
>>     }
>> }
>
>
> As a little side notion.
> Avoid the use of std.format.format at CTFE.
> It's very expensive.
> And please cache the string :)

I'm hoping and praying for a string interpolation dip that gets accepted.
October 07, 2020
On Wednesday, 7 October 2020 at 20:37:47 UTC, Meta wrote:
> On Wednesday, 7 October 2020 at 20:19:57 UTC, Paul Backus wrote:
>> Couldn't you unconditionally lower <Node>.__isModule to __traits(isModule, <Node>) regardless of what type of node it is, and rely on the existing error messages for incorrect trait arguments? You don't have to worry about shadowing "real" properties, because anything that starts with "__" is a reserved identifier.
>
> struct Wrapper(alias sym)
> {
>     import std.format: format;
>
>     template opDispatch(string name, Args...)
>     //Not DRY, probably a better way to do this
>     if (__traits(compiles, mixin(`__traits(%s, sym, Args)`.format(name))))
>     {
>         enum opDispatch = mixin(`__traits(%s, sym, Args)`.format(name));
>     }
> }
>
> void main()
> {
> 	import std.stdio;
>
>     writeln(Wrapper!(std).isPackage);
> }

Clever. Now try this:

    writeln(Wrapper!("hello" + 1).compiles);

Or this:

    struct S { int x; }
    int n = 123;
    writeln(Wrapper!(S(n)).getMember!"x");

Or this:

    struct S { in x, y; }
    writeln(Wrapper!S.allMembers);

The problem with using templates to wrap __traits is that __traits can do things that templates aren't allowed to do, like take expressions as arguments, or evaluate to expressions rather than symbols or constants.
October 07, 2020
On Wednesday, 7 October 2020 at 20:58:21 UTC, Paul Backus wrote:

> Clever. Now try this:
>
>     writeln(Wrapper!("hello" + 1).compiles);
>
> Or this:
>
>     struct S { int x; }
>     int n = 123;
>     writeln(Wrapper!(S(n)).getMember!"x");
>
> Or this:
>
>     struct S { in x, y; }
>     writeln(Wrapper!S.allMembers);
>
> The problem with using templates to wrap __traits is that __traits can do things that templates aren't allowed to do, like take expressions as arguments, or evaluate to expressions rather than symbols or constants.

Hmm seeing this written out I have to say ...
It does look neat ....

If you submit a DIP I can implement it for you.
It only looks neat without the underscores though :)
October 07, 2020
I'm not sure which is the one to go, but we should not have both.
October 07, 2020
On Wednesday, 7 October 2020 at 23:17:18 UTC, Walter Bright wrote:
> I'm not sure which is the one to go, but we should not have both.

I agree.

Removing the either now would be a breaking change though ...

Which version is used more often?
October 07, 2020
On Wed, Oct 07, 2020 at 11:37:06PM +0000, Stefan Koch via Digitalmars-d wrote:
> On Wednesday, 7 October 2020 at 23:17:18 UTC, Walter Bright wrote:
> > I'm not sure which is the one to go, but we should not have both.
> 
> I agree.
> 
> Removing the either now would be a breaking change though ...

We could go through the deprecation process...?


> Which version is used more often?

Maybe grep through the most popular code.dlang.org repos?


T

-- 
Государство делает вид, что платит нам зарплату, а мы делаем вид, что работаем.
October 08, 2020
On Wednesday, 7 October 2020 at 21:01:28 UTC, Stefan Koch wrote:
> On Wednesday, 7 October 2020 at 20:58:21 UTC, Paul Backus wrote:
>
>> Clever. Now try this:
>>
>>     writeln(Wrapper!("hello" + 1).compiles);
>>
>> Or this:
>>
>>     struct S { int x; }
>>     int n = 123;
>>     writeln(Wrapper!(S(n)).getMember!"x");
>>
>> Or this:
>>
>>     struct S { in x, y; }
>>     writeln(Wrapper!S.allMembers);
>>
>> The problem with using templates to wrap __traits is that __traits can do things that templates aren't allowed to do, like take expressions as arguments, or evaluate to expressions rather than symbols or constants.
>
> Hmm seeing this written out I have to say ...
> It does look neat ....
>
> If you submit a DIP I can implement it for you.
> It only looks neat without the underscores though :)

Agree about the underscores. Would be splendid is it was possible. Dunno how you would fix naming issues though, like is someone has a function already named some trait