I don't think it is acceptable that the VM depends on language-specific reflection libraries ... in addition to hardly being a language-agnostic solution, I guess.
Is there a reason why the superclass gets removed in the first place? (isInstanceOf[AnyVal] is forbidden any way ...)
I don't think it is acceptable that the VM depends on language-specific reflection libraries ... in addition to hardly being a language-agnostic solution, I guess.
Is there a reason why the superclass gets removed in the first place? (isInstanceOf[AnyVal] is forbidden any way ...)
--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
When would you ever have a value class and not be able to use the language-specific reflection library for that language that generated the value class?
When would you ever have a value class and not be able to use the language-specific reflection library for that language that generated the value class?
As mentioned, runtime support for unboxed value arrays.
--
The array is unboxed, but the value-class-with-unboxed array is itself in a box, right? You can't just take an Array[Long] and miraculously know that it is a range with two ints instead of a float in vector form packed in there.
And if you have that, then I don't quite see why Scala's reflection abilities would be unavailable to you. Are you wanting something in ClassTag or somesuch?
--
Maybe I don't understand the context in which you mean you are "looking into unboxed value arrays".
If you are wondering what VM support would really help out, it would be if the array could store the signature of the box instead of the signature of the primitive. Java wouldn't know what the heck to do with these weird things, but Scala would have a ball. But it wouldn't be a JVM.
If you're doing something else, please explain, because at least to me it is far from clear.
Why not just look for final classes which have only final fields such that
any reference fields have types which also satisfy those constraints?
Then add a reasonable size limit so you don't end up copying around huge
objects on the stack. Done!
Good question. I'd be inclined to treat null as equivalent to an instance
initialized with all zeros. That ends up breaking strict Java
compatibility, but we already have to do that for other reasons (e.g.
reference equality won't mean the same thing when there aren't any
references involved).
You could certainly add an annotation to the type
to indicate that it's "non-nullable", but we still have to define what the
VM should do if it encounters bytecode which misbehaves with respect to
that directive.
Anyway, I do agree that we'll need some way for the language to tell the
VM that it promises to follow certain rules with respect to a type (e.g.
no nulls, no reference comparisons) if we want to avoid breaking code that
uses e.g. java.lang.Integer in non-referentially-transparent ways.
Even so, it would be nice to allow the user to pass a flag to the VM that says,
"treat all types containing only final fields (and which only reference
other such types) as referentially-transparent; I promise my program will
not do any referentially-opaque things with such types, and if it does
you can throw a UserIsABigFatLiarError."
PS: Question to the Scala hackers: Should I file some "value classes miss AnyVal parent in class files" issue?
The bad news is I already tried to do it and it was inordinately complicated.
You have primitive types like Int, which have AnyVal as a parent, and which erase to themselves and survive in Arrays.You have user-defined value classes like Bippy(val x: Int), which have AnyVal as a parent, and which sometimes erase to Int and sometimes erase to Bippy.You have AnyVal itself, which erases to Object.You have all kinds of boxing, unboxing, casting, and erasing, which traverses two phases (erasure and posterasure) and failure is not an option since it's VerifyError or ClassCastException time, both of which I enjoyed while trying to tweak this.And you have Arrays, and I can't say anything about that except good luck to you.
I'm not sure, but I think none of this is required for the use-case in question. The only thing it needs to support is having a class and asking it whether AnyVal is a parent, whether the actual values are boxed/erased/put in arrays ... who cares? Considering that AnyVal doesn't have any "real" members, it should just work like any other marker trait. But if you say it's hard, I completely trust you.
Not sure about an annotation. I'm still kind of hoping to get the compiler under control. Who knows, this could be my decade.
Assuming that this decade will last another 7 years, what about a scala.annotation.unchecked.uncheckedValueType in the meantime? (Automatically added to AnyVal classes, manually addable to "possible" value types?)
The second bullet addresses the problem of annotating classes in std. library. You can generate that file using Scala reflection that would process all types declared in standard library.
- an annotation defined outside of scala namespace
- a file listing all classes considered to be value classes
There are many ways to experiment with value classes support in Avian without getting Scala compiler involved.
Once we learn from those experiments we can revisit this discussion.
The second bullet addresses the problem of annotating classes in std. library. You can generate that file using Scala reflection that would process all types declared in standard library.
Yes, these things can be done, but they are pretty much no improvement over the current “manual” approach. I was hoping for a more seamless approach which can ship with the next release so that no further action is required by users.
It's only experimental in the sense of “when will it arrive?”. Support will ship, sooner or later (e. g. as soon as I have a reliable grasp of the particular C++ code style of Avian).Once we learn from those experiments we can revisit this discussion.
I still don't see what do we need to improve specifically. Maybe you explain it somewhere in this thread but I think I lost that context.
I don't know the scope of the work you are planning to do on Avian side but in general, value classes are very tricky to get even at runtime.
Also, I find it confusing that you want to promote to runtime a property (extends AnyVal) which is meant to mean something statically only.
Moreover, if you are working on runtime support for value classes then probably you'd like to support Option[T] as a canonical example. However, Option won't be marked as a value class in Scala sense (optimized statically) any time soon due to problems discussed in SI-7685.
If we had any JVM that supports value classes at JIT level then we would probably need to rethink Scala support for value classes from scratch. The current, static approach can get you only that far.
I still don't see what do we need to improve specifically. Maybe you explain it somewhere in this thread but I think I lost that context.
The compiler and developers need a reliable, fast way to mark a certain type as “this should really be a value type”, regardless of the current, limited support for value types in the compiler (only single-field classes, no unboxed array representation, poor support for specialization, issues with clashing members, etc.)
I don't know the scope of the work you are planning to do on Avian side but in general, value classes are very tricky to get even at runtime.
As mentioned, I will first be looking into unboxed value types in arrays. The scope is limited and the potential issues well-known. After that, I will be looking into dropping more and more restrictions.
Also, I find it confusing that you want to promote to runtime a property (extends AnyVal) which is meant to mean something statically only.
In what sense are super types a static property only? It transports an important piece of information, just like other marker interfaces. It seems hard to emit the information to the class file for unrelated reasons (see Paul's efforts). That's why I was proposing to introduce some sort of annotation instead, which doesn't interfere with the LUB business.
Moreover, if you are working on runtime support for value classes then probably you'd like to support Option[T] as a canonical example. However, Option won't be marked as a value class in Scala sense (optimized statically) any time soon due to problems discussed in SI-7685.
Sigh, that's exactly why I want that annotation: To mark types which should be value classes, but can't be handled by the compiler currently! If the runtime knows the intention, it can have a shot at it, too (and might probably be more successful than the compiler currently is).
As soon as value types would be supported reliably at runtime¹, I would even add a switch to the compiler to make it stay away from messing with value classes completely.
¹ That's further down the road because support means a lot more than just unboxed arrays, but some parts should be pretty easy to implement. (E. g. replacing all virtual calls with static ones).
I'd like to know what marking a given class to be a value class means before we start sprinkle it on any classes in scala/scala repo.Do we know already?
My point is that AnyVal is not like any other marker interface. It has a very special treatment in Scala compiler and translates to bytecode in a special way.
I'd like to know what marking a given class to be a value class means before we start sprinkle it on any classes in scala/scala repo.
Do we know already?
I'd like to hear about results of those experiments. I'd expect arrays to be actually very tricky to get right but I might be missing something.
My point is that AnyVal is not like any other marker interface. It has a very special treatment in Scala compiler and translates to bytecode in a special way.
As I mentioned before we don't even know what this annotation would mean apart from vague 'JIT should try harder to optimize'. This kind of vaguely defined concepts should stay in experimental land and not go into scala/scala until the concept is fleshed out and has at least one working implementation that supports that concept.
Don't get me wrong. I'm all for supporting your experiments with Avian. I'm all for competition in JVM space. Scala can only benefit from that. However, I don't see much value in putting an annotation into std lib that doesn't have a single implementation supporting it.
On 28 July 2013 06:21, Simon Ochsenreither <simon.och...@gmail.com> wrote:
I don't know the scope of the work you are planning to do on Avian side but in general, value classes are very tricky to get even at runtime.
As mentioned, I will first be looking into unboxed value types in arrays. The scope is limited and the potential issues well-known. After that, I will be looking into dropping more and more restrictions.
I'd like to hear about results of those experiments. I'd expect arrays to be actually very tricky to get right but I might be missing something.
And you do all your array-reasoning just like you do with Array[String] vs. Array[Object].
it is not at all hard for a runtime to do given that it distinguishes Array[String] from Array[Object]
It could be hard for implementation-accidental reasons. That's how things usually turn out in scalac: shouldn't be hard, but are anyway.
But yes, I guess I'd lost the thread of this conversation when it went on hiatus. Clearly there is no fundamental reason the runtime can't carry around a type tag on its primitive arrays. Unfortunately my gut is telling me (stupid gut) I'll be driving a flying car first.
--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
so, yeah, flying car could well be first.
scala> val aa = classOf[ArrowAssoc[_]]
aa: Class[ArrowAssoc[_]] = class java.lang.Object
scala> val re = classOf[RichException]
re: Class[RichException] = class scala.Predef$RichException
Both are declared as AnyVals. Why does one end up as object but one doesn't?
The only difference seems to be the type arguments.