Would it be a good idea to add a language.autoTupling option?
--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-debate...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
scala> m.map({case (key, value) => (key+1, value+1)})
res1: scala.collection.immutable.Map[Int,Int] = Map(2 -> 3)
I mean ... what the hell?! We know it's type exactly ... why do we force people to use pattern matching/partial functions for something this simple?
And in the same turn, I wonder why we didn't manage to make parameter lists work in a less painful way if we decided to mass with tupling in the first place.
Imho, one of Scala's biggest warts is still this:
scala> val m = Map(1 -> 2)
m: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2)
scala> m.map((key, value) => (key+1, value+1))
<console>:9: error: missing parameter type
m.map((key, value) => (key+1, value+1))
^
<console>:9: error: missing parameter type
m.map((key, value) => (key+1, value+1))
^
scala> m.map(((key, value)) => (key+1, value+1))
<console>:1: error: not a legal formal parameter
m.map(((key, value)) => (key+1, value+1))
^
scala> m.map({case (key, value) => (key+1, value+1)})
res1: scala.collection.immutable.Map[Int,Int] = Map(2 -> 3)
I mean ... what the hell?! We know it's type exactly ... why do we force people to use pattern matching/partial functions for something this simple?
--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-debate...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
On Thu, Nov 28, 2013 at 6:56 PM, Simon Ochsenreither <simon.och...@gmail.com> wrote:
And in the same turn, I wonder why we didn't manage to make parameter lists work in a less painful way if we decided to mass with tupling in the first place.
Imho, one of Scala's biggest warts is still this:
scala> val m = Map(1 -> 2)
m: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2)
scala> m.map((key, value) => (key+1, value+1))
<console>:9: error: missing parameter type
m.map((key, value) => (key+1, value+1))
^
<console>:9: error: missing parameter type
m.map((key, value) => (key+1, value+1))
^
scala> m.map(((key, value)) => (key+1, value+1))
<console>:1: error: not a legal formal parameter
m.map(((key, value)) => (key+1, value+1))
^
Yes, I am with you. We should at a minimum give a more helpful error message. The automatic tupling conversion was an attempt to get there eventually, so that you would not need to distinguish between case pattern and tuples. But it got stuck halfway in no-man's land (and gave us an appreciation that doing it right is not so easy, after all).
Yes, I am with you. We should at a minimum give a more helpful error message. The automatic tupling conversion was an attempt to get there eventually, so that you would not need to distinguish between case pattern and tuples. But it got stuck halfway in no-man's land (and gave us an appreciation that doing it right is not so easy, after all).Here's a better error message for the first case:
IIRC, the problem with turning it off altogether is with infix calls:val x: Buffer[(Int, Int)] = ...x += (1, 2)This is initially typechecked as `x.+=(1, 2)`, and then tupled to match the one-argument method `+=`.
IIRC, the problem with turning it off altogether is with infix calls:val x: Buffer[(Int, Int)] = ...x += (1, 2)This is initially typechecked as `x.+=(1, 2)`, and then tupled to match the one-argument method `+=`.
I threw in a better message for the second case, too:Simon: could you please review the new error messages?
IIRC, the problem with turning it off altogether is with infix calls:val x: Buffer[(Int, Int)] = ...x += (1, 2)This is initially typechecked as `x.+=(1, 2)`, and then tupled to match the one-argument method `+=`.
But here, solely the overloaded method signature ofdef +=(elem1: A, elem2: A, elems: A*): ArrayBuffer.this.type
is to blame, which is an utter disaster and completely incoherent with the reasoning about += vs. ++=.
If I use +=, I want to add a single argument, not multiple ones.
I'm pretty sure I wrote something about that some while ago, too. I'm actually surprised that it hasn't been deprecated yet.
--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-debate...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
The example I was searching for was:scala> val x = Set[(Int, Int)]()x: scala.collection.immutable.Set[(Int, Int)] = Set()
scala> x contains (1, 2)res10: Boolean = falseI'm not sure that we can require an opt-in for this particular case.
I wouldn't interpret this as a failure of the collections library. Instead, I would view it as a mismatch between the compiler's interpretation of such commands and intuition.To me,x contains (1, 2)x += (1, 2)both look likeinstance method tuplenotinstance method (arg1, arg2)
--
I agree with Rex. Infix notation usually has one operand on the right. If it opens with a parenthesis then it's a tuple.I don't mind badly if the compiler auto-detuples though. So the slice case would work, not because you passed two operands, but because being that slice does not take a Tuple2 the compiler would reinterpret it as separate method arguments. After all, that is how it intuitively appears to work. But I don't see much advantage to allowing it.
On Fri, Nov 29, 2013 at 7:56 AM, Rex Kerr <ich...@gmail.com> wrote:
I wouldn't interpret this as a failure of the collections library. Instead, I would view it as a mismatch between the compiler's interpretation of such commands and intuition.To me,x contains (1, 2)x += (1, 2)both look likeinstance method tuplenotinstance method (arg1, arg2)Is that intuition because you're mentally type checking and parsing simultaneously? What about the following?"abcd" slice (1, 2)res1: String = b
Right now, the parser erases the knowledge of whether infix of dotted method call syntax was used.
It also is unable to know anything about the type of the method being called.
So somehow I think we're a bit stuck. In your example, we'd need to introduce auto-detupling for the call to `slice`.
But I do think we could phase out auto-tupling for cases when the expected type is a Any, rather than specifically TupleN. Not sure how easy it will be to implement that situational deprecation, but I'll give it a shot.
List(1, 2, 3).toSet()would be rewritten toList(1, 2, 3).toSet(())
Once we have a program like this, we could add more rules. E.g. put all XML literals in triple quotes. Rewrite procedure syntax, and so on.
Just wanted to say that I think union and intersection types are very interesting and powerful. Also agreed on the fact that Tuple22 and friends are not ideal. We are looking for ways to avoid that in a future version of Scala. I am certainly very interested in what you and the Ceylon community do in terms of language design and hope we can learn from each other.
--
Imho, we should really treat () insertion and auto-tupling separately. There might be non-erroneous code using auto-tupling, but I haven't seen non-erroneous code using () insertion. Additionally, the occurrences of () insertion seem to be a lot less frequent than even auto-tupling.
I did a few commits some time ago making the compiler warning/lint/feature clean, and I think I didn't found a single case of () insertion:
https://github.com/scala/scala/commit/0459db43728e1dc38c3a1db6b7b1920810d0f858
https://github.com/scala/scala/commit/f2de2c4ec43180351ef1f306bcc5f24643ba5477
https://github.com/scala/scala/commit/f670e28d4da648511063c6825905c4960ee94445
https://github.com/scala/scala/commit/7943084a2d06e21f112b4efd0ab70ec6e38ce510
I suggest just moving forward on this. Compared to other things we fixed in the past and never got any complaint, this should be a low-impact change.
--
You received this message because you are subscribed to the Google Groups "scala-debate" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-debate...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
Is anybody aware of code that uses auto-tupling intentionally in the wild?
This use is slightly different form as it is not using dot method invocation. When I first found infix notation I was supprised to find it working for anything other than arity-1 methods.
Matthew
Sent from my android - may contain predictive text entertainment.
--
Yes, agreed. I'd be for deprecating ()-insertion now.
Imho, one of Scala's biggest warts is still this:
scala> val m = Map(1 -> 2)
m: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2)
scala> m.map((key, value) => (key+1, value+1))
<console>:9: error: missing parameter type
m.map((key, value) => (key+1, value+1))
^
<console>:9: error: missing parameter type
m.map((key, value) => (key+1, value+1))
^
scala> m.map(((key, value)) => (key+1, value+1))
<console>:1: error: not a legal formal parameter
m.map(((key, value)) => (key+1, value+1))
^
scala> m.map({case (key, value) => (key+1, value+1)})
res1: scala.collection.immutable.Map[Int,Int] = Map(2 -> 3)
I mean ... what the hell?! We know it's type exactly ... why do we force people to use pattern matching/partial functions for something this simple?
--
Function.tupled transforms an n-argument function into a 1-argument function where that argument is a tuple
with the n arguments as members:
Named and default arguments exist for methods, not functions. So you could still replace FunctionN with Function[TupleN, _], and update method-to-function conversion accordingly...