www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - IsExpression question

reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
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
Jul 09 2006
parent reply Sean Kelly <sean f4.ca> writes:
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
Jul 09 2006
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
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 ); }

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.
Jul 16 2006
parent Sean Kelly <sean f4.ca> writes:
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 ); }

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
Jul 23 2006