Does variance make sense in a fully immutable language?Do resumable exceptions make any sense?When is it inappropriate to make objects immutable?How to make complex objects immutable?Make classes immutable or compatible with standard containersWhy does an immutable object in Scala need less memory than a mutable one?Can we really use immutability in OOP without losing all key OOP features?Efficient algorithm for deducing object type dynamically based on membersIn my use case, does it make sense to make every major method return an async result?Changing immutable objects how does this work?

Neural network vs regression in a small sample

What would influence an alien race to map their planet in a way other than the traditional map of the Earth

Pushing the e-pawn

What is Weapon Handling?

When did Unix stop storing passwords in clear text?

How can I become an invalid target for spells that target humanoids?

Assembly of PCBs containing a mix of SMT and thru-hole parts?

How to model regression with an asymmetric loss function?

Selection Sort Algorithm (Python)

How to justify getting additional team member when the current team is doing well?

Fix Ethernet 10/100 PoE cable with 7 out of 8 wires alive

How to convert what I'm singing to notes

Where to find the Arxiv endorsement code?

Sci-fi movie with one survivor and an organism(?) recreating his memories

お仕事に学校頑張って meaning

Why does C++ have 'Undefined Behaviour' and other languages like C# or Java don't?

An impressive body of work

Whaling ship logistics

What makes learning more difficult as we age?

Why is STARTTLS still used?

How do we know neutrons have no charge?

Why does Captain Marvel in the MCU not have her sash?

Is it ok if I haven't decided my research topic when I first meet with a potential phd advisor?

Why Italian monolingual dictionaries usually take complex/archaic examples from books instead of creating simple examples?



Does variance make sense in a fully immutable language?


Do resumable exceptions make any sense?When is it inappropriate to make objects immutable?How to make complex objects immutable?Make classes immutable or compatible with standard containersWhy does an immutable object in Scala need less memory than a mutable one?Can we really use immutability in OOP without losing all key OOP features?Efficient algorithm for deducing object type dynamically based on membersIn my use case, does it make sense to make every major method return an async result?Changing immutable objects how does this work?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








3















In many OOP programming languages, types can be made co-, contra- or in- variant. Most (if not all of these languages) are able to let variables be mutated in place, i.e. they are not fully immutable languages.



I've seen in this SO answer that, in Scala at least, neither a covariant type can appear in a contravariant position nor a contravariant type can appear in a covariant position.



The problem I have with this answer (and in fact with all similar examples I ever found on the internet) is that it relies on mutability to show evidence of the above fact.



So my questions are:



  • does even the concept of variance make sense in an immutable environment?

  • if so, then could every type of a speculative fully immutable OOP language (like, all of them) be made covariant, regardless of where they are used (i.e. as function input types / function output types)?









share|improve this question









New contributor



Louis-Jacob Lebel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    Wouldn't lack of variance imply an invariant type?

    – Robert Harvey
    9 hours ago











  • To my understanding, "lack of variance" is the definition of type invariance -- that is not covariant nor contravariant.

    – Louis-Jacob Lebel
    8 hours ago






  • 3





    The mutability in those examples is a red herring. They are just an intuitive way to show how wrong variance could be unsound. You get the same problems when you cast immutable containers or functions around. However, most functional languages do not feature subtyping and therefore don't need a concept of variance.

    – amon
    8 hours ago











  • @amon "You get the same problems when you cast immutable containers or functions around": Hmm I'm not sure about this. Could you please write an answer with an example or a proof that supports this fact? You would answer all of my questions at the same time. :)

    – Louis-Jacob Lebel
    8 hours ago


















3















In many OOP programming languages, types can be made co-, contra- or in- variant. Most (if not all of these languages) are able to let variables be mutated in place, i.e. they are not fully immutable languages.



I've seen in this SO answer that, in Scala at least, neither a covariant type can appear in a contravariant position nor a contravariant type can appear in a covariant position.



The problem I have with this answer (and in fact with all similar examples I ever found on the internet) is that it relies on mutability to show evidence of the above fact.



So my questions are:



  • does even the concept of variance make sense in an immutable environment?

  • if so, then could every type of a speculative fully immutable OOP language (like, all of them) be made covariant, regardless of where they are used (i.e. as function input types / function output types)?









share|improve this question









New contributor



