Type information for primitive types in polymorphic types












1














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



Type after taking a dependency on packaged JAR



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]?










share|improve this question






















  • 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
















1














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



Type after taking a dependency on packaged JAR



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]?










share|improve this question






















  • 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














1












1








1







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



Type after taking a dependency on packaged JAR



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]?










share|improve this question













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



Type after taking a dependency on packaged JAR



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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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


















  • 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
















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












1 Answer
1






active

oldest

votes


















3














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.






share|improve this answer





















    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    3














    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.






    share|improve this answer


























      3














      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.






      share|improve this answer
























        3












        3








        3






        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.






        share|improve this answer












        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.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 21 '18 at 22:19









        Toxaris

        6,2031631




        6,2031631






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            404 Error Contact Form 7 ajax form submitting

            How to know if a Active Directory user can login interactively

            TypeError: fit_transform() missing 1 required positional argument: 'X'