Why is the ++: operator in the Scala language so strange?












3















I am using the ++: operator to get a collection of two collections, but the results I get using these two methods are inconsistent:



scala> var r = Array(1, 2)
r: Array[Int] = Array(1, 2)
scala> r ++:= Array(3)
scala> r
res28: Array[Int] = Array(3, 1, 2)

scala> Array(1, 2) ++: Array(3)
res29: Array[Int] = Array(1, 2, 3)


Why do the ++: and ++:= operators give different results?
This kind of difference does not appear with the ++ operator.



The version of Scala I am using is 2.11.8.










share|improve this question

























  • Another interesting effect of ++: and ++:= is that it takes the type of the result collection from the right-hand side (in case they are not both Arrays as here, stackoverflow.com/a/24338494/14955) --- for some definition of "right-hand" in the presence of ++:=.

    – Thilo
    Nov 16 '18 at 6:56


















3















I am using the ++: operator to get a collection of two collections, but the results I get using these two methods are inconsistent:



scala> var r = Array(1, 2)
r: Array[Int] = Array(1, 2)
scala> r ++:= Array(3)
scala> r
res28: Array[Int] = Array(3, 1, 2)

scala> Array(1, 2) ++: Array(3)
res29: Array[Int] = Array(1, 2, 3)


Why do the ++: and ++:= operators give different results?
This kind of difference does not appear with the ++ operator.



The version of Scala I am using is 2.11.8.










share|improve this question

























  • Another interesting effect of ++: and ++:= is that it takes the type of the result collection from the right-hand side (in case they are not both Arrays as here, stackoverflow.com/a/24338494/14955) --- for some definition of "right-hand" in the presence of ++:=.

    – Thilo
    Nov 16 '18 at 6:56
















3












3








3








I am using the ++: operator to get a collection of two collections, but the results I get using these two methods are inconsistent:



scala> var r = Array(1, 2)
r: Array[Int] = Array(1, 2)
scala> r ++:= Array(3)
scala> r
res28: Array[Int] = Array(3, 1, 2)

scala> Array(1, 2) ++: Array(3)
res29: Array[Int] = Array(1, 2, 3)


Why do the ++: and ++:= operators give different results?
This kind of difference does not appear with the ++ operator.



The version of Scala I am using is 2.11.8.










share|improve this question
















I am using the ++: operator to get a collection of two collections, but the results I get using these two methods are inconsistent:



scala> var r = Array(1, 2)
r: Array[Int] = Array(1, 2)
scala> r ++:= Array(3)
scala> r
res28: Array[Int] = Array(3, 1, 2)

scala> Array(1, 2) ++: Array(3)
res29: Array[Int] = Array(1, 2, 3)


Why do the ++: and ++:= operators give different results?
This kind of difference does not appear with the ++ operator.



The version of Scala I am using is 2.11.8.







arrays scala collections assignment-operator






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 16 '18 at 7:36









Brian McCutchon

4,77722136




4,77722136










asked Nov 16 '18 at 6:09









xuejianbestxuejianbest

1435




1435













  • Another interesting effect of ++: and ++:= is that it takes the type of the result collection from the right-hand side (in case they are not both Arrays as here, stackoverflow.com/a/24338494/14955) --- for some definition of "right-hand" in the presence of ++:=.

    – Thilo
    Nov 16 '18 at 6:56





















  • Another interesting effect of ++: and ++:= is that it takes the type of the result collection from the right-hand side (in case they are not both Arrays as here, stackoverflow.com/a/24338494/14955) --- for some definition of "right-hand" in the presence of ++:=.

    – Thilo
    Nov 16 '18 at 6:56



















Another interesting effect of ++: and ++:= is that it takes the type of the result collection from the right-hand side (in case they are not both Arrays as here, stackoverflow.com/a/24338494/14955) --- for some definition of "right-hand" in the presence of ++:=.

– Thilo
Nov 16 '18 at 6:56







Another interesting effect of ++: and ++:= is that it takes the type of the result collection from the right-hand side (in case they are not both Arrays as here, stackoverflow.com/a/24338494/14955) --- for some definition of "right-hand" in the presence of ++:=.

– Thilo
Nov 16 '18 at 6:56














2 Answers
2






active

oldest

votes


















6














Since it ends in a colon, ++: is right-associative. This means that Array(1, 2) ++: Array(3) is equivalent to Array(3).++:(Array(1, 2)). ++: can be thought of as "prepend the elements of the left array to the right array."



