Is it too late to change this?

21 views
Skip to first unread message

John Munro

unread,
Nov 15, 2011, 1:08:11 PM11/15/11
to General Dart Discussion
Modern compilers can deduce scope and line endings - they don't have
to be explicitly stated, and haven't been necessary for decades.

When given the choice between something that makes the compiler's life
easier and something that makes the programmer's life easier, language
designers should fight for the users!

Imagine how much time programmers have spent unnecessarily typing { }
and ; over the years.

If you put this crap into a new language you're just pushing it
further into the future - now we have to put up with it for another
decade.

I think they only do it to keep C people happy, and frankly, screw
that.

Izzy

unread,
Nov 15, 2011, 1:12:30 PM11/15/11
to General Dart Discussion
That's a lot of hate without any actual suggestion.

Bob Nystrom

unread,
Nov 15, 2011, 1:43:04 PM11/15/11
to John Munro, General Dart Discussion
On Tue, Nov 15, 2011 at 10:08 AM, John Munro <ghos...@gmail.com> wrote:
Modern compilers can deduce scope and line endings - they don't have
to be explicitly stated, and haven't been necessary for decades.

When given the choice between something that makes the compiler's life
easier and something that makes the programmer's life easier, language
designers should fight for the users!

Imagine how much time programmers have spent unnecessarily typing { }
and ; over the years.

There is a highly-starred issue on the bug tracker for making semicolons optional: https://code.google.com/p/dart/issues/detail?id=34. If you care about that, feel free to star it and add a comment. Go and Scala (I think?) have shown that you can make semicolons optional after a language has been released without too much pain, so even if we don't do this from day one, it doesn't mean the opportunity is lost forever.

{} are a more complex issue. Some people like significant indentation, some people don't. There isn't a clear win in terms of subjective preference there.

When it comes to actual semantics, indentation has at least one problem that would make it tricky to use in Dart. Dart has function expressions, which means you can have a curly block in expression position in the grammar. Expressions can nest. Consider:

var s = () {
  // I am a function!
}.toString();

If we were using indentation, where would the .toString() go? How would you express this:

takeCallbacks(() {
  // first
}, () {
  // second
});

I think the grammar could be designed to be able to handle this, but doing so is definitely not trivial and makes it harder for users to internalize it. That makes it harder for them to read Dart code.

You'll note that Python dodges this issue by specifically disallowing multi-line lambdas. Personally, I consider that way too much of a loss. I'll gladly type a couple of {} if it means I can make anonymous functions that are as long as I want. If you go through the samples, you'll note that we use large anonymous functions quite frequently in Dart.


If you put this crap into a new language you're just pushing it
further into the future - now we have to put up with it for another
decade.

No syntax will please all people. The Dart team is generally syntactically conservative: we want Dart to be easy to learn if you're coming from Java/JS so that you can get to the new semantics Dart provides as quickly as possible. If you're OK with Dart's semantics but really despise the syntax, there's always an opportunity to make a new language that compiles to Dart.


I think they only do it to keep C people happy, and frankly, screw
that.

And Java, and C#, and C++, and JavaScript. And, to a lesser extent Scala, Go, Groovy, ActionScript, Fantom, Perl, Fancy, D, HaXe... Like it or not, the world's programmers are comfortable with {}. If a language wants to stray from that, it should make sure that doing so adds significant value. I'm not convinced that it does for a language like Dart.

- bob

Izzy

unread,
Nov 15, 2011, 2:24:14 PM11/15/11
to General Dart Discussion
Regarding semicolons: there is also the confusion that can occur since
Dart supports first class functions. Take the following example:

Function getPrinter() {
return (str) { print(str); };
}

var f = getPrinter();
("Hello" + "World").forEach(f);

First, what does this code do? It calls the function stored in f for
each letter in HelloWorld, printing each letter (probably to a new
line).

Now let's remove semicolons (i'll just do the latter part):

var f = getPrinter()
("Hello" + "World").forEach(f)

Now what happens? Well, since getPrinter returns a function, the
following parenthesis actually invokes that function on "HelloWorld",
then tries to call forEach on whatever that returns, probably nothing.

The interpreter can discern in a lot of places that a newline should
== ;, but it doesn't handle edge cases like this well.

I'm actually a fan of not using semicolons in my javascript, but I
appreciate that Dart just says "use semis" and ends the problem.

If you don't have semicolons, you can't treat functions quite as first
class. I'd love to hear how the above situation would be treated
differently in a non-semicolon world, since I certainly can't discover
the solution.


On Nov 15, 1:43 pm, Bob Nystrom <rnyst...@google.com> wrote:
> I think the grammar *could* be designed to be able to handle this, but
> doing so is definitely not trivial and makes it harder for users to
> internalize it. That makes it harder for them to read Dart code.
>
> You'll note that Python dodges this issue by specifically disallowing
> multi-line lambdas. Personally, I consider that way too much of a loss.
> I'll gladly type a couple of {} if it means I can make anonymous functions
> that are as long as I want. If you go through the samples, you'll note that
> we use large anonymous functions quite frequently in Dart.
>
> > If you put this crap into a new language you're just pushing it
> > further into the future - now we have to put up with it for another
> > decade.
>
> No syntax will please all people. The Dart team is generally syntactically
> conservative: we want Dart to be easy to learn if you're coming from
> Java/JS so that you can get to the new *semantics* Dart provides as quickly

John Munro

unread,
Nov 15, 2011, 2:33:22 PM11/15/11
to General Dart Discussion
I feel badly about my tone in my original message, and I apologize. I
will do better.

I feel strongly about this, but I realize that other people will hold
opposing opinions equally strongly.

I also realize that a lot of thought has gone into the design of the
Dart language and that this issue has already probably been discussed
at length by people smarter than me.

I realize that JS is flavor of the decade, but as a programmer there
are a lot of things I dislike about it and I think it needs to be
replaced. So when Google came up with something they want to replace
JS but they kept what I consider to be some of JS' mistakes in order
to keep JS programmers happy, it made me frustrated. I had the same
reaction when Go was released - joy and then horror.

Regarding semicolons - the majority case is single lines of code and
the minority case is line continuations. So it seems logical to me to
use less syntax for the majority case: no syntax for normal line
endings and instead syntax for line continuation. As much as I hate
to hold up VB as an example of something being done right, I think it
has this the right way around.

As for curly brackets, what I mostly object to is having to use them
when my intention is obvious without them. For example in an "if"
statement it's obvious that everything following is inside the "if"
until an "else" or "endif" is encountered. The same thing applies to
loops and other control structures.

So maybe curly brackets could be limited to situations where you can't
do without them, like lambdas, although I'm not certain they're
necessary even there. I hate to hold it up as an example again, but
VB.NET does multi-line lambdas without curly brackets.

In general I consider "it's always been this way" to be a bad reason
to do things. If Dart has its syntax because of JS which has its
syntax because of C, then I worry that when I retire we'll still be
using syntax chosen because of the limitations of compilers written
before I was born.

What I'm trying to express is that it's not impossible if you want to
do it, but if I'm the only one that has an objection then that's fine.

Since there was no great outcry when Go used JS/C-like syntax and
there hasn't been one about Dart, I suppose I don't actually expect it
to change.

Bob Nystrom

unread,
Nov 15, 2011, 2:38:42 PM11/15/11
to Izzy, General Dart Discussion
On Tue, Nov 15, 2011 at 11:24 AM, Izzy <gtg...@gmail.com> wrote:

var f = getPrinter()
("Hello" + "World").forEach(f)

Now what happens? Well, since getPrinter returns a function, the
following parenthesis actually invokes that function on "HelloWorld",
then tries to call forEach on whatever that returns, probably nothing.

That's only true if we were to use JavaScript's awful semicolon insertion rules. If we did make semicolons optional in Dart, we definitely would not do that. Brendan is incredibly smart, but that's a corner of JS that he even agrees is just busted.

There are sane approaches to optional semicolons. See: Go, Scala, Python, et. al.

If you don't have semicolons, you can't treat functions quite as first
class. I'd love to hear how the above situation would be treated
differently in a non-semicolon world, since I certainly can't discover
the solution.

In Go, it would work correctly because the newline would be treated like a semicolon. Newlines are only ignored following tokens that cannot end a statement or expression. Likewise, it would work correctly in Python and Scala because newlines are treated like semicolons unless they appear inside bracketing characters.

- bob

Izzy

unread,
Nov 15, 2011, 3:08:59 PM11/15/11
to General Dart Discussion

> There are sane approaches to optional semicolons. See: Go, Scala, Python,
> et. al.
>
> If you don't have semicolons, you can't treat functions quite as first
>
> > class. I'd love to hear how the above situation would be treated
> > differently in a non-semicolon world, since I certainly can't discover
> > the solution.
>
> In Go, it would work correctly because the newline would be treated like a
> semicolon. Newlines are only ignored following tokens that cannot end a
> statement or expression. Likewise, it would work correctly in Python and
> Scala because newlines are treated like semicolons unless they appear
> inside bracketing characters.

This seems to disallow me from chaining stuff like:

[1,2,3,4,5,6,7,8,9,10].filter((item) => item % 2)
.filter((item) => item %3)
.forEach((item) => print(item))

please ignore the silliness of the example. The point being that
chaining calls like this is quite frequent in a lot of web code, seems
to be just fine in Dart as is.

Moral of the story being removing semi-colons disallows me from
writing something like the above that there's no good reason I can't
do if I want to. Having semicolons does not force you to put your
newlines anywhere you don't want to put them, it only requires that
you know when your statements are completed and indicate that with
something other than whitespace.

Bob Nystrom

unread,
Nov 15, 2011, 3:35:24 PM11/15/11
to John Munro, General Dart Discussion
On Tue, Nov 15, 2011 at 11:33 AM, John Munro <ghos...@gmail.com> wrote:
I realize that JS is flavor of the decade, but as a programmer there
are a lot of things I dislike about it and I think it needs to be
replaced.  So when Google came up with something they want to replace
JS but they kept what I consider to be some of JS' mistakes in order
to keep JS programmers happy, it made me frustrated.

I don't look at Dart as replacing JS as much as offering another alternative. The web is a monoculture now, and I don't think that's healthy. You need diversity and competition in order to grow.

That being said, there are definitely lots of things I don't like about JS and many of those are fixed by Dart. We have to balance that, though, with trying to make the language easy to pick up. I'm personally not excited about semicolons and curlies either (especially semicolons) but they are comfortable to millions of programmers. By having Dart use them, that's two fewer things that people need to learn before they can be productive in Dart.

 
Regarding semicolons - the majority case is single lines of code and
the minority case is line continuations.  So it seems logical to me to
use less syntax for the majority case: no syntax for normal line
endings and instead syntax for line continuation.  As much as I hate
to hold up VB as an example of something being done right, I think it
has this the right way around.

For what it's worth, I agree, though this is not at all up to me. (I'm just an engineer on the team, not one of the core designers.) I think we could probably make semicolons optional without too much pain. At the same time, we've got lots of other important stuff to do (like reflection!) so it's probably not the best use of our time to worry about it right now. Go made semicolons optional well after it was released without too much trouble, so we may be able to do the same.
 

In general I consider "it's always been this way" to be a bad reason
to do things.

I don't think Dart makes choices like that. What we do is place value in the knowledge that's already in people's heads. If there's syntax or semantics that work well and are familiar to many, that's a good reason to keep them. Getting people to adopt a new language is hard. Getting them to adopt a new client-side language on the web is near impossible. Anything we can do to ease that adoption is important, even if it means making the language a little less exciting syntactically.

- bob

Bob Nystrom

unread,
Nov 15, 2011, 3:36:47 PM11/15/11
to Izzy, General Dart Discussion
On Tue, Nov 15, 2011 at 12:08 PM, Izzy <gtg...@gmail.com> wrote:

This seems to disallow me from chaining stuff like:

[1,2,3,4,5,6,7,8,9,10].filter((item) => item % 2)
 .filter((item) => item %3)
 .forEach((item) => print(item))

please ignore the silliness of the example. The point being that
chaining calls like this is quite frequent in a lot of web code, seems
to be just fine in Dart as is.

Hmm, good point. Python does barf on that.

Anyway, I'm not trying to sell you on optional semicolons. I think it could be made to work, but what we have now works fine too, and if it ain't broke...

- bob

Rayiner Hashem

unread,
Nov 15, 2011, 4:23:25 PM11/15/11
to General Dart Discussion
> Now let's remove semicolons (i'll just do the latter part):
>
> var f = getPrinter()
> ("Hello" + "World").forEach(f)
>
> Now what happens? Well, since getPrinter returns a function, the
> following parenthesis actually invokes that function on "HelloWorld",
> then tries to call forEach on whatever that returns, probably nothing.
>
> The interpreter can discern in a lot of places that a newline should
> == ;, but it doesn't handle edge cases like this well.

This isn't an edge case. '(' is both a prefix operator and an infix
operator, and that can cause an ambiguity.
Allowing the semi-colon just to resolve the ambiguity is a simple
solution. It's not really any different than
using parens in C when the * operator, which can be both infix and
prefix, causes ambiguity, or using
whitespace to separate tokens that could otherwise be lex-ed as a
single token.

I personally dislike Javascript's "automatic semi-colon insertion
rules" if only because it makes the problem
seem far more complex than it is. A simple rule is "statements are
parsed into the longest legal statement,
but ';' can be used explicitly to terminate a statement."

- Ray

Ramalingam G

unread,
Nov 15, 2011, 11:29:06 PM11/15/11
to General Dart Discussion
Hello everyone,

Semicolons may or may not important for compiled languages, but for
browser based languages like dart, I think, it is a must. Think what
if html parsers strip new line and white spaces inside script tag as
other tag's contents.

- Ramalingam

On Nov 16, 2:23 am, Rayiner Hashem <r-

Daren Chandisingh

unread,
Nov 16, 2011, 10:14:49 AM11/16/11
to General Dart Discussion
> when my intention is obvious without them.  For example in an "if"> statement it's obvious that everything following is inside the "if"> until an "else" or "endif" is encountered.
Which is fine, if there's an "endif".  I'd rather type {} than endif,
personally.I see no compelling reason to have endif, endfor,
endforeach etc. (although
I could be persuaded that it makes it more obvious which block is being
ended when there are nested structures), and I think it would make code
look a lot more dense to have such.
Reply all
Reply to author
Forward
0 new messages