Thread overview
IsExpression question
Jul 09, 2006
Kirk McDonald
Jul 10, 2006
Sean Kelly
Jul 16, 2006
Stewart Gordon
Jul 24, 2006
Sean Kelly
July 09, 2006
Even after writing most of a library founded on the thing, I still don't get something. What exactly is the expression

    is(T == function)

testing? I would expect it to test whether T is a function pointer type (like how "is(T == delegate)" tests whether T is a delegate type), but it doesn't.

[test.d]
import std.stdio;

void func(int i) {
    writefln(i);
}

void main() {
    alias void function(int) FN;
    FN fn = &func;
    static if (is(typeof(*FN) == function))
        writefln("1: It's a function.");
    static if (is(FN == function))
        writefln("2: It's a function.");
    static if (is(typeof(func) == function))
        writefln("3: It's a function.");
    static if (is(typeof(&func) == function))
        writefln("4: It's a function.");
    static if (is(void function(int) == function))
        writefln("5: It's a function.");
    static if (is(void delegate(int) == delegate))
        writefln("6: Well, delegates work.");
}
// EOF

When run, only 1, 3, and 6 are printed.

1 just baffles be. What is that? I'm dereferencing a type? Then I'm taking the type of THAT? Why does that even work?

2 is what I expect to work: I'm testing whether a function pointer type is a function pointer type, right? Wrong.

3 makes sense, I suppose. I'm testing whether a function is a function. Fine.

4 is also sort of strange, though in light of the fact that 2 doesn't work, I wouldn't expect this one to, either.

5 is just 2 without the alias.

6 shows that, yes, delegates work like I expect them to.

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://dsource.org/projects/pyd/wiki
July 10, 2006
Kirk McDonald wrote:
> Even after writing most of a library founded on the thing, I still don't get something. What exactly is the expression
> 
>     is(T == function)
> 
> testing? I would expect it to test whether T is a function pointer type (like how "is(T == delegate)" tests whether T is a delegate type), but it doesn't.

It's testing whether T is a function type, not a function pointer type.  For template code, it's mostly useful in this sort of situation:

template isFunctionType( alias ref ) {
    const bool isFunctionType = is( ref == function );
}

Though it can be used to detect a function pointer type like so:

template isFunctionPointerType( T ) {
    const bool isFunctionPointerType = is( typeof(*T) == function );
}

> 1 just baffles be. What is that? I'm dereferencing a type? Then I'm taking the type of THAT? Why does that even work?

Weird, eh? :-)



Sean
July 16, 2006
Sean Kelly wrote:
> Kirk McDonald wrote:
>> Even after writing most of a library founded on the thing, I still don't get something. What exactly is the expression
>>
>>     is(T == function)
>>
>> testing? I would expect it to test whether T is a function pointer type (like how "is(T == delegate)" tests whether T is a delegate type), but it doesn't.
> 
> It's testing whether T is a function type, not a function pointer type.  For template code, it's mostly useful in this sort of situation:
> 
> template isFunctionType( alias ref ) {
>     const bool isFunctionType = is( ref == function );
> }
> 
> Though it can be used to detect a function pointer type like so:
> 
> template isFunctionPointerType( T ) {
>     const bool isFunctionPointerType = is( typeof(*T) == function );
> }
<snip>

The spec states:

"If TypeSpecialization is one of  typedef  struct  union  class interface enum  function  delegate  then the condition is satisifed if Type is one of those."

However, that doesn't excuse the behaviour of function being inconsistent with the behaviour of delegate.  This would make more sense:

    template isFunctionPointerType(T) {
        const bool isFunctionPointerType = is(T == function);
    }

    template isFunction(alias ref) {
        const bool isFunction = is(typeof(&ref) == function);
    }

But I do wonder what you can really do with a function in a template without knowing at least how many parameters it has.

Indeed, the function as a kind of data type ought not to exist in D.  At the moment, it appears to exist only in the form of IsExpression that you've used.  We have function pointers, indicated by the function keyword, and function delegates, indicated by the delegate keyword.  So whatever is(... == delegate) does, is(... == function) logically ought to act correspondingly.

Stewart.
July 24, 2006
Stewart Gordon wrote:
> Sean Kelly wrote:
>> Kirk McDonald wrote:
>>> Even after writing most of a library founded on the thing, I still don't get something. What exactly is the expression
>>>
>>>     is(T == function)
>>>
>>> testing? I would expect it to test whether T is a function pointer type (like how "is(T == delegate)" tests whether T is a delegate type), but it doesn't.
>>
>> It's testing whether T is a function type, not a function pointer type.  For template code, it's mostly useful in this sort of situation:
>>
>> template isFunctionType( alias ref ) {
>>     const bool isFunctionType = is( ref == function );
>> }
>>
>> Though it can be used to detect a function pointer type like so:
>>
>> template isFunctionPointerType( T ) {
>>     const bool isFunctionPointerType = is( typeof(*T) == function );
>> }
> <snip>
> 
> The spec states:
> 
> "If TypeSpecialization is one of  typedef  struct  union  class interface enum  function  delegate  then the condition is satisifed if Type is one of those."
> 
> However, that doesn't excuse the behaviour of function being inconsistent with the behaviour of delegate.  This would make more sense:
> 
>     template isFunctionPointerType(T) {
>         const bool isFunctionPointerType = is(T == function);
>     }
> 
>     template isFunction(alias ref) {
>         const bool isFunction = is(typeof(&ref) == function);
>     }
> 
> But I do wonder what you can really do with a function in a template without knowing at least how many parameters it has.
> 
> Indeed, the function as a kind of data type ought not to exist in D.  At the moment, it appears to exist only in the form of IsExpression that you've used.  We have function pointers, indicated by the function keyword, and function delegates, indicated by the delegate keyword.  So whatever is(... == delegate) does, is(... == function) logically ought to act correspondingly.

I believe this is also true:

    class C { void fn() {} int val; }

    static if( is( typeof( C.fn ) == function ) )
        pragma( msg, "fn is function" );
    static if( is( typeof( C.val ) == function ) )
        pragma( msg, "val is function" );

Taking the address of C.blah here to test for a function is a bit counter-intuitive, and I suspect could lead to some odd corner-cases.


Sean