www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 4427] New: __traits should have isFunction, isVariable, etc

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427

           Summary: __traits should have isFunction, isVariable, etc
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: jmdavisProg gmail.com



18:59:56 PDT ---
At present, __traits has some nice stuff that will let you check things like
whether a function is abstract, or whether something is of an integral type. It
will even let you get all of the member functions and variables of a class.
However, there is no way at present (as far as I can tell) to determine whether
something is a function or a variable. There isn't a way to determine if
something is a type either, let alone whether it's a class, struct, array, or
scalar type. Most of what's there seems to be to ask about the attributes of a
particular expression, variable, or type rather than telling you what it _is_.
In particular, I think that we need these __traits:

isArray
isClass
isFunction
isStruct
isType
isVariable

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 04 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427


Simen Kjaeraas <simen.kjaras gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |simen.kjaras gmail.com



PDT ---
 isArray
std.traits has isArray
 isClass
This is easily done with is( T == class ).
 isFunction
This is easily done with is( T == function ).
 isStruct
This is easily done with is( T == struct ).
 isType
is( T )?
 isVariable
(!is( T ) && is( typeof( T )))? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 05 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427




18:12:14 PDT ---
Good points, though would == function check when it was a function pointer
rather than a function? In either case, I think that you should be able to
check these in a consistent manner, which you can't do right now. With things
spread out between built-in constructs, __traits, and std.traits, it can be a
bit of a mess to figure out how to do something with compile-time reflection.
Even if something like isType were simply translated to is(T), I think that
having it would still be quite valuable since it would make the various
compile-time reflection facilities more consistent and uniform.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 05 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427




PDT ---
I agree. Many of these could easily be turned into templates in std.traits, and
perhaps they should.


template isClass( T ) {
    enum isClass = is( T == class );
}

unittest {
    interface I {}
    class A {}
    class B( T ) {}
    class C : B!int, I {}
    struct S {}

    static assert( isClass!A );
    static assert( isClass!( B!int ) );
    static assert( isClass!C );
    static assert( !isClass!I );
    static assert( !isClass!S );
    static assert( !isClass!int );
    static assert( !isClass!( int* ) );
}

template isInterface( T ) {
    enum isInterface = is( T == interface );
}

unittest {
    interface I {}
    class A {}
    class B( T ) {}
    class C : B!int, I {}
    struct S {}

    static assert( !isInterface!A );
    static assert( !isInterface!( B!int ) );
    static assert( !isInterface!C );
    static assert( isInterface!I );
    static assert( !isInterface!S );
    static assert( !isInterface!int );
    static assert( !isInterface!( int* ) );
}

template isStruct( T ) {
    enum isStruct = is( T == struct );
}

unittest {
    interface I {}
    class A {}
    class B( T ) {}
    class C : B!int, I {}
    struct S {}

    static assert( !isStruct!A );
    static assert( !isStruct!( B!int ) );
    static assert( !isStruct!C );
    static assert( !isStruct!I );
    static assert( isStruct!S );
    static assert( !isStruct!int );
    static assert( !isStruct!( int* ) );
}

template isType( T ) {
    enum isType = true;
}

template isType( alias T ) {
    enum isType = false;
}

unittest {
    struct S {
        alias int foo;
    }

    static assert( isType!int );
    static assert( isType!float );
    static assert( isType!string );
    //static assert( isType!S ); // Bugzilla 4431
    static assert( isType!( S.foo ) );
    static assert( !isType!4 );
    static assert( !isType!"Hello world!" );
}

I'm not entirely sure what you want isVariable to do. Does it check if
something can be assigned to (i.e. is variable), or are immutable and const
'variables' also variables?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 06 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427




10:05:58 PDT ---
I would expect that immutable and const variables would still be variables,
just not mutable ones. If you wanted to know whether they were const or
immutable, you could do a separate test for that on top of checking whether
something was a variable, just like you'd do if you wanted to know whether it
were static.

Personally, I've been trying to figure out how to get the list of non-static
member variables out of a class at compile-time, and it's been a bit of a pain.
And for what I'm doing with them, I wouldn't care whether they were immutable
or const.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 06 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427


Jacob Carlborg <doob me.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |doob me.com




 I would expect that immutable and const variables would still be variables,
 just not mutable ones. If you wanted to know whether they were const or
 immutable, you could do a separate test for that on top of checking whether
 something was a variable, just like you'd do if you wanted to know whether it
 were static.
 
 Personally, I've been trying to figure out how to get the list of non-static
 member variables out of a class at compile-time, and it's been a bit of a pain.
 And for what I'm doing with them, I wouldn't care whether they were immutable
 or const.
You can use object.tupleof to get a list of member variables of out a class at compile time. You can also have a look at http://www.dsource.org/projects/orange/browser/orange/util/Reflection.d (look for the templates/functions containing "field") to get some ideas to implement helper templates/functions. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 07 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427