Since it's right-associative, r ++:= Array(3) desugars to r = Array(3) ++: r. This makes sense when you consider that the purpose of ++: is prepending. This desugaring holds true for any operator that ends in a colon.



If you want to append, you can use ++ (and ++=).






share|improve this answer





















  • 4





    @Thilo +:, ::, and ::: come to mind. Again, it's anything that ends in a colon.

    – Brian McCutchon
    Nov 16 '18 at 6:55






  • 2





    @Thilo: There is no such thing as an "operator" in Scala. Any method can be called without a period like this: a foo(bar, baz), and when you are passing only one argument, you can leave out the parenthesis like this: a foo bar. That's it. It's just a normal method call, and ++ is just a normal method name like foo. There are two exceptions, though, that mean that Scala actually does have "half-operators". 1) Precedence is determined by the first character of the method name. 2) Methods ending in a : are right-associative when called with operator syntax.

    – Jörg W Mittag
    Nov 16 '18 at 7:44






  • 2





    Note: this also applies to Type Constructors. So, if you have class Foo[A, B] {}, then you can of course say def foo: Foo[Int, String], but you can also say def foo: Int Foo String, and if you have class Foo_:[A, B], then Foo_:[Int, String] is the same as String Foo_: Int.

    – Jörg W Mittag
    Nov 16 '18 at 7:47








  • 1





    Ah, sorry. My bad. :: is unary, not binary. But probably someone is doing that.

    – Jörg W Mittag
    Nov 16 '18 at 10:51






  • 1





    @JörgWMittag Type constructors can be right-associative (shapeless.:: is an example), but they don't swap the order of their arguments in that case (thankfully).

    – Brian McCutchon
    Nov 16 '18 at 18:31



















1














Here colon(:) means that the function has right associativity



so, for instance coll1 ++: coll2 is similar to (coll2).++:(coll1)



Which generally means the elements of the left collection is prepended to right collection



Case-1:



Array(1,2) ++: Array(3)
Array(3).++:Array(1,2)
Elements of the left array is prepended to the right array
so the result would be Array(3,1,2)


Case-2:



 r = Array(1,2)
r ++:= Array(3) //This could also be written as the line of code below
r = Array(3) ++: r
= r. ++: Array(3)
= Array(1,2). ++: Array(3) //Elements of the left array is prepended to the right array
so their result would be Array(1,2,3)


Hope this solves the query
Thank you :)






share|improve this answer


























  • ++: is a method, not a function.

    – Brian McCutchon
    Nov 16 '18 at 7:52











  • Edited as per the suggestion thanks @BrianMcCutchon

    – prasanna kumar
    Nov 16 '18 at 7:54











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%2f53332346%2fwhy-is-the-operator-in-the-scala-language-so-strange%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









6














Since it ends in a colon, ++: is right-associative. This means that Array(1, 2) ++: Array(3) is equivalent to Array(3).++:(Array(1, 2)). ++: can be thought of as "prepend the elements of the left array to the right array."



Since it's right-associative, r ++:= Array(3) desugars to r = Array(3) ++: r. This makes sense when you consider that the purpose of ++: is prepending. This desugaring holds true for any operator that ends in a colon.



If you want to append, you can use ++ (and ++=).






share|improve this answer





















  • 4





    @Thilo +:, ::, and ::: come to mind. Again, it's anything that ends in a colon.

    – Brian McCutchon
    Nov 16 '18 at 6:55






  • 2





    @Thilo: There is no such thing as an "operator" in Scala. Any method can be called without a period like this: a foo(bar, baz), and when you are passing only one argument, you can leave out the parenthesis like this: a foo bar. That's it. It's just a normal method call, and ++ is just a normal method name like foo. There are two exceptions, though, that mean that Scala actually does have "half-operators". 1) Precedence is determined by the first character of the method name. 2) Methods ending in a : are right-associative when called with operator syntax.

    – Jörg W Mittag
    Nov 16 '18 at 7:44






  • 2





    Note: this also applies to Type Constructors. So, if you have class Foo[A, B] {}, then you can of course say def foo: Foo[Int, String], but you can also say def foo: Int Foo String, and if you have class Foo_:[A, B], then Foo_:[Int, String] is the same as String Foo_: Int.

    – Jörg W Mittag
    Nov 16 '18 at 7:47








  • 1





    Ah, sorry. My bad. :: is unary, not binary. But probably someone is doing that.

    – Jörg W Mittag
    Nov 16 '18 at 10:51






  • 1





    @JörgWMittag Type constructors can be right-associative (shapeless.:: is an example), but they don't swap the order of their arguments in that case (thankfully).

    – Brian McCutchon
    Nov 16 '18 at 18:31
















