question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Scala Wart: Presence of comments affects program logic

See original GitHub issue

Opening this issue, as suggested by Martin, to provide a place to discuss the individual warts brought up in the blog post Warts of the Scala Programming Language and the possibility of mitigating/fixing them in Dotty (and perhaps later in Scala 2.x). These are based on Scala 2.x behavior, which I understand Dotty follows closely, apologies in advance if it has already been fixed


Did you know the presence or absence of comments can affect the logic of your program?

@ object Foo{
    def bar(x: Any) = println("Foo#bar(x) " + x)
    def bar = println("Foo#bar")
  }
defined class Foo

@ val baz = 1
baz: Int = 1

@ {
  Foo bar
  baz
  }
Foo#bar(x) 1

@ {
  Foo bar

  baz
  }
Foo#bar

@ {
  Foo bar
  // Wooo!
  baz
  }
Foo#bar(x) 1

@ {
  Foo bar
  // Wooo!

  baz
  }
Foo#bar


@ {
  Foo bar
  // Wooo!
  // Hoo!
  baz
  }
Foo#bar(x) 1

As you can see, this code behaves differently if we have a line between the Foo bar and the baz, unless that line has a line comment on it! When there’s no newlines or the newline is filled by a comment, Foo.bar(x: Any) gets called, and when there’s a newline not filled by a comment then the other overload Foo.bar gets called.

There are other places in the language syntax where this is the case:

@ {
  class X(x: Int)(y: Int)

  new X(1)(2)

  class Y(x: Int)
         (y: Int)

  new Y(1)(2)
  }
defined class X
res103_1: X = $sess.cmd103$X@6a58eda9
defined class Y
res103_3: Y = $sess.cmd103$Y@136ca935

@ {
  class Z(x: Int)

         (y: Int)
  }
cmd105.sc:3: not found: value y
       val res105_1 = (y: Int)
                       ^
Compilation Failed

@ {
  class W(x: Int)
  // Woohoo
         (y: Int)
  }
defined class W

A full listing of the places where this “comment can change behavior of newlines” can be found in the OneNLMax rule of the ScalaParse grammar. I don’t have an immediate answer for what the correct solution is here, but I’m 99.9% sure we should make it so comments like this don’t affect the semantics of a Scala program!

PostScript:

As mentioned by Sebastian on reddit, this comes down to a question of “what do you consider comments to be”, since in these cases the Scala grammar is looking for a blank line with no printable characters. Do we consider them to be “whitespace”, which case a line with comments counts as “no printable characters”, or do we consider them “things that do nothing”, in which case there’s still “something” with printable characters on the line preventing the “blank line” rule from kicking in. My personal opinion is that “treating them as whitespace” feels more natural, but I understand that’s somewhat subjective

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:10 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
smartercommented, Apr 21, 2018

@LPTK I like this proposal, but I think its viability depends on whether we can write a reliable rewriting rule to not break existing code.

1reaction
LPTKcommented, Apr 21, 2018

Just wanted to add a use case for this behavior, that I find very useful. I often format mixin compositions with many traits as follows:

object A extends Class
  with Trait0
  with Trait1
  with Trait2
  ...

Then it’s very easy to comment and uncomment one of the trait as needed:

object A extends Class
  with Trait0
  //with Trait1 // TODO fix #123 and re-enable this
  with Trait2
  ...

Or to document each mixin:

object A extends Class
  // used for foo:
  with Trait0
  // used for bar:
  with Trait1
  // used for baz:
  with Trait2
  ...

I’ve also left a message on the forum a while ago, with a proposal that could solve both this and the problem with postfix operators; it is copy-pasted below:


I think there’s a better solution to postfix operators, which would be to introduce some limited measure of indentation sensitivity to Scala’s syntax.

val x = foo bar
baz

means:

val x = foo bar;
baz

and

val x = foo bar
  baz

means:

val x = foo bar baz

I think this will avoid confusing newcomers, since it’s a natural convention that most people already follow – that a non-indented line does not normally continue the expression above.

The same principle could be used to get rid of the fact that removing a comment in some places can break Scala code, which many people seem to find inexcusable.

foo.bar
{ ... }

means (new behavior, less surprising IMHO):

foo.bar;
{ ... }

and

foo.bar
  { ... }

means:

foo.bar { ... }

which is the same as:

foo.bar
// comment
  { ... }

same as:

foo.bar

  { ... }
Read more comments on GitHub >

github_iconTop Results From Across the Web

Warts of the Scala Programming Language
Presence of comments affects program logic​​ Did you know the presence or absence of comments can affect the logic of your program? As...
Read more >
Warts of the Scala Programming Language - Reddit
Presence of comments affects program logic. This one is apparently so much a wart that neither the author nor any of the previous...
Read more >
Scala Wart: Convoluted de-sugaring of for-comprehensions
But some Scala programs would no longer compile. It's a value judgement whether this is worth it. I would be interested in people's...
Read more >
True Scala complexity | Hacker News
In practice, I almost never use monkey-patching in dynamic languages because it's too dangerous. While in Scala there are cases where enrichment ...
Read more >
A Beginner's Guide to Scala, Object Orientation and ...
any side effects and do not depend on the current state of the program. ... The Scala compiler reads this as a comment,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found