Louis-Jacob Lebel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    Wouldn't lack of variance imply an invariant type?

    – Robert Harvey
    9 hours ago











  • To my understanding, "lack of variance" is the definition of type invariance -- that is not covariant nor contravariant.

    – Louis-Jacob Lebel
    8 hours ago






  • 3





    The mutability in those examples is a red herring. They are just an intuitive way to show how wrong variance could be unsound. You get the same problems when you cast immutable containers or functions around. However, most functional languages do not feature subtyping and therefore don't need a concept of variance.

    – amon
    8 hours ago











  • @amon "You get the same problems when you cast immutable containers or functions around": Hmm I'm not sure about this. Could you please write an answer with an example or a proof that supports this fact? You would answer all of my questions at the same time. :)

    – Louis-Jacob Lebel
    8 hours ago














3












3








3








In many OOP programming languages, types can be made co-, contra- or in- variant. Most (if not all of these languages) are able to let variables be mutated in place, i.e. they are not fully immutable languages.



I've seen in this SO answer that, in Scala at least, neither a covariant type can appear in a contravariant position nor a contravariant type can appear in a covariant position.



The problem I have with this answer (and in fact with all similar examples I ever found on the internet) is that it relies on mutability to show evidence of the above fact.



So my questions are:



  • does even the concept of variance make sense in an immutable environment?

  • if so, then could every type of a speculative fully immutable OOP language (like, all of them) be made covariant, regardless of where they are used (i.e. as function input types / function output types)?









share|improve this question









New contributor



Louis-Jacob Lebel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











In many OOP programming languages, types can be made co-, contra- or in- variant. Most (if not all of these languages) are able to let variables be mutated in place, i.e. they are not fully immutable languages.



I've seen in this SO answer that, in Scala at least, neither a covariant type can appear in a contravariant position nor a contravariant type can appear in a covariant position.



The problem I have with this answer (and in fact with all similar examples I ever found on the internet) is that it relies on mutability to show evidence of the above fact.



So my questions are:



  • does even the concept of variance make sense in an immutable environment?

  • if so, then could every type of a speculative fully immutable OOP language (like, all of them) be made covariant, regardless of where they are used (i.e. as function input types / function output types)?






scala immutability invariants






share|improve this question









New contributor



Louis-Jacob Lebel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.










share|improve this question









New contributor



Louis-Jacob Lebel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








share|improve this question




share|improve this question








edited 8 hours ago







Louis-Jacob Lebel













New contributor



Louis-Jacob Lebel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








asked 9 hours ago









Louis-Jacob LebelLouis-Jacob Lebel

214 bronze badges




214 bronze badges




New contributor



Louis-Jacob Lebel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




New contributor




Louis-Jacob Lebel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • 1





    Wouldn't lack of variance imply an invariant type?

    – Robert Harvey
    9 hours ago











  • To my understanding, "lack of variance" is the definition of type invariance -- that is not covariant nor contravariant.

    – Louis-Jacob Lebel
    8 hours ago






  • 3





    The mutability in those examples is a red herring. They are just an intuitive way to show how wrong variance could be unsound. You get the same problems when you cast immutable containers or functions around. However, most functional languages do not feature subtyping and therefore don't need a concept of variance.

    – amon
    8 hours ago











  • @amon "You get the same problems when you cast immutable containers or functions around": Hmm I'm not sure about this. Could you please write an answer with an example or a proof that supports this fact? You would answer all of my questions at the same time. :)

    – Louis-Jacob Lebel
    8 hours ago













  • 1





    Wouldn't lack of variance imply an invariant type?

    – Robert Harvey
    9 hours ago











  • To my understanding, "lack of variance" is the definition of type invariance -- that is not covariant nor contravariant.

    – Louis-Jacob Lebel
    8 hours ago






  • 3





    The mutability in those examples is a red herring. They are just an intuitive way to show how wrong variance could be unsound. You get the same problems when you cast immutable containers or functions around. However, most functional languages do not feature subtyping and therefore don't need a concept of variance.

    – amon
    8 hours ago











  • @amon "You get the same problems when you cast immutable containers or functions around": Hmm I'm not sure about this. Could you please write an answer with an example or a proof that supports this fact? You would answer all of my questions at the same time. :)

    – Louis-Jacob Lebel
    8 hours ago








1




1





Wouldn't lack of variance imply an invariant type?

– Robert Harvey
9 hours ago