6














Since it ends in a colon, ++: is right-associative. This means that Array(1, 2) ++: Array(3) is equivalent to Array(3).++:(Array(1, 2)). ++: can be thought of as "prepend the elements of the left array to the right array."



Since it's right-associative, r ++:= Array(3) desugars to r = Array(3) ++: r. This makes sense when you consider that the purpose of ++: is prepending. This desugaring holds true for any operator that ends in a colon.



If you want to append, you can use ++ (and ++=).






share|improve this answer





















  • 4





    @Thilo +:, ::, and ::: come to mind. Again, it's anything that ends in a colon.

    – Brian McCutchon
    Nov 16 '18 at 6:55






  • 2





    @Thilo: There is no such thing as an "operator" in Scala. Any method can be called without a period like this: a foo(bar, baz), and when you are passing only one argument, you can leave out the parenthesis like this: a foo bar. That's it. It's just a normal method call, and ++ is just a normal method name like foo. There are two exceptions, though, that mean that Scala actually does have "half-operators". 1) Precedence is determined by the first character of the method name. 2) Methods ending in a : are right-associative when called with operator syntax.

    – Jörg W Mittag
    Nov 16 '18 at 7:44






  • 2





    Note: this also applies to Type Constructors. So, if you have class Foo[A, B] {}, then you can of course say def foo: Foo[Int, String], but you can also say def foo: Int Foo String, and if you have class Foo_:[A, B], then Foo_:[Int, String] is the same as String Foo_: Int.

    – Jörg W Mittag
    Nov 16 '18 at 7:47








  • 1





    Ah, sorry. My bad. :: is unary, not binary. But probably someone is doing that.

    – Jörg W Mittag
    Nov 16 '18 at 10:51






  • 1





    @JörgWMittag Type constructors can be right-associative (shapeless.:: is an example), but they don't swap the order of their arguments in that case (thankfully).

    – Brian McCutchon
    Nov 16 '18 at 18:31














6












6








6







Since it ends in a colon, ++: is right-associative. This means that Array(1, 2) ++: Array(3) is equivalent to Array(3).++:(Array(1, 2)). ++: can be thought of as "prepend the elements of the left array to the right array."



Since it's right-associative, r ++:= Array(3) desugars to r = Array(3) ++: r. This makes sense when you consider that the purpose of ++: is prepending. This desugaring holds true for any operator that ends in a colon.



If you want to append, you can use ++ (and ++=).






share|improve this answer















Since it ends in a colon, ++: is right-associative. This means that Array(1, 2) ++: Array(3) is equivalent to Array(3).++:(Array(1, 2)). ++: can be thought of as "prepend the elements of the left array to the right array."



Since it's right-associative, r ++:= Array(3) desugars to r = Array(3) ++: r. This makes sense when you consider that the purpose of ++: is prepending. This desugaring holds true for any operator that ends in a colon.



If you want to append, you can use ++ (and ++=).







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 16 '18 at 6:59

























answered Nov 16 '18 at 6:45









Brian McCutchonBrian McCutchon

4,77722136




