Type information for primitive types in polymorphic types
Given the following object:
object Foo {
val bar: List[Int] = List(1, 2, 3)
}
When we compile this file to JVM bytecode, because of type erasure and due to the fact that Java does not support primitive types as parameters for generic types, this gets translated into a List<Object>
.
We can see this by compiling and inspecting the .class
with javap -l
:
public static com.yuvalitzchakov.github.Foo$ MODULE$;
descriptor: Lcom/yuvalitzchakov/github/Foo$;
flags: ACC_PUBLIC, ACC_STATIC
public scala.collection.immutable.List<java.lang.Object> bar();
descriptor: ()Lscala/collection/immutable/List;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #19 // Field bar:Lscala/collection/immutable/List;
4: areturn
LineNumberTable:
line 4: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/yuvalitzchakov/github/Foo$;
Signature: #17 // ()Lscala/collection/immutable/List<Ljava/lang/Object;>;
But, if we compile this into a JAR file and later take it as a dependency in a different Scala project and try to set Foo.bar
to a different value, the Scala compiler will infer this type as List[Int]
, not List[Object]
:
After browsing around the .class
file, I could not find the information on the type parameter which would allow the Scala compiler to successfully infer this as List[Int]
.
Where is this metadata stored such that we can refer to this type as an actual List[Int]
instead of List[Object]
?
scala polymorphism jvm-bytecode
add a comment |
Given the following object:
object Foo {
val bar: List[Int] = List(1, 2, 3)
}
When we compile this file to JVM bytecode, because of type erasure and due to the fact that Java does not support primitive types as parameters for generic types, this gets translated into a List<Object>
.
We can see this by compiling and inspecting the .class
with javap -l
:
public static com.yuvalitzchakov.github.Foo$ MODULE$;
descriptor: Lcom/yuvalitzchakov/github/Foo$;
flags: ACC_PUBLIC, ACC_STATIC
public scala.collection.immutable.List<java.lang.Object> bar();
descriptor: ()Lscala/collection/immutable/List;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #19 // Field bar:Lscala/collection/immutable/List;
4: areturn
LineNumberTable:
line 4: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/yuvalitzchakov/github/Foo$;
Signature: #17 // ()Lscala/collection/immutable/List<Ljava/lang/Object;>;
But, if we compile this into a JAR file and later take it as a dependency in a different Scala project and try to set Foo.bar
to a different value, the Scala compiler will infer this type as List[Int]
, not List[Object]
:
After browsing around the .class
file, I could not find the information on the type parameter which would allow the Scala compiler to successfully infer this as List[Int]
.
Where is this metadata stored such that we can refer to this type as an actual List[Int]
instead of List[Object]
?
scala polymorphism jvm-bytecode
I’d assume that there are Scala specific attributes for Scala’s type system whichjavap
doesn’t understand and hence, doesn’t print.
– Holger
Nov 21 '18 at 17:49
@Holger Interesting, perhaps looking at the JVM phase of scalac would help.
– Yuval Itzchakov
Nov 21 '18 at 17:51
add a comment |
Given the following object:
object Foo {
val bar: List[Int] = List(1, 2, 3)
}
When we compile this file to JVM bytecode, because of type erasure and due to the fact that Java does not support primitive types as parameters for generic types, this gets translated into a List<Object>
.
We can see this by compiling and inspecting the .class
with javap -l
:
public static com.yuvalitzchakov.github.Foo$ MODULE$;
descriptor: Lcom/yuvalitzchakov/github/Foo$;
flags: ACC_PUBLIC, ACC_STATIC
public scala.collection.immutable.List<java.lang.Object> bar();
descriptor: ()Lscala/collection/immutable/List;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #19 // Field bar:Lscala/collection/immutable/List;
4: areturn
LineNumberTable:
line 4: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/yuvalitzchakov/github/Foo$;
Signature: #17 // ()Lscala/collection/immutable/List<Ljava/lang/Object;>;
But, if we compile this into a JAR file and later take it as a dependency in a different Scala project and try to set Foo.bar
to a different value, the Scala compiler will infer this type as List[Int]
, not List[Object]
:
After browsing around the .class
file, I could not find the information on the type parameter which would allow the Scala compiler to successfully infer this as List[Int]
.
Where is this metadata stored such that we can refer to this type as an actual List[Int]
instead of List[Object]
?
scala polymorphism jvm-bytecode
Given the following object:
object Foo {
val bar: List[Int] = List(1, 2, 3)
}
When we compile this file to JVM bytecode, because of type erasure and due to the fact that Java does not support primitive types as parameters for generic types, this gets translated into a List<Object>
.
We can see this by compiling and inspecting the .class
with javap -l
:
public static com.yuvalitzchakov.github.Foo$ MODULE$;
descriptor: Lcom/yuvalitzchakov/github/Foo$;
flags: ACC_PUBLIC, ACC_STATIC
public scala.collection.immutable.List<java.lang.Object> bar();
descriptor: ()Lscala/collection/immutable/List;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #19 // Field bar:Lscala/collection/immutable/List;
4: areturn
LineNumberTable:
line 4: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/yuvalitzchakov/github/Foo$;
Signature: #17 // ()Lscala/collection/immutable/List<Ljava/lang/Object;>;
But, if we compile this into a JAR file and later take it as a dependency in a different Scala project and try to set Foo.bar
to a different value, the Scala compiler will infer this type as List[Int]
, not List[Object]
:
After browsing around the .class
file, I could not find the information on the type parameter which would allow the Scala compiler to successfully infer this as List[Int]
.
Where is this metadata stored such that we can refer to this type as an actual List[Int]
instead of List[Object]
?
scala polymorphism jvm-bytecode
scala polymorphism jvm-bytecode
asked Nov 21 '18 at 17:41
Yuval Itzchakov
113k26168238
113k26168238
I’d assume that there are Scala specific attributes for Scala’s type system whichjavap
doesn’t understand and hence, doesn’t print.
– Holger
Nov 21 '18 at 17:49
@Holger Interesting, perhaps looking at the JVM phase of scalac would help.
– Yuval Itzchakov
Nov 21 '18 at 17:51
add a comment |
I’d assume that there are Scala specific attributes for Scala’s type system whichjavap
doesn’t understand and hence, doesn’t print.
– Holger
Nov 21 '18 at 17:49
@Holger Interesting, perhaps looking at the JVM phase of scalac would help.
– Yuval Itzchakov
Nov 21 '18 at 17:51
I’d assume that there are Scala specific attributes for Scala’s type system which
javap
doesn’t understand and hence, doesn’t print.– Holger
Nov 21 '18 at 17:49
I’d assume that there are Scala specific attributes for Scala’s type system which
javap
doesn’t understand and hence, doesn’t print.– Holger
Nov 21 '18 at 17:49
@Holger Interesting, perhaps looking at the JVM phase of scalac would help.
– Yuval Itzchakov
Nov 21 '18 at 17:51
@Holger Interesting, perhaps looking at the JVM phase of scalac would help.
– Yuval Itzchakov
Nov 21 '18 at 17:51
add a comment |
1 Answer
1
active
oldest
votes
The JVM class file format allows compilers to put custom attributes into a class file, see Section 4.7.1 of the Java Virtual Machine Specification. Among other things, the Scala compiler puts information about the Scala signature of names into the class files it generates, so that on a later compiler run, it can read this information again. Java Virtual machines are required to ignore attributes they don't understand, so this doesn't make a difference at runtime.
I didn't find a specification of the binary format for the annotations, but if you want to dig into the implementation, I found:
- serialization of types in https://github.com/scala/scala/blob/2.13.x/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
- deserialization of types in
https://github.com/scala/scala/blob/2.13.x/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
For Scala 3.0, it is even planned to store the full abstract syntax tree including the information generated by the type checker in class files using the new "tasty" format. Tasty stands for "typed abstract syntax trees". The basic idea is to serialize the abstract syntax tree after the type checking phase and put it into the class files. Later compiler runs can then load the full abstract syntax of dependencies. This can allow not just type checking, but also cross-module inlining and other global optimizations.
Tasty is planned to become a universal interchange format for Scala abstract syntax trees, also for the communication between the compiler and integrated development environments and for meta programming.
If you want to dig into the implementation, maybe the files in https://github.com/lampepfl/dotty/tree/master/compiler/src/dotty/tools/dotc/core/tasty are good start.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53417795%2ftype-information-for-primitive-types-in-polymorphic-types%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The JVM class file format allows compilers to put custom attributes into a class file, see Section 4.7.1 of the Java Virtual Machine Specification. Among other things, the Scala compiler puts information about the Scala signature of names into the class files it generates, so that on a later compiler run, it can read this information again. Java Virtual machines are required to ignore attributes they don't understand, so this doesn't make a difference at runtime.
I didn't find a specification of the binary format for the annotations, but if you want to dig into the implementation, I found:
- serialization of types in https://github.com/scala/scala/blob/2.13.x/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
- deserialization of types in
https://github.com/scala/scala/blob/2.13.x/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
For Scala 3.0, it is even planned to store the full abstract syntax tree including the information generated by the type checker in class files using the new "tasty" format. Tasty stands for "typed abstract syntax trees". The basic idea is to serialize the abstract syntax tree after the type checking phase and put it into the class files. Later compiler runs can then load the full abstract syntax of dependencies. This can allow not just type checking, but also cross-module inlining and other global optimizations.
Tasty is planned to become a universal interchange format for Scala abstract syntax trees, also for the communication between the compiler and integrated development environments and for meta programming.
If you want to dig into the implementation, maybe the files in https://github.com/lampepfl/dotty/tree/master/compiler/src/dotty/tools/dotc/core/tasty are good start.
add a comment |
The JVM class file format allows compilers to put custom attributes into a class file, see Section 4.7.1 of the Java Virtual Machine Specification. Among other things, the Scala compiler puts information about the Scala signature of names into the class files it generates, so that on a later compiler run, it can read this information again. Java Virtual machines are required to ignore attributes they don't understand, so this doesn't make a difference at runtime.
I didn't find a specification of the binary format for the annotations, but if you want to dig into the implementation, I found:
- serialization of types in https://github.com/scala/scala/blob/2.13.x/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
- deserialization of types in
https://github.com/scala/scala/blob/2.13.x/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
For Scala 3.0, it is even planned to store the full abstract syntax tree including the information generated by the type checker in class files using the new "tasty" format. Tasty stands for "typed abstract syntax trees". The basic idea is to serialize the abstract syntax tree after the type checking phase and put it into the class files. Later compiler runs can then load the full abstract syntax of dependencies. This can allow not just type checking, but also cross-module inlining and other global optimizations.
Tasty is planned to become a universal interchange format for Scala abstract syntax trees, also for the communication between the compiler and integrated development environments and for meta programming.
If you want to dig into the implementation, maybe the files in https://github.com/lampepfl/dotty/tree/master/compiler/src/dotty/tools/dotc/core/tasty are good start.
add a comment |
The JVM class file format allows compilers to put custom attributes into a class file, see Section 4.7.1 of the Java Virtual Machine Specification. Among other things, the Scala compiler puts information about the Scala signature of names into the class files it generates, so that on a later compiler run, it can read this information again. Java Virtual machines are required to ignore attributes they don't understand, so this doesn't make a difference at runtime.
I didn't find a specification of the binary format for the annotations, but if you want to dig into the implementation, I found:
- serialization of types in https://github.com/scala/scala/blob/2.13.x/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
- deserialization of types in
https://github.com/scala/scala/blob/2.13.x/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
For Scala 3.0, it is even planned to store the full abstract syntax tree including the information generated by the type checker in class files using the new "tasty" format. Tasty stands for "typed abstract syntax trees". The basic idea is to serialize the abstract syntax tree after the type checking phase and put it into the class files. Later compiler runs can then load the full abstract syntax of dependencies. This can allow not just type checking, but also cross-module inlining and other global optimizations.
Tasty is planned to become a universal interchange format for Scala abstract syntax trees, also for the communication between the compiler and integrated development environments and for meta programming.
If you want to dig into the implementation, maybe the files in https://github.com/lampepfl/dotty/tree/master/compiler/src/dotty/tools/dotc/core/tasty are good start.
The JVM class file format allows compilers to put custom attributes into a class file, see Section 4.7.1 of the Java Virtual Machine Specification. Among other things, the Scala compiler puts information about the Scala signature of names into the class files it generates, so that on a later compiler run, it can read this information again. Java Virtual machines are required to ignore attributes they don't understand, so this doesn't make a difference at runtime.
I didn't find a specification of the binary format for the annotations, but if you want to dig into the implementation, I found:
- serialization of types in https://github.com/scala/scala/blob/2.13.x/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
- deserialization of types in
https://github.com/scala/scala/blob/2.13.x/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
For Scala 3.0, it is even planned to store the full abstract syntax tree including the information generated by the type checker in class files using the new "tasty" format. Tasty stands for "typed abstract syntax trees". The basic idea is to serialize the abstract syntax tree after the type checking phase and put it into the class files. Later compiler runs can then load the full abstract syntax of dependencies. This can allow not just type checking, but also cross-module inlining and other global optimizations.
Tasty is planned to become a universal interchange format for Scala abstract syntax trees, also for the communication between the compiler and integrated development environments and for meta programming.
If you want to dig into the implementation, maybe the files in https://github.com/lampepfl/dotty/tree/master/compiler/src/dotty/tools/dotc/core/tasty are good start.
answered Nov 21 '18 at 22:19
Toxaris
6,2031631
6,2031631
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53417795%2ftype-information-for-primitive-types-in-polymorphic-types%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I’d assume that there are Scala specific attributes for Scala’s type system which
javap
doesn’t understand and hence, doesn’t print.– Holger
Nov 21 '18 at 17:49
@Holger Interesting, perhaps looking at the JVM phase of scalac would help.
– Yuval Itzchakov
Nov 21 '18 at 17:51