This page is no longer maintained — Please continue to the home page at www.scala-lang.org

2.8 collections again: StringBuilder.dropRight and String.dropRight

5 replies
Chris Marshall
Joined: 2009-06-17,
User offline. Last seen 44 weeks 3 days ago.
I've just spent several hours hunting down a bug which was ultimately caused by the following:
  String.dropRight (inherited from IterableLike/IndexedSeqOptimized via StringOps) returns a String
  StringBuilder.dropRight (also inherited from IterableLike/IndexedSeqOptimized) returns an IndexedSeq[Char]
Which means that:
  scala> val sb = new StringBuilder  sb: StringBuilder = StringBuilder()
  scala> sb ++= "Hello World"  res0: sb.type = StringBuilder(H, e, l, l, o,  , W, o, r, l, d)
  scala> sb.dropRight(1).toString  res3: String = ArrayBuffer(H, e, l, l, o,  , W, o, r, l)
  scala> sb.toString.dropRight(1)  res4: String = Hello Worl
Hmmm - I can't help but feel that this sort of thing (2.8 collections API) is going to provide similarly unpleasant surprises to peeps for some time to come. The precise issue in this instance is presumably that StringBuilder does not extend StringLike (extending IndexedSeqOptimized[Char,Repr]) and that it specifies that it is an indexed seq:
   class StringBuilder .... with IndexedSeqOptimized[Char, IndexedSeq[Char]]
What is the rationale behind the decision that StringBuilder does not inherit from StringLike[StringBuilder]?
Chris





Get a new e-mail account with Hotmail - Free. Sign-up now.
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: 2.8 collections again: StringBuilder.dropRight and String.d

On Thu, Jul 01, 2010 at 08:27:07AM +0000, christopher marshall wrote:
> Hmmm - I can't help but feel that this sort of thing (2.8 collections
> API) is going to provide similarly unpleasant surprises to peeps for
> some time to come. The precise issue in this instance is presumably
> that StringBuilder does not extend StringLike (extending
> IndexedSeqOptimized[Char,Repr]) and that it specifies that it is an
> indexed seq:

That is not necessarily how I would characterize the issue. toString is
a coarse, unreliable, and all around terrible solution when it comes to
turning things into Strings if correctness rides on the result. If you
didn't know that, now you do. There are many ways for it to surprise
even under the best of circumstances, and these aren't those.

I think the only legit use of toString is debugging.

scala> "Hello world" dropRight 1 mkString
res0: String = Hello worl

scala> (new StringBuilder ++= "Hello world") dropRight 1 mkString
res1: String = Hello worl

Looks good to me. And mkString calls toString in StringLike, so it's
not even particularly inefficient.

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: 2.8 collections again: StringBuilder.dropRight and String.

On Thu, Jul 1, 2010 at 10:17 PM, Paul Phillips wrote:
> On Thu, Jul 01, 2010 at 08:27:07AM +0000, christopher marshall wrote:
>> Hmmm - I can't help but feel that this sort of thing (2.8 collections
>> API) is going to provide similarly unpleasant surprises to peeps for
>> some time to come. The precise issue in this instance is presumably
>> that StringBuilder does not extend StringLike (extending
>> IndexedSeqOptimized[Char,Repr]) and that it specifies that it is an
>> indexed seq:
>
> That is not necessarily how I would characterize the issue.  toString is
> a coarse, unreliable, and all around terrible solution when it comes to
> turning things into Strings if correctness rides on the result.  If you
> didn't know that, now you do.  There are many ways for it to surprise
> even under the best of circumstances, and these aren't those.
>
> I think the only legit use of toString is debugging.
>
> scala> "Hello world" dropRight 1 mkString
> res0: String = Hello worl
>
> scala> (new StringBuilder ++= "Hello world") dropRight 1 mkString
> res1: String = Hello worl
>
> Looks good to me.  And mkString calls toString in StringLike, so it's
> not even particularly inefficient.
>
But what that amounts to saying is that the user should not care what
the returned type is, as long as mkString works. I don't think it
works this way. Users do care. And that means StringBuilder should be
better integrated in the colleltions hierarchy.

Cheers

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: 2.8 collections again: StringBuilder.dropRight and String.d

On Thu, Jul 01, 2010 at 10:40:33PM +0200, martin odersky wrote:
> But what that amounts to saying is that the user should not care what
> the returned type is, as long as mkString works. I don't think it
> works this way. Users do care. And that means StringBuilder should be
> better integrated in the colleltions hierarchy.

I have no problem giving StringBuilder some more parents or otherwise
kicking it around (naturally not, I practically rewrote it between rc6
and rc7! Clearly I live to change it!) but I stand by the idea that
there will always be corner cases with toString and we will never be
able to make good guarantees about it.

There's simply no way to robustly deal with these methods which exist on
java.lang.Object (yes equals, I'm talking to you too) in a world where a
very small change at the source level can ripple through type inference
until some expression not only has a different type, but originates from
a different library written by a different author in a different source
language and probably using vi instead of emacs. If you use toString
you (generic you) abandon all type safety: that's your privilege, but
you have to lower the expectations once you've leapt off the boat.

And I will interpret your email as endorsing a StringLike parent unless
you indicate otherwise.

Chris Marshall
Joined: 2009-06-17,
User offline. Last seen 44 weeks 3 days ago.
RE: 2.8 collections again: StringBuilder.dropRight and String.d
> Date: Thu, 1 Jul 2010 13:17:00 -0700
> From: paulp [at] improving [dot] org
> To: oxbow_lakes [at] hotmail [dot] com

> toString is a coarse, unreliable, and all around terrible solution when it comes to
> turning things into Strings if correctness rides on the result. If you
> didn't know that, now you do. 
*Desperately looks to find that statement in documentation*.StringBuilder's toString says:
"Returns a new String representing the data in this sequence."
So it does not seem unreasonable (especially coming from a Java background) to use it in this case. This issue is not (IMHO) with toString, it is with the fact that StringBuilder is not a StringLike[StringBuilder]. Perhaps there is a convincing case that this is not so (mutability, perhaps?).
But thanks for the pointer - I'll use mkString (which is ugly, again IMHO) as idiomatic scala from now on
Get a new e-mail account with Hotmail - Free. Sign-up now.
dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: 2.8 collections again: StringBuilder.dropRight and String.
Err, what? I thought the problem was that the toString method was being applied to the result of drop, which is clearly documented as being IndexedSeq[Char], as unhelpful as that may be.

On Fri, Jul 2, 2010 at 4:27 AM, christopher marshall <oxbow_lakes [at] hotmail [dot] com> wrote:
> Date: Thu, 1 Jul 2010 13:17:00 -0700
> From: paulp [at] improving [dot] org
> To: oxbow_lakes [at] hotmail [dot] com

> toString is a coarse, unreliable, and all around terrible solution when it comes to
> turning things into Strings if correctness rides on the result. If you
> didn't know that, now you do. 
*Desperately looks to find that statement in documentation*.StringBuilder's toString says:
"Returns a new String representing the data in this sequence."
So it does not seem unreasonable (especially coming from a Java background) to use it in this case. This issue is not (IMHO) with toString, it is with the fact that StringBuilder is not a StringLike[StringBuilder]. Perhaps there is a convincing case that this is not so (mutability, perhaps?).
But thanks for the pointer - I'll use mkString (which is ugly, again IMHO) as idiomatic scala from now on
Get a new e-mail account with Hotmail - Free. Sign-up now.



--
Daniel C. Sobral

I travel to the future all the time.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland