Below is my ramblings about long-standind issues with is expressions. I think
it was inspired by a recent post about how to translate some D 2.x is
expressions into D 1.x... I have a few thoughts on how I might fix the syntax,
but I'd first like to know if my objections to the current syntax is shared
with others.
According to http://www.digitalmars.com/d/2.0/expression.html#IsExpression,
there are currently 8 forms for is expressions:
1. is ( Type )
2. is ( Type : TypeSpecialization )
3. is ( Type == TypeSepcialization )
4. is ( Type Identifier )
5. is ( Type Identifier : TypeSpecialization )
6. is ( Type Identifier == typeSpecialization )
7. is ( Type Identifier : TypeSpecialization , TemplateParameterList )
8. is ( Type Identifier == TypeSpecialization , TemplateParameterList )
I see 3 issues with groking is expressions:
1. "Type Identifier" does not always create something matching type "Type"
2. Type Specialization has multple forms
3. Use of ":" or "==" can be ambiguous, especially when reading code
Issue 1:
In all other parts of D code, "Type Identifier" creates something matching
"Type". In an is expression, this is always true with form 4, sometimes true
with forms 5 and 6, and never true with forms 7 and 8. When it isn't true, the
identifier is reused on the right side fo the ":" or "==" and corresponds to a
derived type. With enough thinking about an is expression, the meaning should
become clear, but I don't think a casual reader of D code will get it on first
glance.
Issue #2
Type specialization has three forms:
A. A pure type
B. A type with deduction arguments
C. A keyword representing a class of types
Form C is not valid for all forms of is expressions (more on this in issue
#3). As discussed in issue #1, forms A and C have Identifier mean one thing
while form B will have Identifier mean somethign else. Form B can have up to
one symbol match "identifier", and one or more symbols match inside
TemplateParameterList. I think there was a recent post to the newsgroup with
an example like is(T U : U*, U) where the identifier U is both the identifier
and part of the TemplateParameterList.
Issue #3
When reading D code, the meaning of ":" can be ambiguous. It's a form that
does not match any languages that I know of. Unlike ":", the meaning of "=="
is clear when reading code. ":" can be translated as "is implicitly castable
to" and "==" can be translated "is equal to".
When writing code, an ambiguity pops up when a keyword TypeSpecialization
(form C above) is used. is(T:struct) and is(T==struct) can make sense. In my
mind, T is part of the larger group of structs, just like a short is part of
the larger groups of integers (and is implicitly castable to int because of
this). That implies to me that the syntax should be is(T:struct), but this is
not correct. The D syntax is is(T==struct)