This page is no longer maintained — Please continue to the home page at www.scala-lang.org

2.8.0.head Structured Type and isInstanceOf

6 replies
richard emberson
Joined: 2010-03-22,
User offline. Last seen 42 years 45 weeks ago.

Is there a problem with isInstanceOf and Structured Types?

shell> scala -unchecked
Welcome to Scala version 2.8.0.Beta1-prerelease (Java HotSpot(TM) 64-Bit
Server
VM, Java 1.6.0_19).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class F {
| def getName(): String = {
| "hi"
| }
| }
defined class F

scala> var f = new F()
f: F = F@6b91602

scala> f.isInstanceOf[{ def getName(): String }]
:7: warning: refinement AnyRef{def getName: <?>} in type AnyRef{def
getName: <?>} is unchecked since it is eliminated by erasure
f.isInstanceOf[{ def getName(): String }]
^
res0: Boolean = true

// Note: returns true

scala> "someString".isInstanceOf[{ def getName(): String }]
:5: warning: refinement AnyRef{def getName: <?>} in type AnyRef{def
getName: <?>} is unchecked since it is eliminated by erasure
"someString".isInstanceOf[{ def getName(): String }]
^
res1: Boolean = true

// Note: should not return true
scala> var a = new Array[{ def getName(): String}](1)
a: Array[AnyRef{def getName(): String}] = Array(null)

scala> a(0) = f

scala> a(0)
res3: AnyRef{def getName(): String} = F@6b91602

scala> a(0) = "someString"
:6: error: type mismatch;
found : java.lang.String("someString")
required: AnyRef{def getName(): String}
a(0) = "someString"
^
// So, adding to the Array fails as it should,
// but isInstanceOf does not work

Richard

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: 2.8.0.head Structured Type and isInstanceOf

On Fri, Apr 02, 2010 at 08:32:36AM -0700, richard emberson wrote:
> Is there a problem with isInstanceOf and Structured Types?

If only there were some sort of warning!

fanf
Joined: 2009-03-17,
User offline. Last seen 2 years 30 weeks ago.
Re: 2.8.0.head Structured Type and isInstanceOf

Le 02/04/2010 17:32, richard emberson a écrit :
[...]
> scala> "someString".isInstanceOf[{ def getName(): String }]
> :5: warning: refinement AnyRef{def getName: <?>} in type
> AnyRef{def
> getName: <?>} is unchecked since it is eliminated by erasure
> "someString".isInstanceOf[{ def getName(): String }]
> ^

The warning is really important and say exactly what is happening. You
are just testing that you string is an instance of AnyRef.

Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: 2.8.0.head Structured Type and isInstanceOf

On Friday April 2 2010, Francois wrote:
> Le 02/04/2010 17:32, richard emberson a écrit :
> [...]
>
>> scala> f.isInstanceOf[{ def getName(): String }]
>> :7: warning: refinement AnyRef{def getName: <?>} in type AnyRef{def getName: <?>} is unchecked since it is eliminated by erasure
>> f.isInstanceOf[{ def getName(): String }]
>
> The warning is really important and say exactly what is happening.
> You are just testing that you string is an instance of AnyRef.

One could make the argument that for what is ordinarily a dynamic test,
the generated code should test the instance for the presence of a
structurally compatible method, analogous to the way an attempt to
invoke that method would use reflection to find the method.

Randall Schulz

richard emberson
Joined: 2010-03-22,
User offline. Last seen 42 years 45 weeks ago.
Re: 2.8.0.head Structured Type and isInstanceOf

import java.io.File
import collection.mutable.ListBuffer

object ST {
class T(name: String) {
def getName(): String = name
override def toString(): String = {
"T.name=" +name
}
}
def main(args: Array[String]) {
val l = List[AnyRef]("hi", new File("test.txt"), new T("someT"))

val lb = new ListBuffer[{ def getName(): String }]

for (v <- l) {
if (v.isInstanceOf[ {def getName(): String } ]) {
lb += v.asInstanceOf[{ def getName(): String }]
}
}
println(lb)
}
}

shell> scalac ST.scala
warning: there were unchecked warnings; re-run with -unchecked for details
one warning found

shell> scala ST
ListBuffer(hi, test.txt, T.name=someT)

This is not the expected result which is to say,
its a run-time error.

Great there was a compile-time warning.
The result was a run-time error.
The best solution would be for isInstanceOf to work
at run-time. Next best is for asInstanceOf to work
at run-time. And I mean "work" as a developer might
expect rather than "work" only to a point due to
limitations in the platform. The third best option
is for the compiler to create a compile-time error
stating that run-time information concerning
Structured Types is very limited and isInstanceOf
and asInstanceOf can not be used with them.

Richard

On 04/02/2010 09:11 AM, Randall R Schulz wrote:
> On Friday April 2 2010, Francois wrote:
>> Le 02/04/2010 17:32, richard emberson a écrit :
>> [...]
>>
>>> scala> f.isInstanceOf[{ def getName(): String }]
>>> :7: warning: refinement AnyRef{def getName:<?>} in type AnyRef{def getName:<?>} is unchecked since it is eliminated by erasure
>>> f.isInstanceOf[{ def getName(): String }]
>>
>> The warning is really important and say exactly what is happening.
>> You are just testing that you string is an instance of AnyRef.
>
> One could make the argument that for what is ordinarily a dynamic test,
> the generated code should test the instance for the presence of a
> structurally compatible method, analogous to the way an attempt to
> invoke that method would use reflection to find the method.
>
>
> Randall Schulz
>

James Iry
Joined: 2008-08-19,
User offline. Last seen 1 year 23 weeks ago.
Re: 2.8.0.head Structured Type and isInstanceOf
I'm sympathetic but sometimes casting across type erasure is useful so a warning is more appropriate than an error.

That  said, there is enough information in the class file for isInstanceOf and asInstanceOf to do -SOME- runtime checking of structural types, certainly more than is being done now.  Since this is very important to you would you mind specifying the details of the enhancement (exactly what will and will not be checked, how it all behaves with subtyping, how it all behaves with Scala's various boxed forms, etc) in a SID?

On Fri, Apr 2, 2010 at 9:23 AM, richard emberson <richard [dot] emberson [at] gmail [dot] com> wrote:


Great there was a compile-time warning.
The result was a run-time error.
The best solution would be for isInstanceOf to work
at run-time. Next best is for asInstanceOf to work
at run-time. And I mean "work" as a developer might
expect rather than "work" only to a point due to
limitations in the platform. The third best option
is for the compiler to create a compile-time error
stating that run-time information concerning
Structured Types is very limited and isInstanceOf
and asInstanceOf can not be used with them.

Richard

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: 2.8.0.head Structured Type and isInstanceOf

On Fri, Apr 02, 2010 at 11:25:58AM -0700, James Iry wrote:
> That said, there is enough information in the class file for
> isInstanceOf and asInstanceOf to do -SOME- runtime checking of
> structural types, certainly more than is being done now.

I've had this 75% done for a while. The static side is done, but I have
to generalize the reflection machinery in cleanup to do the runtime
check cleanly. IOW in that branch this gives correct answers more often
than a stopped clock:

"abc".isInstanceOf[{ def length(): Int }]

But this still needs work:

("abc": AnyRef).isInstanceOf[{ def length(): Int }]

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland