any2stringadd killed my code

457 views
Skip to first unread message

Matthew Pocock

unread,
Jan 27, 2014, 9:13:30 AM1/27/14
to scala-user
GHA!!!!!

Again I had some code that was compiling and giving garbage results because of Predef.any2stringadd. Can this please die? Failing that, can we have a simple one-liner that disables it? It causes me nothing but woe.

Matthew

--
Dr Matthew Pocock
Turing ate my hamster LTD

Integrative Bioinformatics Group, School of Computing Science, Newcastle University

skype: matthew.pocock
tel: (0191) 2566550

Flavio W. Brasil

unread,
Jan 27, 2014, 9:35:08 AM1/27/14
to scala-user
+1!

-- 
Flavio W. Brasil

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Dennis Haupt

unread,
Jan 27, 2014, 9:37:22 AM1/27/14
to Flavio W. Brasil, scala-user
even i got tricked by this once, and i usually do not fall into such traps. +1 for a warning or something
 
Gesendet: Montag, 27. Januar 2014 um 15:35 Uhr
Von: "Flavio W. Brasil" <fwbr...@gmail.com>
An: scala-user <scala...@googlegroups.com>
Betreff: Re: [scala-user] any2stringadd killed my code

Maurício Linhares

unread,
Jan 27, 2014, 9:38:06 AM1/27/14
to scala-user

Kevin Wright

unread,
Jan 27, 2014, 9:39:29 AM1/27/14
to Dennis Haupt, Flavio W. Brasil, scala-user
+1

Hide it behind a language import!
Kevin Wright
mail: kevin....@scalatechnology.com
gtalk / msn : kev.lee...@gmail.com
vibe / skype: kev.lee.wright
steam: kev_lee_wright

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra

Kevin Wright

unread,
Jan 27, 2014, 9:42:51 AM1/27/14
to Maurício Linhares, scala-user
Highly frustrated that I can't vote, now it's flagged "WON'T FIX"

Dennis Haupt

unread,
Jan 27, 2014, 9:44:30 AM1/27/14
to Kevin Wright, Maurício Linhares, scala-user
how about replacing any2string by int2stringadd, double2stringadd etc?
it would be backwards compatible for most use cases


2014-01-27 Kevin Wright <kev.lee...@gmail.com>

Som Snytt

unread,
Jan 27, 2014, 11:45:10 AM1/27/14
to Matthew Pocock, scala-user
a simple one-liner that disables it

scala> :pa -raw
// Entering paste mode (ctrl-D to finish)

import Predef.{ StringAdd => _, _ }

trait X { def x = (new AnyRef {}) + "" }

// Exiting paste mode, now interpreting.

<pastie>:3: error: value + is not a member of AnyRef
trait X { def x = (new AnyRef {}) + "" }
                                  ^
There were compilation errors!


or

scala> :pa -raw
// Entering paste mode (ctrl-D to finish)

package P {
  object StringAdd
  package Q {
    trait X { def x = (new AnyRef {}) + "" }
  }
}

// Exiting paste mode, now interpreting.

<pastie>:4: error: value + is not a member of AnyRef
    trait X { def x = (new AnyRef {}) + "" }
                                      ^
There were compilation errors!





--

Dennis Haupt

unread,
Jan 27, 2014, 11:46:15 AM1/27/14
to Som Snytt, Matthew Pocock, scala-user
you sir, just won


2014-01-27 Som Snytt <som....@gmail.com>

Erik Osheim

unread,
Jan 27, 2014, 1:41:44 PM1/27/14
to Som Snytt, Matthew Pocock, scala-user
One big caveat here is that Scala hardcodes things like (Int + String
=> Int) into the scala.Int type, so there is no way to disable that.

https://github.com/scala/scala/blob/master/src/library/scala/Int.scala#L45

I only mention this because I am overwhelmingly affected by this
problem with number types like Int and Double.

Without a SIP and changes to Scala itself I don't see a way to
restrict concatenative-plus to *only* String types.

-- Erik

Erik Osheim

unread,
Jan 27, 2014, 1:43:57 PM1/27/14
to Som Snytt, Matthew Pocock, scala-user
On Mon, Jan 27, 2014 at 01:41:44PM -0500, Erik Osheim wrote:
> One big caveat here is that Scala hardcodes things like (Int + String
> => Int) into the scala.Int type, so there is no way to disable that.

Errrr, this should read (Int + String => String) obviously.

-- Erik

Florian Hars

unread,
Jan 27, 2014, 3:01:35 PM1/27/14
to scala...@googlegroups.com
Am 27.01.2014 15:13, schrieb Matthew Pocock:
> Again I had some code that was compiling and giving garbage results
> because of Predef.any2stringadd. Can this please die?

https://github.com/puffnfresh/wartremover


Simon Ochsenreither

unread,
Jan 27, 2014, 4:21:33 PM1/27/14
to scala...@googlegroups.com, Dennis Haupt, Flavio W. Brasil
I'll look into making language imports available to disable any2strinadd, implicit widening conversions etc. for 2.12.

I can't promise anything, but maybe making sanity opt-in is more acceptable to those in charge (vs. opt-out).

Ryan Tanner

unread,
Jan 27, 2014, 4:31:55 PM1/27/14
to scala...@googlegroups.com, Dennis Haupt, Flavio W. Brasil
+1 to this.  

David Landis

unread,
Jan 27, 2014, 5:43:34 PM1/27/14
to Matthew Pocock, scala-user
I was just reading this question:


It seems a bit like a crazy circular sequence of compiler errors. If the argument in favor of this feature is that it helps new Scala programmers, what would a new Scala user think if they came across the situation described in the question?



--

Glen Marchesani

unread,
Jan 27, 2014, 5:51:32 PM1/27/14
to scala...@googlegroups.com, Dennis Haupt, Flavio W. Brasil

I am a +1 for this...

FWIW We use the following work around in places where we are reifying text from an AST and it is quite easy to accidentally miss something 

step 1:  use import Predef.{any2stringadd => _, _}  // as mentioned this still doesn't cover (Int + String => String) but is better then nothing

step 2: create a set of implicits to allow ~ as a replacement for +.  In our use cases we have found an ^ operator as a concatenate with a space to be handy and lend a bit of brevity.

Again would be great to 

Kevin Wright

unread,
Jan 28, 2014, 3:15:20 PM1/28/14
to Glen Marchesani, scala-user, Dennis Haupt, Flavio W. Brasil
For anyone who hasn't noticed, the issue has been re-opened and is now accepting votes:

Rich Oliver

unread,
Jan 28, 2014, 4:00:57 PM1/28/14
to scala...@googlegroups.com
One aspect I find particular irritating is that people on the one hand you get people lecturing on how its wrong to use + as non-commutative method, when that's so trivial compared to the abomination that is stringAdd. I can live and let live with how other people write their classes. I can even live and let live to some extent with the classes in the Standard library. But StringAdd pollutes the whole global name-space for the number one operator.

martin odersky

unread,
Jan 29, 2014, 4:27:41 AM1/29/14
to Erik Osheim, Som Snytt, Matthew Pocock, scala-user
On Mon, Jan 27, 2014 at 7:41 PM, Erik Osheim <er...@plastic-idolatry.com> wrote:
One big caveat here is that Scala hardcodes things like (Int + String
=> Int) into the scala.Int type, so there is no way to disable that.

https://github.com/scala/scala/blob/master/src/library/scala/Int.scala#L45

I only mention this because I am overwhelmingly affected by this
problem with number types like Int and Double.

It would be great if we could change this? Is there (still) a reason to have +(String) defined on Int, etc? It seems AnyToStringAdd would cover that anyway. 

And AnyToStringAdd can be disabled with the Predef import that Som showed.

Cheers

 - Martin



--
Prof. Martin Odersky
LAMP/IC, EPFL
Station 14, 1015 Lausanne, Switzerland
Tel: +41 21 693 6863

Rich Oliver

unread,
Jan 29, 2014, 7:29:21 AM1/29/14
to scala...@googlegroups.com, Erik Osheim, Som Snytt, Matthew Pocock
On Wednesday, January 29, 2014 9:27:41 AM UTC, martin wrote:

And AnyToStringAdd can be disabled with the Predef import that Som showed.

That still requires an import into every file? If there was a way to shadow it out in my Util package that I'm probably importing anyway that would be a better temporary solution. I've long felt that first class imports and deports would be very helpful anyway, this is another case.

"Java has it" strikes me as a weak argument at the best of times. But at least Java didn't have type inference. AnyToStringAdd plus type inference is a whole another level. I'd be interested to see a talk entitled::

"Why we must have AnyToStringAdd, but proper enums like Java are out of the question!"

martin odersky

unread,
Jan 29, 2014, 7:40:14 AM1/29/14
to Rich Oliver, scala-user, Erik Osheim, Som Snytt, Matthew Pocock
I think the only argument preventing us to remove AnyToStringAdd altogether is existing Scala code. Removing it now would simply break too much. I believe there will be some point in the future where will contemplate a major shift in Scala that would be supported by a migration tool based on automated source code rewriting. In such a situation would be easy to get rid of things like AnyToStringAdd or procedure syntax, or any of a number of other things.

Cheers

 - Martin
 
--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Erik Osheim

unread,
Jan 29, 2014, 10:18:27 AM1/29/14
to martin odersky, Rich Oliver, scala-user, Som Snytt, Matthew Pocock
On Wed, Jan 29, 2014 at 01:40:14PM +0100, martin odersky wrote:
> I think the only argument preventing us to remove AnyToStringAdd
> altogether is existing Scala code. Removing it now would simply break too
> much. I believe there will be some point in the future where will
> contemplate a major shift in Scala that would be supported by a migration
> tool based on automated source code rewriting. In such a situation would be
> easy to get rid of things like AnyToStringAdd or procedure syntax, or any
> of a number of other things.

I agree with this, but I do think AnyToStringAdd could be deprecated
and issue warnings under -feature (the same way that implicit
conversions and other things do right now). This would at least have
the effect of slowing the creation of new code relying on this
feature. The same argument could be made for procedure syntax.

Since there are relatively easy ways to disable these warnings
globally, this shouldn't be a big burden for those who want to
continue using these features (at least, that's how the argument has
gone so far for things like higher-kinded types) but it will steer
people away from a feature that will possibly go away in the future.

-- Erik

Jason Zaugg

unread,
Jan 29, 2014, 10:25:38 AM1/29/14
to Erik Osheim, martin odersky, Rich Oliver, scala-user, Som Snytt, Matthew Pocock
Thing is, we really want people to listen to API deprecations. If they have to turn of deprecations altogether to silence thousands of procedure syntax warnings, we won't reach them.

The remedies are configurable warning escalation/demotion, and migration assistants to rewrite code.

We're actually thinking of adding a the former to 2.11. It's very late in the cycle, but we want to deprecate buggy things like DelayedInit as a signal to stop new code being built on it, without necessarily removing it straight away. If we know that people who accept the risks could selectively silence such a warning, we're more willing to issue them.

-jason

martin odersky

unread,
Jan 29, 2014, 10:33:22 AM1/29/14
to Erik Osheim, Rich Oliver, scala-user, Som Snytt, Matthew Pocock
There's still a big difference. String + is used by most Scala files out there. Higher-kinded types: A minority of advanced users.

Higher-kinded types caused a huge fuss when the import was introduced. And the typical programmer who uses them is quite able to add the flag or the import. Imagine how much worse it will be when every Scala newcomer or occasional user will see their code deprecated. It won't fly. 

Until there is a major version bump this is a clear case of a lint tool, IMO.

Cheers

 - Martin

 
-- Erik

Haoyi Li

unread,
Jan 29, 2014, 10:45:45 AM1/29/14
to martin odersky, Erik Osheim, Rich Oliver, scala-user, Som Snytt, Matthew Pocock
String + is used by most Scala files out there. 

+1. I think basically every project i've ever written will break if we take it out suddenly; even with string interpolation, I often use string addition purely out of habit.

On the other hand, that may be an argument that we should deprecate it now so people slowly stop using it. If all my use sites were covered in deprecation-warnings/-highlights, I probably would be annoyed into using it much less.

Until there is a major version bump this is a clear case of a lint tool, IMO.

Problem is, any2stringadd is not just a "gotcha" that causes bugs. It actually pollutes the global namespace and makes it annoying to use + as an extension method in any of your libraries because of ambiguous implicits. Lint tools are normally meant for silent-killers, whereas this (noisily causing compilation failures) is something a lint tool won't help with. 

martin odersky

unread,
Jan 29, 2014, 11:45:06 AM1/29/14
to Haoyi Li, Erik Osheim, Rich Oliver, scala-user, Som Snytt, Matthew Pocock
On Wed, Jan 29, 2014 at 4:45 PM, Haoyi Li <haoy...@gmail.com> wrote:
String + is used by most Scala files out there. 

+1. I think basically every project i've ever written will break if we take it out suddenly; even with string interpolation, I often use string addition purely out of habit.

On the other hand, that may be an argument that we should deprecate it now so people slowly stop using it. If all my use sites were covered in deprecation-warnings/-highlights, I probably would be annoyed into using it much less.

Why suffer the annoyance when at some point we can offer an automatic rewrite and thereafter reject String-+ outright :-)
 
Until there is a major version bump this is a clear case of a lint tool, IMO.

Problem is, any2stringadd is not just a "gotcha" that causes bugs. It actually pollutes the global namespace and makes it annoying to use + as an extension method in any of your libraries because of ambiguous implicits. Lint tools are normally meant for silent-killers, whereas this (noisily causing compilation failures) is something a lint tool won't help with. 

I believe for precisely that reason we need an all-or-nothing solution. It would not do to have one part of the Scala community clean their code of String-+ and start to add + methods (extension or otherwise) to their libraries, only for the other part that has not upgraded yet to fall in a hole.

Cheers

 - Martin

 

Martijn Hoekstra

unread,
Jan 29, 2014, 12:18:52 PM1/29/14
to martin odersky, scala-user, Rich Oliver, Erik Osheim, Som Snytt, Haoyi Li, Matthew Pocock

Speaking as a scala novice, I would very much appreciate the compiler warning me and telling me to "fix" my code now, or at least warn me to stop writing new code depending on any2stringadd.

Rich Oliver

unread,
Jan 30, 2014, 2:21:00 PM1/30/14
to scala...@googlegroups.com, Rich Oliver, Erik Osheim, Som Snytt, Matthew Pocock
On Wednesday, January 29, 2014 12:40:14 PM UTC, martin wrote:

I think the only argument preventing us to remove AnyToStringAdd altogether is existing Scala code. Removing it now would simply break too much. I believe there will be some point in the future where will contemplate a major shift in Scala that would be supported by a migration tool based on automated source code rewriting.
 
Will this migration tool be a top priority for 2.12 then? And can we least be guaranteed a compiler opt out parameter in 2.11?
 
In such a situation would be easy to get rid of things like AnyToStringAdd or procedure syntax, or any of a number of other things.

Cheers

 - Martin

I don't know if others feel the same but for me AnyToStringAdd is not just one among many wishes but is uniquely bad. Over time I've been persuaded by your arguments against enums, although if we're not going to do them right lets not do them at all. Maybe getting rid of enums is actually a language improvement. AnyToStringAdd is a step backwards from Pascal, C, C++, C# and others. Combined with type inference it is actually step backwards form Java as well. Although not as bad I would argue that Scala's over enthusiastic type inference, Any, AnyRef, AnyVal etc is also a step backwards from Pascal, C, C++, C# and Java. Primum non nocere. This is 2014, really I don't think a String should any longer be allowed to pass as strongly typed.

Raoul Duke

unread,
Jan 30, 2014, 2:23:08 PM1/30/14
to scala-user
> Pascal, C, C++, C# and Java. Primum non nocere. This is 2014, really I don't
> think a String should any longer be allowed to pass as strongly typed.

word. up.

Som Snytt

unread,
Jan 30, 2014, 2:30:18 PM1/30/14
to scala-user
For folks coming from other languages,

import scala.language.refugee.java


martin odersky

unread,
Jan 30, 2014, 5:50:15 PM1/30/14
to Rich Oliver, scala-user, Erik Osheim, Som Snytt, Matthew Pocock
On Thu, Jan 30, 2014 at 8:21 PM, Rich Oliver <rzi...@gmail.com> wrote:
On Wednesday, January 29, 2014 12:40:14 PM UTC, martin wrote:

I think the only argument preventing us to remove AnyToStringAdd altogether is existing Scala code. Removing it now would simply break too much. I believe there will be some point in the future where will contemplate a major shift in Scala that would be supported by a migration tool based on automated source code rewriting.
 
Will this migration tool be a top priority for 2.12 then? And can we least be guaranteed a compiler opt out parameter in 2.11?
 
I can pretty much guarantee that a solution will come in due time. But I am also strongly proposed to any half-baked, temporary measures until then. These are well intended, to be sure, but in the end only lead to needless complexity. Give it time, and we will fix it  for good :-)

Cheers

 - Martin

In such a situation would be easy to get rid of things like AnyToStringAdd or procedure syntax, or any of a number of other things.

Cheers

 - Martin

I don't know if others feel the same but for me AnyToStringAdd is not just one among many wishes but is uniquely bad. Over time I've been persuaded by your arguments against enums, although if we're not going to do them right lets not do them at all. Maybe getting rid of enums is actually a language improvement. AnyToStringAdd is a step backwards from Pascal, C, C++, C# and others. Combined with type inference it is actually step backwards form Java as well. Although not as bad I would argue that Scala's over enthusiastic type inference, Any, AnyRef, AnyVal etc is also a step backwards from Pascal, C, C++, C# and Java. Primum non nocere. This is 2014, really I don't think a String should any longer be allowed to pass as strongly typed.

--

Simon Ochsenreither

unread,
Jan 30, 2014, 5:59:16 PM1/30/14
to scala...@googlegroups.com, Rich Oliver, Erik Osheim, Som Snytt, Matthew Pocock

I can pretty much guarantee that a solution will come in due time. But I am also strongly proposed to any half-baked, temporary measures until then. These are well intended, to be sure, but in the end only lead to needless complexity. Give it time, and we will fix it  for good :-)

Thanks, nice to hear!

Naftoli Gugenheim

unread,
Feb 2, 2014, 5:40:56 PM2/2/14
to Simon Ochsenreither, Erik Osheim, Rich Oliver, Som Snytt, scala...@googlegroups.com, Matthew Pocock

Regarding the arguments against deprecation -- maybe we need a new class of warning for things that will break further into the future than "deprecated" usually indicates. This way it won't cause people to turn off warnings.
Also I guess it's obvious but now that we have string interpolation the case for StringAdd is even weaker than before.

On Jan 30, 2014 5:59 PM, "Simon Ochsenreither" <simon.och...@gmail.com> wrote:

I can pretty much guarantee that a solution will come in due time. But I am also strongly proposed to any half-baked, temporary measures until then. These are well intended, to be sure, but in the end only lead to needless complexity. Give it time, and we will fix it  for good :-)

Thanks, nice to hear!

--

Simon Ochsenreither

unread,
Feb 2, 2014, 8:02:07 PM2/2/14
to scala...@googlegroups.com, Simon Ochsenreither, Erik Osheim, Rich Oliver, Som Snytt, Matthew Pocock

Regarding the arguments against deprecation -- maybe we need a new class of warning for things that will break further into the future than "deprecated" usually indicates. This way it won't cause people to turn off warnings.
Also I guess it's obvious but now that we have string interpolation the case for StringAdd is even weaker than before.

Agree. I think a good way would be to introduce feature imports, which are first opt-in and then turn into opt-out. Then deprecation. Then removal.

My wishlist of language imports for 2.12 would be like:
  • noLossyImplicitWideningConversions
  • noImplicitStringConversions
  • noValsInTraits

Ken Scambler