Wouldn't lack of variance imply an invariant type?

– Robert Harvey
9 hours ago













To my understanding, "lack of variance" is the definition of type invariance -- that is not covariant nor contravariant.

– Louis-Jacob Lebel
8 hours ago





To my understanding, "lack of variance" is the definition of type invariance -- that is not covariant nor contravariant.

– Louis-Jacob Lebel
8 hours ago




3




3





The mutability in those examples is a red herring. They are just an intuitive way to show how wrong variance could be unsound. You get the same problems when you cast immutable containers or functions around. However, most functional languages do not feature subtyping and therefore don't need a concept of variance.

– amon
8 hours ago





The mutability in those examples is a red herring. They are just an intuitive way to show how wrong variance could be unsound. You get the same problems when you cast immutable containers or functions around. However, most functional languages do not feature subtyping and therefore don't need a concept of variance.

– amon
8 hours ago













@amon "You get the same problems when you cast immutable containers or functions around": Hmm I'm not sure about this. Could you please write an answer with an example or a proof that supports this fact? You would answer all of my questions at the same time. :)

– Louis-Jacob Lebel
8 hours ago






@amon "You get the same problems when you cast immutable containers or functions around": Hmm I'm not sure about this. Could you please write an answer with an example or a proof that supports this fact? You would answer all of my questions at the same time. :)

– Louis-Jacob Lebel
8 hours ago











3 Answers
3






active

oldest

votes


















5

















does even the concept of variance make sense in an immutable environment?




Yes; presence of subtyping is independent of immutability.




could every type of a speculative fully immutable OOP language (like, all of them) be made covariant, regardless of where they are used (i.e. as function input types / function output types)?




As a simple demonstration why function input types can't be covariant, with no mutability involved (using Scala syntax):



val f: Int => Int = x => 2 * x
val g: Any => Int = f // allowed by covariance
g("") // what should this do?


The rule is still the same: "producer extends (covariant), consumer super (contravariant)". And a function is a consumer of its input type.






share|improve this answer



























  • I was actually writing my own answer accordingly to the one written by JimmyJames, in almost exactly this format, when you posted it. Sometimes coincidences can be disappointing.

    – Louis-Jacob Lebel
    6 hours ago



















5
















Variance has nothing to do with mutability. It appears at the intersection of parametric polymorphism and subtyping.



The oldest example of variance is actually an example that comes out of functional programming, namely the question: when is a function type a subtype of another function type?



And it turns out that a function type is a subtype of another function type if its inputs are at least as general and its outputs at least as specific as the supertype.



In other words, functions are contravariant in their inputs and covariant in their outputs.






share|improve this answer
































    1
















    Suppose you have a function that takes a list/array and a comparison function and returns a new one with the items sorted. If I have a list of Integers objects, I need a function that can sort integers: compare(a,b). With variance-free typing, I either have to specify that the function must take integers compare(a: Integer, a:Integer) or that it must take a specific super-type of integer e.g. compare(a: Object, a:Object). But what if I have a comparison defined as compare(a: Number, b: Number)? It should work fine but I can't use it in either case. So we need to be able to specify that the comparison function needs to be able to handle Integer or any superclass of Integer i.e. contra-variance.






    share|improve this answer

























    • Just to be sure, in your example compare(a: Number, b: Number), is Number assumed to not be a supertype of Integer?

      – Louis-Jacob Lebel
      7 hours ago











    • Number is assumed to be a superclass of Integer.

      – JimmyJames
      7 hours ago











    • I'm not sure then why compare(a: Number, b: Number) would not work where compare(a: Object, b: Object) would. Also, I'm not sure what you mean by "It should work fine but I can't use it in either case", maybe that's what I'm missing?

      – Louis-Jacob Lebel
      7 hours ago












    • A comparison function defined as compare(a: Object, b:Object) must be able to compare any two objects e.g. two Strings or a String and a List. compare(a: Number, b: Number) doesn't accept Strings or Lists.

      – JimmyJames
      7 hours ago











    • Sorry, I meant in the context of an Integer application, which I thought was what you meant in your answer. So lets say we have sort(c: OrderedCollection[Integer], compare: (T, T) => T), then as long as T is a supertype of Integer there is no type error. Outside of this context, then indeed you seem to be right. Anyways, even if not everything was clear to me in your answer, I got a clear answer to my questions.

      – Louis-Jacob Lebel
      7 hours ago














    Your Answer








    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "131"
    ;
    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: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    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/4.0/"u003ecc by-sa 4.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
    );



    );







    Louis-Jacob Lebel is a new contributor. Be nice, and check out our Code of Conduct.









    draft saved

    draft discarded
















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f398770%2fdoes-variance-make-sense-in-a-fully-immutable-language%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    5

















    does even the concept of variance make sense in an immutable environment?




    Yes; presence of subtyping is independent of immutability.




    could every type of a speculative fully immutable OOP language (like, all of them) be made covariant, regardless of where they are used (i.e. as function input types / function output types)?




    As a simple demonstration why function input types can't be covariant, with no mutability involved (using Scala syntax):



    val f: Int => Int = x => 2 * x
    val g: Any => Int = f // allowed by covariance
    g("") // what should this do?


    The rule is still the same: "producer extends (covariant), consumer super (contravariant)". And a function is a consumer of its input type.






    share|improve this answer



























    • I was actually writing my own answer accordingly to the one written by JimmyJames, in almost exactly this format, when you posted it. Sometimes coincidences can be disappointing.

      – Louis-Jacob Lebel
      6 hours ago
















    5

















    does even the concept of variance make sense in an immutable environment?




    Yes; presence of subtyping is independent of immutability.




    could every type of a speculative fully immutable OOP language (like, all of them) be made covariant, regardless of where they are used (i.e. as function input types / function output types)?




    As a simple demonstration why function input types can't be covariant, with no mutability involved (using Scala syntax):



    val f: Int => Int = x => 2 * x
    val g: Any => Int = f // allowed by covariance
    g("") // what should this do?


    The rule is still the same: "producer extends (covariant), consumer super (contravariant)". And a function is a consumer of its input type.






    share|improve this answer



























    • I was actually writing my own answer accordingly to the one written by JimmyJames, in almost exactly this format, when you posted it. Sometimes coincidences can be disappointing.

      – Louis-Jacob Lebel
      6 hours ago














    5














    5










    5










    does even the concept of variance make sense in an immutable environment?




    Yes; presence of subtyping is independent of immutability.




    could every type of a speculative fully immutable OOP language (like, all of them) be made covariant, regardless of where they are used (i.e. as function input types / function output types)?




    As a simple demonstration why function input types can't be covariant, with no mutability involved (using Scala syntax):



    val f: Int => Int = x => 2 * x
    val g: Any => Int = f // allowed by covariance
    g("") // what should this do?


    The rule is still the same: "producer extends (covariant), consumer super (contravariant)". And a function is a consumer of its input type.






    share|improve this answer
















    does even the concept of variance make sense in an immutable environment?




    Yes; presence of subtyping is independent of immutability.




    could every type of a speculative fully immutable OOP language (like, all of them) be made covariant, regardless of where they are used (i.e. as function input types / function output types)?




    As a simple demonstration why function input types can't be covariant, with no mutability involved (using Scala syntax):



    val f: Int => Int = x => 2 * x
    val g: Any => Int = f // allowed by covariance
    g("") // what should this do?


    The rule is still the same: "producer extends (covariant), consumer super (contravariant)". And a function is a consumer of its input type.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 5 hours ago

























    answered 6 hours ago









    Alexey RomanovAlexey Romanov

    1,31410 silver badges14 bronze badges




    1,31410 silver badges14 bronze badges















    • I was actually writing my own answer accordingly to the one written by JimmyJames, in almost exactly this format, when you posted it. Sometimes coincidences can be disappointing.

      – Louis-Jacob Lebel
      6 hours ago


















    • I was actually writing my own answer accordingly to the one written by JimmyJames, in almost exactly this format, when you posted it. Sometimes coincidences can be disappointing.

      – Louis-Jacob Lebel
      6 hours ago

















    I was actually writing my own answer accordingly to the one written by JimmyJames, in almost exactly this format, when you posted it. Sometimes coincidences can be disappointing.

    – Louis-Jacob Lebel
    6 hours ago






    I was actually writing my own answer accordingly to the one written by JimmyJames, in almost exactly this format, when you posted it. Sometimes coincidences can be disappointing.

    – Louis-Jacob Lebel
    6 hours ago














    5
















    Variance has nothing to do with mutability. It appears at the intersection of parametric polymorphism and subtyping.



    The oldest example of variance is actually an example that comes out of functional programming, namely the question: when is a function type a subtype of another function type?



    And it turns out that a function type is a subtype of another function type if its inputs are at least as general and its outputs at least as specific as the supertype.



    In other words, functions are contravariant in their inputs and covariant in their outputs.






    share|improve this answer





























      5
















      Variance has nothing to do with mutability. It appears at the intersection of parametric polymorphism and subtyping.



      The oldest example of variance is actually an example that comes out of functional programming, namely the question: when is a function type a subtype of another function type?



      And it turns out that a function type is a subtype of another function type if its inputs are at least as general and its outputs at least as specific as the supertype.



      In other words, functions are contravariant in their inputs and covariant in their outputs.






      share|improve this answer



























        5














        5










        5









        Variance has nothing to do with mutability. It appears at the intersection of parametric polymorphism and subtyping.



        The oldest example of variance is actually an example that comes out of functional programming, namely the question: when is a function type a subtype of another function type?



        And it turns out that a function type is a subtype of another function type if its inputs are at least as general and its outputs at least as specific as the supertype.



        In other words, functions are contravariant in their inputs and covariant in their outputs.






        share|improve this answer













        Variance has nothing to do with mutability. It appears at the intersection of parametric polymorphism and subtyping.



        The oldest example of variance is actually an example that comes out of functional programming, namely the question: when is a function type a subtype of another function type?



        And it turns out that a function type is a subtype of another function type if its inputs are at least as general and its outputs at least as specific as the supertype.



        In other words, functions are contravariant in their inputs and covariant in their outputs.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 6 hours ago









        Jörg W MittagJörg W Mittag

        72.9k16 gold badges158 silver badges238 bronze badges




        72.9k16 gold badges158 silver badges238 bronze badges
























            1
















            Suppose you have a function that takes a list/array and a comparison function and returns a new one with the items sorted. If I have a list of Integers objects, I need a function that can sort integers: compare(a,b). With variance-free typing, I either have to specify that the function must take integers compare(a: Integer, a:Integer) or that it must take a specific super-type of integer e.g. compare(a: Object, a:Object). But what if I have a comparison defined as compare(a: Number, b: Number)? It should work fine but I can't use it in either case. So we need to be able to specify that the comparison function needs to be able to handle Integer or any superclass of Integer i.e. contra-variance.






            share|improve this answer

























            • Just to be sure, in your example compare(a: Number, b: Number), is Number assumed to not be a supertype of Integer?

              – Louis-Jacob Lebel
              7 hours ago











            • Number is assumed to be a superclass of Integer.

              – JimmyJames
              7 hours ago











            • I'm not sure then why compare(a: Number, b: Number) would not work where compare(a: Object, b: Object) would. Also, I'm not sure what you mean by "It should work fine but I can't use it in either case", maybe that's what I'm missing?

              – Louis-Jacob Lebel
              7 hours ago












            • A comparison function defined as compare(a: Object, b:Object) must be able to compare any two objects e.g. two Strings or a String and a List. compare(a: Number, b: Number) doesn't accept Strings or Lists.

              – JimmyJames
              7 hours ago











            • Sorry, I meant in the context of an Integer application, which I thought was what you meant in your answer. So lets say we have sort(c: OrderedCollection[Integer], compare: (T, T) => T), then as long as T is a supertype of Integer there is no type error. Outside of this context, then indeed you seem to be right. Anyways, even if not everything was clear to me in your answer, I got a clear answer to my questions.

              – Louis-Jacob Lebel
              7 hours ago
















            1
















            Suppose you have a function that takes a list/array and a comparison function and returns a new one with the items sorted. If I have a list of Integers objects, I need a function that can sort integers: compare(a,b). With variance-free typing, I either have to specify that the function must take integers compare(a: Integer, a:Integer) or that it must take a specific super-type of integer e.g. compare(a: Object, a:Object). But what if I have a comparison defined as compare(a: Number, b: Number)? It should work fine but I can't use it in either case. So we need to be able to specify that the comparison function needs to be able to handle Integer or any superclass of Integer i.e. contra-variance.






            share|improve this answer

























            • Just to be sure, in your example compare(a: Number, b: Number), is Number assumed to not be a supertype of Integer?

              – Louis-Jacob Lebel
              7 hours ago











            • Number is assumed to be a superclass of Integer.

              – JimmyJames
              7 hours ago











            • I'm not sure then why compare(a: Number, b: Number) would not work where compare(a: Object, b: Object) would. Also, I'm not sure what you mean by "It should work fine but I can't use it in either case", maybe that's what I'm missing?

              – Louis-Jacob Lebel
              7 hours ago












            • A comparison function defined as compare(a: Object, b:Object) must be able to compare any two objects e.g. two Strings or a String and a List. compare(a: Number, b: Number) doesn't accept Strings or Lists.

              – JimmyJames
              7 hours ago











            • Sorry, I meant in the context of an Integer application, which I thought was what you meant in your answer. So lets say we have sort(c: OrderedCollection[Integer], compare: (T, T) => T), then as long as T is a supertype of Integer there is no type error. Outside of this context, then indeed you seem to be right. Anyways, even if not everything was clear to me in your answer, I got a clear answer to my questions.

              – Louis-Jacob Lebel
              7 hours ago














            1














            1










            1









            Suppose you have a function that takes a list/array and a comparison function and returns a new one with the items sorted. If I have a list of Integers objects, I need a function that can sort integers: compare(a,b). With variance-free typing, I either have to specify that the function must take integers compare(a: Integer, a:Integer) or that it must take a specific super-type of integer e.g. compare(a: Object, a:Object). But what if I have a comparison defined as compare(a: Number, b: Number)? It should work fine but I can't use it in either case. So we need to be able to specify that the comparison function needs to be able to handle Integer or any superclass of Integer i.e. contra-variance.






            share|improve this answer













            Suppose you have a function that takes a list/array and a comparison function and returns a new one with the items sorted. If I have a list of Integers objects, I need a function that can sort integers: compare(a,b). With variance-free typing, I either have to specify that the function must take integers compare(a: Integer, a:Integer) or that it must take a specific super-type of integer e.g. compare(a: Object, a:Object). But what if I have a comparison defined as compare(a: Number, b: Number)? It should work fine but I can't use it in either case. So we need to be able to specify that the comparison function needs to be able to handle Integer or any superclass of Integer i.e. contra-variance.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 7 hours ago









            JimmyJamesJimmyJames

            14.6k1 gold badge27 silver badges55 bronze badges




            14.6k1 gold badge27 silver badges55 bronze badges















            • Just to be sure, in your example compare(a: Number, b: Number), is Number assumed to not be a supertype of Integer?

              – Louis-Jacob Lebel
              7 hours ago











            • Number is assumed to be a superclass of Integer.

              – JimmyJames
              7 hours ago











            • I'm not sure then why compare(a: Number, b: Number) would not work where compare(a: Object, b: Object) would. Also, I'm not sure what you mean by "It should work fine but I can't use it in either case", maybe that's what I'm missing?

              – Louis-Jacob Lebel
              7 hours ago












            • A comparison function defined as compare(a: Object, b:Object) must be able to compare any two objects e.g. two Strings or a String and a List. compare(a: Number, b: Number) doesn't accept Strings or Lists.

              – JimmyJames
              7 hours ago











            • Sorry, I meant in the context of an Integer application, which I thought was what you meant in your answer. So lets say we have sort(c: OrderedCollection[Integer], compare: (T, T) => T), then as long as T is a supertype of Integer there is no type error. Outside of this context, then indeed you seem to be right. Anyways, even if not everything was clear to me in your answer, I got a clear answer to my questions.

              – Louis-Jacob Lebel
              7 hours ago


















            • Just to be sure, in your example compare(a: Number, b: Number), is Number assumed to not be a supertype of Integer?

              – Louis-Jacob Lebel
              7 hours ago











            • Number is assumed to be a superclass of Integer.

              – JimmyJames
              7 hours ago











            • I'm not sure then why compare(a: Number, b: Number) would not work where compare(a: Object, b: Object) would. Also, I'm not sure what you mean by "It should work fine but I can't use it in either case", maybe that's what I'm missing?

              – Louis-Jacob Lebel
              7 hours ago












            • A comparison function defined as compare(a: Object, b:Object) must be able to compare any two objects e.g. two Strings or a String and a List. compare(a: Number, b: Number) doesn't accept Strings or Lists.

              – JimmyJames
              7 hours ago











            • Sorry, I meant in the context of an Integer application, which I thought was what you meant in your answer. So lets say we have sort(c: OrderedCollection[Integer], compare: (T, T) => T), then as long as T is a supertype of Integer there is no type error. Outside of this context, then indeed you seem to be right. Anyways, even if not everything was clear to me in your answer, I got a clear answer to my questions.

              – Louis-Jacob Lebel
              7 hours ago

















            Just to be sure, in your example compare(a: Number, b: Number), is Number assumed to not be a supertype of Integer?

            – Louis-Jacob Lebel
            7 hours ago





            Just to be sure, in your example compare(a: Number, b: Number), is Number assumed to not be a supertype of Integer?

            – Louis-Jacob Lebel
            7 hours ago













            Number is assumed to be a superclass of Integer.

            – JimmyJames
            7 hours ago





            Number is assumed to be a superclass of Integer.

            – JimmyJames
            7 hours ago













            I'm not sure then why compare(a: Number, b: Number) would not work where compare(a: Object, b: Object) would. Also, I'm not sure what you mean by "It should work fine but I can't use it in either case", maybe that's what I'm missing?

            – Louis-Jacob Lebel
            7 hours ago






            I'm not sure then why compare(a: Number, b: Number) would not work where compare(a: Object, b: Object) would. Also, I'm not sure what you mean by "It should work fine but I can't use it in either case", maybe that's what I'm missing?

            – Louis-Jacob Lebel
            7 hours ago














            A comparison function defined as compare(a: Object, b:Object) must be able to compare any two objects e.g. two Strings or a String and a List. compare(a: Number, b: Number) doesn't accept Strings or Lists.

            – JimmyJames
            7 hours ago





            A comparison function defined as compare(a: Object, b:Object) must be able to compare any two objects e.g. two Strings or a String and a List. compare(a: Number, b: Number) doesn't accept Strings or Lists.

            – JimmyJames
            7 hours ago













            Sorry, I meant in the context of an Integer application, which I thought was what you meant in your answer. So lets say we have sort(c: OrderedCollection[Integer], compare: (T, T) => T), then as long as T is a supertype of Integer there is no type error. Outside of this context, then indeed you seem to be right. Anyways, even if not everything was clear to me in your answer, I got a clear answer to my questions.

            – Louis-Jacob Lebel
            7 hours ago






            Sorry, I meant in the context of an Integer application, which I thought was what you meant in your answer. So lets say we have sort(c: OrderedCollection[Integer], compare: (T, T) => T), then as long as T is a supertype of Integer there is no type error. Outside of this context, then indeed you seem to be right. Anyways, even if not everything was clear to me in your answer, I got a clear answer to my questions.

            – Louis-Jacob Lebel
            7 hours ago












            Louis-Jacob Lebel is a new contributor. Be nice, and check out our Code of Conduct.









            draft saved

            draft discarded

















            Louis-Jacob Lebel is a new contributor. Be nice, and check out our Code of Conduct.












            Louis-Jacob Lebel is a new contributor. Be nice, and check out our Code of Conduct.











            Louis-Jacob Lebel is a new contributor. Be nice, and check out our Code of Conduct.














            Thanks for contributing an answer to Software Engineering Stack Exchange!


            • 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%2fsoftwareengineering.stackexchange.com%2fquestions%2f398770%2fdoes-variance-make-sense-in-a-fully-immutable-language%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

            Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

            Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

            François Viète Contents Biography Work and thought Bibliography See also Notes Further reading External links Navigation menup. 21Google Bookspp. 75–77Google BooksDe thou (from University of Saint Andrews)ArchivedGoogle BooksGoogle BooksGoogle BooksGoogle booksGoogle Bookscc-parthenay.frL'histoire universelle (fr)Universal History (en)ArchivedAdsabs.harvard.eduPagesperso-orange.frArchive.orgChikara Sasaki. Descartes' mathematical thought p.259Google BooksGoogle BooksGoogle Bookspp. 152 and onwardGoogle BooksGoogle BooksScribd.comGoogle Books1257-7979Google BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGallica.bnf.frGoogle BooksGoogle Books"François Viète"Francois Viète: Father of Modern Algebraic NotationThe Lawyer and the GamblerAbout TarporleySite de Jean-Paul GuichardL'algèbre nouvelle"About the Harmonicon"cb120511976(data)1188044800000 0001 0913 5903n82164680ola2013766880073431702w6vt1sb70287374827140948071409480