Skip to main content

VM to remove support for String + operator by June 17th

Posted by Seth Ladd

Today, the Dart VM team announced they will be removing support for String + operator from the VM on June 17th. In an email to the misc@dartlang.org group, Matthias Hausner wrote:

"On Sunday, June 17, we will turn off support for the String + operator in the VM compiler and runtime. Any code that still uses + will break.

You can test now whether your code is free of String + by invoking the VM with --allow_string_plus=false, or by locally editing runtime/vm/parser.cc and setting the default value of this flag to false and recompile the VM. Then, run your code and fix any fallout."

Rationale

After careful consideration, the string operator+ was removed because:
  • It causes puzzlers (exhibit A)
  • It's superfluous in the presence of string interpolation.
  • It encourages people to write inherently inefficient (quadratic) code.
Alternatives

You have three options to construct Strings, in the absence of the + operator.

String interpolation

String interpolation is great when you need to construct a simple string using other values. For example:


var to = 'Dart developer';
var msg = 'Hello $to!';
assert(msg == 'Hello Dart developer!');

StringBuffer

A StringBuffer allows you to build up a string without actually constructing a string instance. For example:

var to = 'Dart developer';
var buffer = new StringBuffer();
buffer.add('Hello ');
buffer.add(to);
buffer.add('!');
var msg = buffer.toString();
assert(msg == 'Hello Dart developer!');

String buffers are useful when you're building a string using a loop.

Adjacent string literals

When you have long string literals that should be split across different lines, the Dart runtimes will automatically concatenate adjacent string literals.

var longMessage = 'This is a long message that might exceed 80 '
                  'characters because I have '
                  'so much to say, so I split it across many '
                  'lines using adjacent string literals';

While Dart does support the triple-quote string (which allows you to write strings across many lines), sometimes you want to control leading and trailing spacing. In those cases, adjacent string literals is very useful.

Thanks for working with Dart! As always, the Dart discussion list is open for your thoughts and feedback.

Comments

  1. What is the reason for this change?
    Does this mean that I will have to add extra lines to a recursive function like this?

    //count(5) returns "0 1 2 3 4 5"
    String count(int x) {
    if (x==0) return '0';
    return count(x-1) + ' ' + x;
    }

    ReplyDelete
    Replies
    1. you don't need extra lines:

      String count(int x) {
      if (x==0) return '0';
      return "${count(x-1)} $x";
      }

      Delete
    2. I understand thanks!
      However, I hope that Java developers (and others) can get used to that and give Dart a try.

      Delete
  2. Any reasons for this change? Almost every language since the beginning of time has a string concatenation operator, why has Dart dropped it? Will this not alienate Java developers who would expect this from a language that looks so much like Java?

    ReplyDelete
    Replies
    1. Why do you need "a+b" to concatenate strings? You can always just "new StringBuffer().add(a).add(b).toString()", which is just as easy to write.

      Delete
    2. > which is just as easy to write

      It's not. It's bloody hell not! This is as easy to write: "$a$b"

      Delete
    3. I can believe someone prefer to write "new stringBuffer().add(a).add(b).toString()" unlike "a+b" ahah
      A string operator can be different than "+", it could be "." like in perl/php. It solves the puzzler 11.
      By the way, I think google knows it, and the main reason to drop "+ string" is performance.

      Delete
    4. For immutable strings the concatenation operator is problematic at best. I'm a Java developer and I rarely use string concatenation simply because of the copy semantics of immutable strings. I find string interpolation to be a natural evolution of string concatenation and a welcome change. If only Java would follow suit.

      Delete
    5. While I agree that there are other options to "+", I would have thought that under the hood the compiler would achieve the same using "+" as with Strings.concatAll. Personally I prefer the "+" operator, and I imagine others do also because of both brevity and expressiveness. While Dart is great and this is no deal-breaker, obviously all of these "things" add up. I presume that the reason is based on theoretical principles because "+" is a mathematical operator. While that may be a valid reason, I think it detracts from the agility of Dart. The reasons actually given don't "add up" for me. I think that the real reason is to force programmers to write more efficient programs when that should be their decision, and the compiler should allow for it as Java has done (I'm no Java fan-boy). Interpolation is good, but it's not as agile. As for "new StringBuffer().add(a).add(b).toString()" - no thank you. While efficiency is obviously important, agility and expressiveness are also. Most of the efficiency is the job of the compiler and the VM. I think that removal of "+" for Strings is a backward-step for the reasons given.

      Delete
    6. On further reflection, I think that the reason "+" was removed for Strings is because of dynamic typing. Because of dynamic-typing and the overloading of "+" there could be bugs that rarely surface. If that is the case, perhaps it should have been explained. Why not use another operator or find another solution?

      Delete
  3. hi, I was wondering why the compiler can't convert "+" to StringBuffer.add???

    ReplyDelete
  4. I really don't understand the point of this. Why remove an operator that everyone understands and is comfortable with in favor of interpolation? I get that the + operator and string interpolation do the same thing, bu why remove something that everyone is comfortable with? Is it to differentiate actual addition from string concatenation? If so, then why don't we have a VB-style concatenation operator like the ampersand (&) or something?

    ReplyDelete
    Replies
    1. Because using + for both addition and concatenation is broken in every conceivable way. It's the root of a bunch of weird horrible behaviour in JavaScript too.

      e.g.

      print("a + b = " + a + b)

      One might argue in favour of a dedicated concatenation operator as in Lua but overloading + is broken in any case.

      Delete
    2. It's also worth noting that it breaks a fundamental principle of maths, that addition should be commutative.

      print('10' + 10) -> 1010
      print(10 + '10') -> error

      Delete
  5. Here's your answer: http://www.dartlang.org/articles/puzzlers/chapter-2.html#13

    I personally don't like + removal either, as it makes some code harder to read, but, well... it's for greater good.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
  6. Well, that's kind of an answer but I never write "string" + x == y, I always write "string" + (x == y). Still, java already converts "string" + "string" to StringBuilder.add(...). That was one of the java 5 optimizations.

    I was wondering when I would jump in and code an entire application in Dart, seems like I will postpone again. This is a change that can be a pita when you have to upgrade the VM and then all of you code. I would have prefered a step in between where the compiler warns of potential "+" misuses not break. And operator precedence is not really an excuse, if you are a programmer, you always have to take into account operator precedence.

    I would have felt a bit more confortable with the way changes are handled. And since google seems to have very strong people in the compiler side of things, I am surprised they haven't come up with something clever for the already "legacy" dart code.

    ReplyDelete
  7. There's nothing like legacy code in Dart. Guys, we're not even in alpha yet! Changes are inevitable at this stage of development, and if you're not comfortable with them happening, you shouldn't use Dart right now.

    ReplyDelete
  8. Very very disappointing.

    Make things easy, intuitive and *elegant* guys - it's these type of decisions that makes a language ugly and before you know it we have Dart++ or Dava.

    I too, as Sabastien, would always have written: print('Animals are equal: ' + (pig == dog));

    ReplyDelete
  9. Not using it, merely fiddling with it, can't wait to have a stable version... But still removing "+" is weird, adding the rest "hello $var" is cool...

    ReplyDelete
  10. I thought at first that this was going to be bad, but when I rewrote a bunch of code, string interpolation turned out to be easier on the eye in almost all cases.

    For example, print("Animals are equal: ${pig == dog}") seems intuitive and unambiguous.

    ReplyDelete
    Replies
    1. I was initially shocked and appalled that such a seemingly basic operator was being removed. Then I read your comment and I'd have to say it's not bad.
      On a side note, I really loved "Object-Oriented Design and Patterns"! It's how I learned Java.

      Delete
    2. I do get interpolation and I like it. One place where I miss the + operator is when you need to increment a string by a char (something like this):

      var s = "xxxxxxx";
      if (...)
      s += "*";
      print(s);

      Isn't it a burden to write it with StringBuffer instead?

      Delete
    3. You can still do:

      var s = "xxxxxxx";
      if (...)
      s = "${s}*";
      print(s);

      Delete
  11. Still, getting rid of the polymorphic + exposes the compromises made in the design. It's a brand new language, why not go asymptotic on perfect?

    ReplyDelete
  12. I like it when a language tries to teach a programmer good behavior but IMO string concatenation should be possible. Although I agree that it shouldn't use the + operator. I agree that that can be confusing/misleading.

    But why not simply opt for a string concatenation operator? I suppose a string concatenation operator should have lower precedence than numerical operators. I'm trying to think of a situation where this would be counter-intuitive but so far I cant find one.

    Plus, and this is just me, I've always found string interpolation an ugly concept. It looks to much like magic to me.

    ReplyDelete
  13. Its funny how people are complaining. Try rewriting your code with the new rule and tell me what blunder it caused. It didn't even increase the lines of code. The only reason for the complain is because its not what you're used to. Get used to it and the change will be meaningless.

    Finally, stop comparing with other languages. This is Dart, not Java or Javascript.

    ReplyDelete
    Replies
    1. you want your average moron (person of +-average inteligence is profoundly _DUMB_) to think, acknowledge context, try new things and stop comparing apples with oranges ?

      have a disappointing rest of life, i suppose :-(((

      Delete
  14. I don't see what the big fuss is all about. I think the Dart team has more than compensated for removing string concatenation. If we all just took the time to actually read the article, you would know why the decision was made and the benefits. It's not like they haven't justified their decision or just decided to make our lives difficult for the sheer fun of it.

    Also, keep in mind guys that Dart is not even in alpha yet. Expect a lot to change.

    ReplyDelete
    Replies
    1. I agree, but changes like this are the main reason I have not written a Dart application. Once the code base is stable I will jump in this mix. I do however like this change, the + operator has actually always kind of bugged me the way it bends how my brain accepts mathematics. I literally had to just say, "ok fine" and use it.

      Delete
  15. This is crazy, why not simple use VB-style (&) operator.

    How would you now handle the following

    var a = 'Welcome ";
    var b;
    var c = 'To the world of dart';

    b = 'john';

    print (a + b + c);

    or

    print (a + c + ' ' + b);

    depending on some if-else

    ReplyDelete
  16. is it possible to add extra functions to String I.E

    var s1 = "hello";
    var s2 = "world";

    var newstring = String.concat(s1,s2);
    var newstring2 = String.concat(s1, " ", s2);

    ReplyDelete
  17. What is now the best way to replace something very common like this:
    catch(ex) {
    print("error found : " + ex);
    }

    ReplyDelete

Post a Comment

Popular posts from this blog

Const, Static, Final, Oh my!

Posted by Seth Ladd

(This is an "oldie but a goodie" misc@dartlang.org post originally written by Bob Nystrom. It is being posted here as the explanations still ring true.)

Bob writes:


"static", "final", and "const" mean entirely distinct things in Dart:

"static" means a member is available on the class itself instead of on instances of the class. That's all it means, and it isn't used for anything else. static modifies *members*.

"final" means single-assignment: a final variable or field *must* have an initializer. Once assigned a value, a final variable's value cannot be changed. final modifies *variables*.

"const" has a meaning that's a bit more complex and subtle in Dart. const modifies *values*. You can use it when creating collections, like const [1, 2, 3], and when constructing objects (instead of new) like const Point(2, 3). Here, const means that the object's entire deep state can be determ…

AngularDart 4

AngularDart v4 is now available. We've been busy since the release angular2 v3.1.0 in May. Not only did we "drop the 2", but we also improved the compiler and tightened up the framework to give you smaller code, we updated the package structure to improve usability, and we added several new features. Check out the updated documentation to get started.
Just angular Upgrading to v4 will require more than updating your version constraint. The package has changed names (back) to angular – dropping the 2. You'll need to update your pubspec.yaml and the corresponding imports in your code. In most instances, find-and-replace should do the trick. Going forward, the package will be called package:angular. We'll just update the version number.
Smaller code The updated compiler in 4.0 allows type-based optimizations that not only improve runtime performance but generate better code because we are able to strongly type templates. A big result of the update is that many ap…

The new AdWords UI uses Dart — we asked why

Google just announced a re-designed AdWords experience. In case you’re not familiar with AdWords: businesses use it to advertise on google.com and partner websites. Advertising makes up majority of Google’s revenue, so when Google decides to completely redo the customer-facing front end to it, it’s a big deal. The Dart team is proud to say that this new front end is built with Dart and Angular 2. Whenever you asked us whether Google is ‘even using Dart for anything,’ this is what we had in mind but couldn’t say aloud. Until now. We asked Joshy Joseph, the primary technical lead on the project, some questions. Joshy is focusing on things like infrastructure, application latency and development velocity, so he’s the right person to ask about Dart.Q: What exactly did we launch on Monday?It’s a complete redesign of the AdWords customer experience that is rolling out slowly as a test to a small initial set of advertisers. The most noticeable thing is probably the Material Design look and f…