#1326 Support for is/as operators on value-types

jlist Wed 24 Nov 2010

This works:

fansh> "s" is Str

This does not:

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'

vkuzkokov Wed 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)

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.

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 between i is Int and 1 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:

"s" is Str


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 :-)

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


Login or Signup to reply.