OK... So far I'm liking this IsExpression thing, but either I'm hitting
a limitation, or I'm not using it right. I basically want to determine
if a method exists for a variable. I want the following snippet to
print "hash", while it currently prints "nohash":
Object o = new Object;
static if( is(o.toHash()) ) {
writefln("hash");
} else {
writefln("nohash");
}
This is in a template, so I can use the type instead of the instance, if
needed. Is there any way for me to do this? If there isn't currently,
can it be added? It'd be really, really useful. And cool. BTW, except
for this issue I'm really liking this new addition. Props to Walter.
Thanks
John Demme

John Demme wrote:
> OK... So far I'm liking this IsExpression thing, but either I'm hitting
> a limitation, or I'm not using it right. I basically want to determine
> if a method exists for a variable. I want the following snippet to
> print "hash", while it currently prints "nohash":
> Object o = new Object;
> static if( is(o.toHash()) ) {
<snip>
It would appear to be a bug that this complies - it isn't among the listed forms of IsExpression.
I don't know if there's a way to do it, but I guess it wouldn't be this - it looks related to the _evaluation_ of o.toHash rather than the function itself.
I'm guessing that something like this would work
static if (is(typeof(&o.toHash) : T delegate())) { ... }
but it might not work if the function name is overloaded, depending on how the compiler resolves the typeof. OTOH something like this might work:
uint delegate() dummy;
static if (is(typeof(dummy = &o.toHash))) { ... }
But yes, there ought to be a clear way of doing this. Maybe when I'm in a position to experiment....
Stewart.
--
My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.

John Demme wrote:
> OK... So far I'm liking this IsExpression thing, but either I'm hitting
> a limitation, or I'm not using it right. I basically want to determine
> if a method exists for a variable.
<snip>
This code tests for the presence of a method having the given signature.
The dummy delegate is needed to disambiguate between overloadings.
----------
import std.stdio;
class Qwert {
void yuiop(int asdfg) {}
int yuiop() { return 0; }
}
void main() {
Qwert hjkl;
//void delegate(int) zxcvb;
//real delegate(char[]) zxcvb;
int delegate() zxcvb;
static if (is(typeof(zxcvb = &hjkl.yuiop))) {
writefln("yes");
} else {
writefln("no");
}
}
----------
OTOH, if you merely want to test for the presence of a method with a given name without caring about its signature (don't ask me why you'd want to do this),
static if (is(typeof(&hjkl.yuiop)))
is adequate.
Stewart.
--
My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.

"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message news:d98uen$2tg1$1@digitaldaemon.com...> John Demme wrote:
> > OK... So far I'm liking this IsExpression thing, but either I'm hitting
> > a limitation, or I'm not using it right. I basically want to determine
> > if a method exists for a variable. I want the following snippet to
> > print "hash", while it currently prints "nohash":
> > Object o = new Object;
> > static if( is(o.toHash()) ) {
> <snip>
>> It would appear to be a bug that this complies - it isn't among the listed forms of IsExpression.
It's a feature, not a bug <g>. The feature is that if the type inside the is( ) parentheses fails to compile *for whatever reason* then the IsExpression result is false.
In this case, o.toHash() is not a type, so it fails to compile, and
IsExpression returns false.
This capability can be manipulated in diverse ways to test for the existence of methods, members, the types of them, etc.

On Thu, 23 Jun 2005 22:30:10 -0700, Walter wrote:
> "Stewart Gordon" <smjg_1998@yahoo.com> wrote in message news:d98uen$2tg1$1@digitaldaemon.com...>> John Demme wrote:
>>> OK... So far I'm liking this IsExpression thing, but either I'm hitting
>>> a limitation, or I'm not using it right. I basically want to determine
>>> if a method exists for a variable. I want the following snippet to
>>> print "hash", while it currently prints "nohash":
>>> Object o = new Object;
>>> static if( is(o.toHash()) ) {
>> <snip>
>>>> It would appear to be a bug that this complies - it isn't among the listed forms of IsExpression.
> > It's a feature, not a bug <g>. The feature is that if the type inside the is( ) parentheses fails to compile *for whatever reason* then the IsExpression result is false.
> > In this case, o.toHash() is not a type, so it fails to compile, and
> IsExpression returns false.
> > This capability can be manipulated in diverse ways to test for the existence of methods, members, the types of them, etc.
Can you supply an example of how to test for the existence of ...
... a module function
... a module variable
... a class member
... a struct member
... a class declaration
... a struct declaration
... a module importation
... a function member
--
Derek
Melbourne, Australia
24/06/2005 3:40:32 PM

"Derek Parnell" <derek@psych.ward> wrote in message news:w3vzckxoa968.nxmmy66f775t$.dlg@40tude.net...> > This capability can be manipulated in diverse ways to test for the
existence
> > of methods, members, the types of them, etc.
>> Can you supply an example of how to test for the existence of ...
>> ... a module function
> ... a module variable
> ... a class member
> ... a struct member
> ... a class declaration
> ... a struct declaration
> ... a module importation
> ... a function member
In general, the idea is to construct an expression which will fail to compile if it is *not* one of the above. For example, to test for the existence of member 'm' of struct 'S':
static if ( is(typeof(S.m)) )
...

On Fri, 24 Jun 2005 00:09:21 -0700, Walter wrote:
> "Derek Parnell" <derek@psych.ward> wrote in message news:w3vzckxoa968.nxmmy66f775t$.dlg@40tude.net...>>> This capability can be manipulated in diverse ways to test for the
> existence
>>> of methods, members, the types of them, etc.
>>>> Can you supply an example of how to test for the existence of ...
>>>> ... a module function
>> ... a module variable
>> ... a class member
>> ... a struct member
>> ... a class declaration
>> ... a struct declaration
>> ... a module importation
>> ... a function member
> > In general, the idea is to construct an expression which will fail to compile if it is *not* one of the above. For example, to test for the existence of member 'm' of struct 'S':
> > static if ( is(typeof(S.m)) )
> ...
But that is exactly what I'd like to prevent! In other words I'd like to do this sort of thing ...
static_if (! exists(S.m))
{
// declare 'm'
}
--
Derek
Melbourne, Australia
24/06/2005 5:21:06 PM

Walter wrote:
> "Stewart Gordon" <smjg_1998@yahoo.com> wrote in message
> news:d98uen$2tg1$1@digitaldaemon.com...<snip>
>>It would appear to be a bug that this complies - it isn't among the
>>listed forms of IsExpression.
> > It's a feature, not a bug <g>. The feature is that if the type inside the
> is( ) parentheses fails to compile *for whatever reason* then the
> IsExpression result is false.
For whatever reason? Then
static if (is(/.,mnbv\][)) { ... }
should compile?
> In this case, o.toHash() is not a type, so it fails to compile, and
> IsExpression returns false.
You tell us that the IsExpression must be syntactically valid regardless.
IsExpression:
is ( Type )
is ( Type : TypeSpecialization )
is ( Type == TypeSpecialization )
is ( Type Identifier )
is ( Type Identifier : TypeSpecialization )
is ( Type Identifier == TypeSpecialization )
The OP's code isn't parseable as any of these, so according to this it's a syntax error.
> This capability can be manipulated in diverse ways to test for the existence
> of methods, members, the types of them, etc.
--
My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.

In article <1f1np8srt6jk1.j36513qm0sd7.dlg@40tude.net>, Derek Parnell says...
>>On Fri, 24 Jun 2005 00:09:21 -0700, Walter wrote:
>>> "Derek Parnell" <derek@psych.ward> wrote in message news:w3vzckxoa968.nxmmy66f775t$.dlg@40tude.net...>>>> This capability can be manipulated in diverse ways to test for the
>> existence
>>>> of methods, members, the types of them, etc.
>>>>>> Can you supply an example of how to test for the existence of ...
>>>>>> ... a module function
>>> ... a module variable
>>> ... a class member
>>> ... a struct member
>>> ... a class declaration
>>> ... a struct declaration
>>> ... a module importation
>>> ... a function member
>> >> In general, the idea is to construct an expression which will fail to compile if it is *not* one of the above. For example, to test for the existence of member 'm' of struct 'S':
>> >> static if ( is(typeof(S.m)) )
>> ...
>>But that is exactly what I'd like to prevent! In other words I'd like to do this sort of thing ...
>> static_if (! exists(S.m))
> {
> // declare 'm'
> }
I like the new features, but using "is" in this way (since it's also a non-static binary operator) is somewhat confusing. In some respects I'd prefer a new keyowrd for this purpose--istype perhaps? That said, I think we may need the implementation as it is now if it's to work effectively with template code. Consider this (bad) example:
# class A {
# alias int T;
# }
#
# class B {
# int T() {}
# }
#
# template Eval(E) {
# static if( is(E.T) ) {}
# }
#
# Eval!(A);
# Eval!(B);
Here we're filtering on whether or not E.T is a type, rather than whether E.T exists at all (and I just realized I could make a terrible joke about aliens, but I'm resisting the urge).
Sean

Aha! This is what I got wrong when testing for function existance.
I don't mean to repeat myself, but is this going to find its way into the documentation? I would argue it's very useful (in fact I did, possibly not-to-successfully.)
-[Unknown]
> static if ( is(typeof(S.m)) )
> ...