www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - IsExpression

reply =?ISO-8859-1?Q?Lu=EDs_Marques?= <luismarques+spam gmail.com> writes:
Hello,

The documentation of IsExpression lists the following valid forms:

is ( Type )
is ( Type : TypeSpecialization )
is ( Type == TypeSpecialization )
is ( Type Identifier )
is ( Type Identifier : TypeSpecialization )
is ( Type Identifier == TypeSpecialization )

What about the form "expression is expression"? I cannot find 
documentation for that form. What are its semantics? "exp is null" is an 
obvious one. But what about other forms?

- for classes it seems that "obj1 is obj2" is equivalent to "&obj1 == 
&obj2". Can I rely on that? I have a singleton called "nil", so it's 
great being able to say "obj is nil".

- for structs "structvar1 is structvar2" is always true.

- for PODs it seems that values must be semantically equivalent. For 
instance, "1L is 1.0+0i" is true.

Could this be documented?

Also, the IsExpression docs refer to a "Type", which can be an 
identifier (e.g. "int x; writefln(is(x));" is valid, even though the 
form in question is "is(Type)"). Perhaps that could be made more clear?

Regards,
Luis
Mar 12 2007
next sibling parent Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Luís Marques wrote:
 Hello,
 
 The documentation of IsExpression lists the following valid forms:
 
 is ( Type )
 is ( Type : TypeSpecialization )
 is ( Type == TypeSpecialization )
 is ( Type Identifier )
 is ( Type Identifier : TypeSpecialization )
 is ( Type Identifier == TypeSpecialization )
 
 What about the form "expression is expression"? I cannot find 
 documentation for that form. What are its semantics? "exp is null" is an 
 obvious one. But what about other forms?
 
 - for classes it seems that "obj1 is obj2" is equivalent to "&obj1 == 
 &obj2". Can I rely on that? I have a singleton called "nil", so it's 
 great being able to say "obj is nil".
 
 - for structs "structvar1 is structvar2" is always true.
 
 - for PODs it seems that values must be semantically equivalent. For 
 instance, "1L is 1.0+0i" is true.
 
 Could this be documented?
 

The 'is' keyword is used in two completely separate contexts: The first is the IsExpression, which has the grammar you outlined above. This is used for compile-time type checking. The other use of 'is' is in the IdentityExpression. http://www.digitalmars.com/d/expression.html#IdentityExpression "For operand types other than class objects, static or dynamic arrays, identity is defined as being the same as equality." Thus for structs I would expect it to perform a bitwise comparison of the two instances if the struct doesn't overload opEquals.
 Also, the IsExpression docs refer to a "Type", which can be an 
 identifier (e.g. "int x; writefln(is(x));" is valid, even though the 
 form in question is "is(Type)"). Perhaps that could be made more clear?
 

It is indeed valid. As you point out, a "Type" can be an identifier, and it is a property of the IsExpression that it returns false if the Type provided is not a semantically valid type. Therefore, you must be able to provide it semantically /invalid/ types. (Which must still be /syntactically/ valid.) -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.org
Mar 12 2007
prev sibling parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Luís Marques wrote:
 
 The documentation of IsExpression lists the following valid forms:
 
 is ( Type )
 is ( Type : TypeSpecialization )
 is ( Type == TypeSpecialization )
 is ( Type Identifier )
 is ( Type Identifier : TypeSpecialization )
 is ( Type Identifier == TypeSpecialization )
 
 What about the form "expression is expression"? I cannot find 
 documentation for that form.

That isn't an IsExpression, it's an IdentityExpression: http://www.digitalmars.com/d/expression.html#IdentityExpression
 What are its semantics? "exp is null" is an
 obvious one. But what about other forms?

See above URL: --- The is compares for identity. To compare for not identity, use e1 !is e2. The type of the result is bool. The operands go through the usual conversions to bring them to a common type before comparison. For operand types other than class objects, static or dynamic arrays, identity is defined as being the same as equality. For class objects, identity is defined as the object references are for the same object. Null class objects can be compared with is. For static and dynamic arrays, identity is defined as referring to the same array elements. The identity operator is cannot be overloaded. ---
 - for classes it seems that "obj1 is obj2" is equivalent to "&obj1 == 
 &obj2". Can I rely on that? I have a singleton called "nil", so it's 
 great being able to say "obj is nil".

Yes, you can rely on that, as long as it's a class type.
 - for structs "structvar1 is structvar2" is always true.

Should only be so if the contents of the member variables is equal (or opEqual is defined and returns true)
 - for PODs it seems that values must be semantically equivalent. For 
 instance, "1L is 1.0+0i" is true.

This is because of equivalence to '==' in this case and implicit conversions.
 Could this be documented?

It is.
 Also, the IsExpression docs refer to a "Type", which can be an 
 identifier (e.g. "int x; writefln(is(x));" is valid, even though the 
 form in question is "is(Type)"). Perhaps that could be made more clear?

To be clear, is(x) is allowed for int x, but will return false. As it will if x isn't even declared. An IsExpression tests if the argument is a valid type, so obviously "Type" refers to something that should be tested for type-ness. Note that the syntax definition defines just that: the syntax, not the semantics. As long as the argument is something that can possibly be parsed as a type (as far as the syntax is concerned, so before inspecting the declarations of the symbols used) it should be allowed.
Mar 12 2007