4,77722136








  • 4





    @Thilo +:, ::, and ::: come to mind. Again, it's anything that ends in a colon.

    – Brian McCutchon
    Nov 16 '18 at 6:55






  • 2





    @Thilo: There is no such thing as an "operator" in Scala. Any method can be called without a period like this: a foo(bar, baz), and when you are passing only one argument, you can leave out the parenthesis like this: a foo bar. That's it. It's just a normal method call, and ++ is just a normal method name like foo. There are two exceptions, though, that mean that Scala actually does have "half-operators". 1) Precedence is determined by the first character of the method name. 2) Methods ending in a : are right-associative when called with operator syntax.

    – Jörg W Mittag
    Nov 16 '18 at 7:44






  • 2





    Note: this also applies to Type Constructors. So, if you have class Foo[A, B] {}, then you can of course say def foo: Foo[Int, String], but you can also say def foo: Int Foo String, and if you have class Foo_:[A, B], then Foo_:[Int, String] is the same as String Foo_: Int.

    – Jörg W Mittag
    Nov 16 '18 at 7:47








  • 1





    Ah, sorry. My bad. :: is unary, not binary. But probably someone is doing that.

    – Jörg W Mittag
    Nov 16 '18 at 10:51






  • 1





    @JörgWMittag Type constructors can be right-associative (shapeless.:: is an example), but they don't swap the order of their arguments in that case (thankfully).

    – Brian McCutchon
    Nov 16 '18 at 18:31














  • 4





    @Thilo +:, ::, and ::: come to mind. Again, it's anything that ends in a colon.

    – Brian McCutchon
    Nov 16 '18 at 6:55






  • 2





    @Thilo: There is no such thing as an "operator" in Scala. Any method can be called without a period like this: a foo(bar, baz), and when you are passing only one argument, you can leave out the parenthesis like this: a foo bar. That's it. It's just a normal method call, and ++ is just a normal method name like foo. There are two exceptions, though, that mean that Scala actually does have "half-operators". 1) Precedence is determined by the first character of the method name. 2) Methods ending in a : are right-associative when called with operator syntax.

    – Jörg W Mittag
    Nov 16 '18 at 7:44






  • 2





    Note: this also applies to Type Constructors. So, if you have class Foo[A, B] {}, then you can of course say def foo: Foo[Int, String], but you can also say def foo: Int Foo String, and if you have class Foo_:[A, B], then Foo_:[Int, String] is the same as String Foo_: Int.

    – Jörg W Mittag
    Nov 16 '18 at 7:47








  • 1





    Ah, sorry. My bad. :: is unary, not binary. But probably someone is doing that.

    – Jörg W Mittag
    Nov 16 '18 at 10:51






  • 1





    @JörgWMittag Type constructors can be right-associative (shapeless.:: is an example), but they don't swap the order of their arguments in that case (thankfully).

    – Brian McCutchon
    Nov 16 '18 at 18:31








4




4





@Thilo +:, ::, and ::: come to mind. Again, it's anything that ends in a colon.

– Brian McCutchon
Nov 16 '18 at 6:55





@Thilo +:, ::, and ::: come to mind. Again, it's anything that ends in a colon.

– Brian McCutchon
Nov 16 '18 at 6:55




2




2





@Thilo: There is no such thing as an "operator" in Scala. Any method can be called without a period like this: a foo(bar, baz), and when you are passing only one argument, you can leave out the parenthesis like this: a foo bar. That's it. It's just a normal method call, and ++ is just a normal method name like foo. There are two exceptions, though, that mean that Scala actually does have "half-operators". 1) Precedence is determined by the first character of the method name. 2) Methods ending in a : are right-associative when called with operator syntax.

– Jörg W Mittag
Nov 16 '18 at 7:44





@Thilo: There is no such thing as an "operator" in Scala. Any method can be called without a period like this: a foo(bar, baz), and when you are passing only one argument, you can leave out the parenthesis like this: a foo bar. That's it. It's just a normal method call, and ++ is just a normal method name like foo. There are two exceptions, though, that mean that Scala actually does have "half-operators". 1) Precedence is determined by the first character of the method name. 2) Methods ending in a : are right-associative when called with operator syntax.

– Jörg W Mittag
Nov 16 '18 at 7:44




2




2





Note: this also applies to Type Constructors. So, if you have class Foo[A, B] {}, then you can of course say def foo: Foo[Int, String], but you can also say def foo: Int Foo String, and if you have class Foo_:[A, B], then Foo_:[Int, String] is the same as String Foo_: Int.

– Jörg W Mittag
Nov 16 '18 at 7:47







Note: this also applies to Type Constructors. So, if you have class Foo[A, B] {}, then you can of course say def foo: Foo[Int, String], but you can also say def foo: Int Foo String, and if you have class Foo_:[A, B], then Foo_:[Int, String] is the same as String Foo_: Int.

– Jörg W Mittag
Nov 16 '18 at 7:47






1




1





Ah, sorry. My bad. :: is unary, not binary. But probably someone is doing that.

– Jörg W Mittag
Nov 16 '18 at 10:51





Ah, sorry. My bad. :: is unary, not binary. But probably someone is doing that.

– Jörg W Mittag
Nov 16 '18 at 10:51




1




1





@JörgWMittag Type constructors can be right-associative (shapeless.:: is an example), but they don't swap the order of their arguments in that case (thankfully).

– Brian McCutchon
Nov 16 '18 at 18:31





@JörgWMittag Type constructors can be right-associative (shapeless.:: is an example), but they don't swap the order of their arguments in that case (thankfully).