Rob T <alanb ucora.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |alanb ucora.com




 Good points, though would == function check when it was a function pointer
 rather than a function? In either case, I think that you should be able to
 check these in a consistent manner, which you can't do right now. With things
 spread out between built-in constructs, __traits, and std.traits, it can be a
 bit of a mess to figure out how to do something with compile-time reflection.
 Even if something like isType were simply translated to is(T), I think that
 having it would still be quite valuable since it would make the various
 compile-time reflection facilities more consistent and uniform.
I wasted an hour on this very issue because it's not obvious in the least how to do something like isStruct() for a template constraint. I don't mind using is( T == struct ), so long how to do such a thing (and other tests) is documented in an obvious place that someone is going to look at, like in the templates constraint section. That section currently has nothing in it of much help other than showing how to constrain a few basic types. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 16 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427




PST ---
I had forgotten that I created this enhancement request, though I don't know
how valid it is at this point given how powerful is expressions are (though how
to fully use them isn't well enough known).

 I wasted an hour on this very issue because it's not obvious in the least how
 to do something like isStruct() for a template constraint.
 I don't mind using is( T == struct ), so long how to do such a thing (and
 other tests) is documented in an obvious place that someone is going to look 
 at, like in the templates constraint section. That section currently has 
 nothing in it of much help other than showing how to constrain a few basic 
 types.
It's explained in the section on is expressions: http://dlang.org/expression.html#IsExpression However, that documentation is fairly sparse, and given the extreme flexibility and power (and therefore complication) of is expressions, we could really use a solid tutorial on them on the site. Phillippe Segaud has an extension tutorial on templates in general on github though: https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/dtemplates.pdf -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 16 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427





 I had forgotten that I created this enhancement request, though I don't know
 how valid it is at this point given how powerful is expressions are (though how
 to fully use them isn't well enough known).
 
 I wasted an hour on this very issue because it's not obvious in the least how
 to do something like isStruct() for a template constraint.
 I don't mind using is( T == struct ), so long how to do such a thing (and
 other tests) is documented in an obvious place that someone is going to look 
 at, like in the templates constraint section. That section currently has 
 nothing in it of much help other than showing how to constrain a few basic 
 types.
It's explained in the section on is expressions: http://dlang.org/expression.html#IsExpression However, that documentation is fairly sparse, and given the extreme flexibility and power (and therefore complication) of is expressions, we could really use a solid tutorial on them on the site. Phillippe Segaud has an extension tutorial on templates in general on github though: https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/dtemplates.pdf
Thanks for the response! I have no idea how I skipped the section on Expressions, probably because at the time I was too new with D to understand what it was good for. lot's to read up on in there. Looks like it covers everything I can imagine is needed. Yes it seems that with availability of expressions the enhancement request is somewhat redundant, and like you said, making people aware of it may be what's needed most. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 17 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla digitalmars.com



13:40:36 PST ---
 Many of these could easily be turned into templates
The is ==struct and __traits are not really intended to be user-facing. They are intended to be embedded into templates which then can present a simple, straightforward user interface. Sometimes those templates do need to work hard internally to get the information, but being able to is all that's relevant. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 17 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427


Manu <turkeyman gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |turkeyman gmail.com




 Many of these could easily be turned into templates
The is ==struct and __traits are not really intended to be user-facing. They are intended to be embedded into templates which then can present a simple, straightforward user interface. Sometimes those templates do need to work hard internally to get the information, but being able to is all that's relevant.
Well with this in mind, perhaps we can complete the suite of std.traits? There are a lot missing. I'd certainly like to clean up that aspect of my code before I depart, as it's the most confusing and unreadable section by far. Particularly for new-comers who haven't taken the time to wrangle those sorts of problems yet (who I will be leaving it to) :/ -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 24 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich gmail.com



14:30:51 PST ---
I've lost track here, what's left to implement that requires the compiler's
help by exposing a new __trait?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427





 I've lost track here, what's left to implement that requires the compiler's
 help by exposing a new __trait?
I think the __trait's were more or less good now (at least for me personally), and Kenji had a bug/task where he was fleshing out std.traits. I'm not sure where that landed. I copied his example/prototype code locally and used that, not sure if it was ever completed/merged/documented. Sorry, I've been a major advocate for this stuff, and I'm currently AWOL. Back in 2-3 more weeks and I'll start making noise again ;) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 12 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427




11:54:22 PST ---
Jonathan can you give us an updated on what's still missing?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 12 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4427






I would like to see something like isNullable(T) that evaluates to true if the
type value can be assigned a null.

Eg,

struct S { ... }
S* s; 
class C { ... }

isNullable( S ) is false
isNullable( typeof(s) ) is true
isNullable( C ) is true

--rt

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 29 2013