unread,
Feb 2, 2014, 8:12:37 PM2/2/14
to Simon Ochsenreither, scala-user, Erik Osheim, Rich Oliver, Som Snytt, Matthew Pocock
"Vals in traits" have a valid usage; when you are declaring a super-high level cakey abstraction over a bunch of things, and you want certain members to end up with a fixed path, permitting imports and .type access.  

Arguably still not worth it.


--

Simon Ochsenreither

unread,
Feb 2, 2014, 8:34:41 PM2/2/14
to scala...@googlegroups.com, Simon Ochsenreither, Erik Osheim, Rich Oliver, Som Snytt, Matthew Pocock

"Vals in traits" have a valid usage; when you are declaring a super-high level cakey abstraction over a bunch of things, and you want certain members to end up with a fixed path, permitting imports and .type access.  

Arguably still not worth it.

The idea comes from looking at Java 8's default methods. Would be nice if traits all mapped cleanly on those interfaces-with-default-methods, but I think vals will cause a lot of trouble here.

Would be nice to be able to get the better binary compatibility of default methods by default and only use Scala's way of encoding things when absolutely necessary. (Maybe make traits with vals inherit from AnyRef?)

martin odersky

unread,
Feb 3, 2014, 3:56:53 AM2/3/14
to Simon Ochsenreither, scala-user, Erik Osheim, Rich Oliver, Som Snytt, Matthew Pocock
vals are not the only problem here. Any method in a trait that overrides a method in a base class cannot be 
represented by a default method either (Java 8 would always choose the class method).  So, stackable modifications are not supported. 

Cheers

 - Martin

Raul Bache

unread,
Feb 3, 2014, 6:26:32 AM2/3/14
to scala...@googlegroups.com, Simon Ochsenreither, Erik Osheim, Rich Oliver, Som Snytt, Matthew Pocock
Vals and Vars in traits really helpful from time to time, why kill them?

Adriaan Moors

unread,
Feb 3, 2014, 1:13:18 PM2/3/14
to Raul Bache, scala-user, Simon Ochsenreither, Erik Osheim, Rich Oliver, Som Snytt, Matthew Pocock
I don't think we should kill vals/vars in traits (or overriding methods defined in a base class, as Martin points out),
but it would be useful to have an annotation that indicates that a trait should be compilable to a Java interface. (Which is what I assume was Simon's intent.)

Raoul Duke

unread,
Feb 3, 2014, 1:48:21 PM2/3/14
to scala-user
> I don't think we should kill vals/vars in traits (or overriding methods

man, i just want usability to be respected and have the two names be a
little more different in terms of their ascii. sorta like get/set is
an evil pair easy to mis-read. no i don't know the perfect names and
yes i know this is not possible ever now. :-)

Simon Ochsenreither

unread,
Feb 3, 2014, 6:44:46 PM2/3/14
to scala...@googlegroups.com, Raul Bache, Simon Ochsenreither, Erik Osheim, Rich Oliver, Som Snytt, Matthew Pocock

... it would be useful to have an annotation that indicates that a trait should be compilable to a Java interface. (Which is what I assume was Simon's intent.)

Exactly!

Rich Oliver

unread,
Mar 9, 2014, 11:47:55 AM3/9/14
to scala...@googlegroups.com
I still get caught by this. I've got a var Seq[Function1] I do a += on it. Compile error found String - er what? Luckily I've done enough Scala that it only takes a few seconds before I realise, oh of course its stringAdd I need :+= . So its just irritating and breaks my flow. But this can cause real problems for beginners. Remember it can cause almost as much problems for Java programmers, the people its meant to help, because Java doesn't have the same level of type inference as Scala, so it doesn't cause anywhere near the same amount of problems in Java.

I'm using Scala 2.11RC1 in Eclipse and as far as I can see there's still no compiler option to turn the damm thing off!

Adriaan Moors

unread,
Mar 10, 2014, 12:33:23 AM3/10/14
to Rich Oliver, scala-user
These kind of improvements are our focus for 2014. I'm very interested in hearing your ideas on designing a solution for this over at scala-internals.
One approach I'm considering is a mechanism to configure warning/error messages in combination with an external list of deprecated members.


--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages