fansh> 1 is Int
ERROR(1): Cannot use 'is' operator on value type 'sys::Int'
ERROR(1): Not a statement
This does not:
fansh> 1 is Num
ERROR(1): Cannot use 'is' operator on value type 'sys::Int'
ERROR(1): Not a statement'
vkuzkokovWed 24 Nov 2010
Exactly. From ${FAN_HOME}/src/compiler/fan/steps/CheckErrors.fan
private Void checkTypeCheck(TypeCheckExpr expr)
{
// don't bother checking a synthetic coercion that the
// compiler generated itself (which is most coercions)
if (expr.synthetic) return
// verify types are convertible
check := expr.check
target := expr.target.ctype
if (!check.fits(target) && !target.fits(check) && !check.isMixin && !target.isMixin)
err("Inconvertible types '$target' and '$check'", expr.loc)
// don't allow is, as, isnot (everything but coerce) to be
// used with value type expressions
if (expr.id != ExprId.coerce)
{
if (target.isVal)
{
err("Cannot use '$expr.opStr' operator on value type '$target'", expr.loc)
return
}
}
Here target is type of expr and isVal is true iff the type is Bool, Int or Float. Those types are treated specially, because they are mapped to primitives and common type check procedure won't work for them (in terms of VM bytecodes).
I'd rather have this type check replaced with its result evaluated at compile time, because this behavior may break backward compatibility in not-so-obvious way.
e.g. I have Num getSize() in my library and change it to Int getSize. After that getSize is Float somewhere in client code won't compile.
jlistWed 24 Nov 2010
I see, thanks for explaining, vkuzkokov. As a new comer, I'm a bit surprised to see the inconsistency in language spec caused by implementation details. I was assuming that "is" was an operator that's applicable to any type.
jodastephenWed 24 Nov 2010
I spotted this one when looking at the compiler. I'd say that there should be no visiable effect of a type being a value type, so this is an anti-feature. After all, Fantom could compile down to a different VM where there is no primitive int, and there should be no visible impact on the source (ie. the effects of value types should be a transformation of the AST at a later stage).
brianFri 26 Nov 2010
You could definitely argue that from a purity stand point we should allow that. But I can't think of a situation where that would ever make sense. In this case the value is known at compile time to be a Bool, Int, or Float (which are all final classes). So to me trying to use a is or other operator with a known value type does indeed like a compile time error.
DanielFathFri 26 Nov 2010
It's not so much purity as it is consistency. Another argument for 1 is Int is simply that everything is an object so there is no difference between i is Int and 1 is Int.
alex_panchenkoFri 26 Nov 2010
Definitely, there are no reasons to report an error if expression can be evaluated at compile time. A warning should be enough.
katoxFri 26 Nov 2010
I don't see a good reason for it to behave differently. It is strikingly illogical.
For instance, if you had a code generator (not that I am a fan of those) you would have to complicate your code path to avoid this.
jlistFri 26 Nov 2010
Yes, it's about consistency. To me, we are doing type check of a literal in both cases:
"s" is Str
and
1 is Int
Since everything is a class, I expect that I can check type on any class. The is operator should be a language feature, as opposed to class specific.
BTW, this fails, too:
i := 1
i is Int
So Int and Str just behave differently. I'm still new to Fantom so my question is, what's special about Str, or Int?
I think the compiler should report errors on real errors, not something that it thinks makes no sense. So I agree with alex_panchenko here: a warning will do. This looks very much like a bug to me :-)
rfeldmanFri 26 Nov 2010
To draw an analogy, no good reason comes to mind to write if (1 == 1), but I'd still expect it to compile.
brianSun 28 Nov 2010
Promoted to ticket #1326 and assigned to brian
Sounds like everyone votes for consistency in the operators here, so I don't see a big problem supporting is, as with value-types. We will just box them into an Object in the compiler.
brianSun 28 Nov 2010
Renamed from is operator is only good for some types but not all? to Support for is/as operators on value-types
qualidafialSun 28 Nov 2010
What about optimizing the expression away since the result is known statically at compile time?
jlist Wed 24 Nov 2010
This works:
This does not:
This does not:
vkuzkokov Wed 24 Nov 2010
Exactly. From
${FAN_HOME}/src/compiler/fan/steps/CheckErrors.fan
Here
target
is type of expr andisVal
is true iff the type isBool
,Int
orFloat
. Those types are treated specially, because they are mapped to primitives and common type check procedure won't work for them (in terms of VM bytecodes).I'd rather have this type check replaced with its result evaluated at compile time, because this behavior may break backward compatibility in not-so-obvious way.
e.g. I have
Num getSize()
in my library and change it toInt getSize
. After thatgetSize is Float
somewhere in client code won't compile.jlist Wed 24 Nov 2010
I see, thanks for explaining, vkuzkokov. As a new comer, I'm a bit surprised to see the inconsistency in language spec caused by implementation details. I was assuming that "is" was an operator that's applicable to any type.
jodastephen Wed 24 Nov 2010
I spotted this one when looking at the compiler. I'd say that there should be no visiable effect of a type being a value type, so this is an anti-feature. After all, Fantom could compile down to a different VM where there is no primitive
int
, and there should be no visible impact on the source (ie. the effects of value types should be a transformation of the AST at a later stage).brian Fri 26 Nov 2010
You could definitely argue that from a purity stand point we should allow that. But I can't think of a situation where that would ever make sense. In this case the value is known at compile time to be a Bool, Int, or Float (which are all final classes). So to me trying to use a
is
or other operator with a known value type does indeed like a compile time error.DanielFath Fri 26 Nov 2010
It's not so much purity as it is consistency. Another argument for
1 is Int
is simply that everything is an object so there is no difference betweeni is Int
and1 is Int
.alex_panchenko Fri 26 Nov 2010
Definitely, there are no reasons to report an error if expression can be evaluated at compile time. A warning should be enough.
katox Fri 26 Nov 2010
I don't see a good reason for it to behave differently. It is strikingly illogical.
For instance, if you had a code generator (not that I am a fan of those) you would have to complicate your code path to avoid this.
jlist Fri 26 Nov 2010
Yes, it's about consistency. To me, we are doing type check of a literal in both cases:
and
Since everything is a class, I expect that I can check type on any class. The is operator should be a language feature, as opposed to class specific.
BTW, this fails, too:
So Int and Str just behave differently. I'm still new to Fantom so my question is, what's special about Str, or Int?
I think the compiler should report errors on real errors, not something that it thinks makes no sense. So I agree with alex_panchenko here: a warning will do. This looks very much like a bug to me :-)
rfeldman Fri 26 Nov 2010
To draw an analogy, no good reason comes to mind to write
if (1 == 1)
, but I'd still expect it to compile.brian Sun 28 Nov 2010
Promoted to ticket #1326 and assigned to brian
Sounds like everyone votes for consistency in the operators here, so I don't see a big problem supporting
is
,as
with value-types. We will just box them into an Object in the compiler.brian Sun 28 Nov 2010
Renamed from is operator is only good for some types but not all? to Support for is/as operators on value-types
qualidafial Sun 28 Nov 2010
What about optimizing the expression away since the result is known statically at compile time?
brian Sun 2 Jan 2011
Ticket resolved in 1.0.57
changeset