– Brian McCutchon
Nov 16 '18 at 18:31













1














Here colon(:) means that the function has right associativity



so, for instance coll1 ++: coll2 is similar to (coll2).++:(coll1)



Which generally means the elements of the left collection is prepended to right collection



Case-1:



Array(1,2) ++: Array(3)
Array(3).++:Array(1,2)
Elements of the left array is prepended to the right array
so the result would be Array(3,1,2)


Case-2:



 r = Array(1,2)
r ++:= Array(3) //This could also be written as the line of code below
r = Array(3) ++: r
= r. ++: Array(3)
= Array(1,2). ++: Array(3) //Elements of the left array is prepended to the right array
so their result would be Array(1,2,3)


Hope this solves the query
Thank you :)






share|improve this answer


























  • ++: is a method, not a function.

    – Brian McCutchon
    Nov 16 '18 at 7:52











  • Edited as per the suggestion thanks @BrianMcCutchon

    – prasanna kumar
    Nov 16 '18 at 7:54
















1














Here colon(:) means that the function has right associativity



so, for instance coll1 ++: coll2 is similar to (coll2).++:(coll1)



Which generally means the elements of the left collection is prepended to right collection



Case-1:



Array(1,2) ++: Array(3)
Array(3).++:Array(1,2)
Elements of the left array is prepended to the right array
so the result would be Array(3,1,2)


Case-2:



 r = Array(1,2)
r ++:= Array(3) //This could also be written as the line of code below
r = Array(3) ++: r
= r. ++: Array(3)
= Array(1,2). ++: Array(3) //Elements of the left array is prepended to the right array
so their result would be Array(1,2,3)


Hope this solves the query
Thank you :)






share|improve this answer


























  • ++: is a method, not a function.

    – Brian McCutchon
    Nov 16 '18 at 7:52











  • Edited as per the suggestion thanks @BrianMcCutchon

    – prasanna kumar
    Nov 16 '18 at 7:54














1












1








1







Here colon(:) means that the function has right associativity



so, for instance coll1 ++: coll2 is similar to (coll2).++:(coll1)



Which generally means the elements of the left collection is prepended to right collection



Case-1:



Array(1,2) ++: Array(3)
Array(3).++:Array(1,2)
Elements of the left array is prepended to the right array
so the result would be Array(3,1,2)


Case-2:



 r = Array(1,2)
r ++:= Array(3) //This could also be written as the line of code below
r = Array(3) ++: r
= r. ++: Array(3)
= Array(1,2). ++: Array(3) //Elements of the left array is prepended to the right array
so their result would be Array(1,2,3)


Hope this solves the query
Thank you :)






share|improve this answer















Here colon(:) means that the function has right associativity



so, for instance coll1 ++: coll2 is similar to (coll2).++:(coll1)



Which generally means the elements of the left collection is prepended to right collection



Case-1:



Array(1,2) ++: Array(3)
Array(3).++:Array(1,2)
Elements of the left array is prepended to the right array
so the result would be Array(3,1,2)


Case-2:



 r = Array(1,2)
r ++:= Array(3) //This could also be written as the line of code below
r = Array(3) ++: r
= r. ++: Array(3)
= Array(1,2). ++: Array(3) //Elements of the left array is prepended to the right array
so their result would be Array(1,2,3)


Hope this solves the query
Thank you :)







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 16 '18 at 7:53

























answered Nov 16 '18 at 7:44









prasanna kumarprasanna kumar

978




978













  • ++: is a method, not a function.

    – Brian McCutchon
    Nov 16 '18 at 7:52











  • Edited as per the suggestion thanks @BrianMcCutchon

    – prasanna kumar
    Nov 16 '18 at 7:54



















  • ++: is a method, not a function.

    – Brian McCutchon
    Nov 16 '18 at 7:52











  • Edited as per the suggestion thanks @BrianMcCutchon

    – prasanna kumar
    Nov 16 '18 at 7:54

















++: is a method, not a function.

– Brian McCutchon
Nov 16 '18 at 7:52





++: is a method, not a function.

– Brian McCutchon
Nov 16 '18 at 7:52













Edited as per the suggestion thanks @BrianMcCutchon

– prasanna kumar
Nov 16 '18 at 7:54





Edited as per the suggestion thanks @BrianMcCutchon

– prasanna kumar
Nov 16 '18 at 7:54


















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.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53332346%2fwhy-is-the-operator-in-the-scala-language-so-strange%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

Bressuire

Vorschmack

Quarantine