Feedback sought: Optional Braces

What I fear the most about optional braces is community won’t have an agreement on some option as it happens in the thread.

That will cause inconsistency in different codebases and might lead to forbidding optional braces syntax in some companies guidelines due to inconsistency, as inconsistency in approach creates mess in code.

This is a good point. Style guides will be very opinionated and also likely automated (e.g. scalafmt).

allow optional braces only for simple unambiguous parts of code and disallow else (keep braces)

In reality that will just devolve into disallowing optional braces everywhere because no-one wants the hassle of bike-shedding if this is sufficiently “unambiguous” to warrant braceless.

There’s a similar point with the end statements when using braceless: people that auto-formatters will likely either force their removal or force their presence to avoid the hassle over arguing if they should exist or not. In all likelihood (again) that will devolve to them never being present.

2 Likes

Seconded. It’s hard enough to teach new devs that braces can be omitted for single expressions in Scala 2. As that determination has a good chance of being significantly messier with Optional Braces, there’s a very real risk of perverse incentives landing us in a place where Optional Braces produces more braces than it removes.

4 Likes

Well, computers are deterministic but people are not :slight_smile: and code is actually more about people than machines as, for the most significant part, code is read rather than compiled; we want code to evolve and it is people that evolve it.

Transferring the way of “one single way to do it” to human communication would feel really restrictive to me. Pragmatism rules in the real world. And who are we as a language designers to rule out peoples unforeseeable needs for expression? The whole foundation for Scala is pragmatism and with that comes a plurality of ways to express ourselves, just as in natural language.

I believe that artificial languages are the next level of human communication :robot:

3 Likes

I think choice is good, but too much choice is not. I am happy Scala gives us multiple tools, but having multiple ways to define the exact same thing is not (IMHO of course). For the same reason things like formatters have become increasingly popular, because consistency reduces the cognitive burden. Also, Its for the same reason @infix was introduced, to introduce consistency.

Being more opinionated has been a core goal of Scala 3. And regards to syntax it has not done great there. This thread has shown people clearly feel different about what works well, so it is even more likely that one codebase will increasingly look less like another. Making it much harder to go from one Scala codebase to the next, and adapt your style to the new ‘true’ way.

1 Like

I have had great difficulty reconciling the reasons given for the @infix change with reasons given for this one.

1 Like

I am not sure what point you are trying to make. But I don’t think there is any reconciling, since this change offers more choice, and @infix tries to offer less.

Also it was not really the point I was trying to make. We have even more ways to do things, and nothing that encourages one style over another. I am not even in favor of forbidding a style, I just think something should (eventually) be encouraged (whether that is in the language, as a compiler flag or anything else I don’t know).

1 Like

“Let’s be more consistent, more opinionated, and simpler” has been a pretty common guiding principle in the changes between Scala 2 and 3. And then there’s Optional Braces, which basically creates a parallel syntax structure that’s also highly inconsistent, and only gets marginally more consistent with the introduction of an experimental compiler flag.

I just don’t understand what’s so bad about braces that justifies this level of complexity and risk, and that it appears diametrically opposed to the third stated goal of Scala 3 just makes it harder to understand why this is being pushed so hard.

It’s really confusing, and trying to reconcile this change into the overall “idea” (for lack of a better word) of Scala 3 has been incredibly frustrating. The sudden nature of the switch between “this is an experiment” to “this will be the default” was really jarring and that did not help.

3 Likes

I agree, I am not sure why you are reacting to me specifically. I do quite like the new syntax (though I don’t love it), but I don’t think it is worth it. I am increasingly afraid it will do no good for Scala’s reputation.

3 Likes

Fair question :slight_smile:

I’ve posted a couple of comments that didn’t really make as much sense as I expected because something else was posted while I was writing, so I’ve tried to build a habit of quoting what prompted my thoughts as a way of retaining that context (with varying levels of success, both in effectiveness and consistency of application).

In this case, your comment about @infix reminded me that why this is ok and infix flexibility isn’t hasn’t ever really been explained (at least to my knowledge), and I quoted the relevant snippet to provide context.

1 Like

Where does this kind of style:

val ys = xs
  .map(f)
  .filter(p)

fit into the axioms? Here, each line may of may not be followed by something. But I guess that since these are not “expressions or definitions”, no : would be necessesary?

What about:

xs.map:
   x =>
      val y = x - 1
      y * y

Would it be allowed to write this also as:

xs.map x =>
  val y = x - 1
  y * y

since something must follow =>?

The first axiom was incomplete here. It says in effect that a statement separator (think ;) is inserted if the last token on the preceding line can end a statement and the first token on the following line can start a statement. . cannot start a statement, hence, no separator is inserted.

That works today under -Yindent-colons.

Not yet, but the plan is to support this also (post 3.0).

3 Likes

I’ve been recently using a language with explicit end markers (Lean), and I can assure you that it definitely improves readability for non trivial declarations.

In Scala 2 or Java I totally depend on IntelliJ magick to discover the block start.

This is no longer needed with end NAME.

Ah no that’s not what I meant. Let me try again, if you look at these below, do you expect that 1,2,4 compile ok and 3 is a compiler error?

// 1. No :, single method = ok
extension (x: T)
  def f = 1

// 2. With :, single method = ok
extension (x: T):
  def f = 1

// 3. No :, multi method = error
extension (x: T)
  def f = 1
  def g = 2

// 4. With :, multi method = ok
extension (x: T):
  def f = 1
  def g = 2
1 Like

My primary experience with explicit end markers has been in Ruby and Bash (sort of), and it was extremely clunky. While it’s possible that being able to omit most of them will change this, the examples I’ve seen haven’t been particularly convincing (at least to me).

On the other hand, every code-oriented editor I’ve encountered has been able to colorize, highlight, or otherwise visually match braces in a lightweight manner, so it’s not really an IntelliJ or IDE thing. I’ve found it both useful and easy to visually parse when needed and unobtrusive when not needed.

The bigger issue isn’t that some people find it easier to grok, I understand and agree that some will, it’s that most developers won’t be familiar with this sort of syntax, and this feature is shipping and touted as the new default without the supporting effort to convince them this is a good thing. Even the examples in the documentation about this feature look better with braces, which is a big problem.

How am I supposed to sell this to my engineering department? Almost every other change has some tangible benefit, but this is going to require a bunch of time to review style guides and training and that’s going to eat up time for the most experienced (and thus most expensive) employees, for what benefit? To get rid of something most of us find so comfortable to use we don’t have to think about? That would be a hard sell, even if I believed in it.

2 Likes

One option would be to stick with brackets for the moment and see how the Scala 3 syntax shakes out over the next year, then make a decision as to whether it makes sense to adopt the new syntax.

I believe that Martin has stated on several occasions that brackets are not going away. It seems plausible that this could change in future if everyone decided to wholeheartedly decide to stop using brackets …

Unfortunately, my company just went through a merger, so while it would be an easier sell to do a minimal upgrade in place for my existing department, making the case to the larger combined department is going to be much harder. Even then, what I would effectively have to do is go through on my own time and decide what would make sense to adopt and what would make sense to skip, then propose that.

I’ve earned enough trust over the years that there’s a decent chance this would either be accepted wholesale or at least cut down the number of discussion points to where it’s feasible to entertain. I don’t have that track record yet with the combined company, and I don’t trust my soft-skills are up to the task of making the case to strangers without having to go point by point (and that’s not organizationally or financially feasible).

There’s already going to be friction because one of the leads from that part of the company really wanted to go with Scala when they started, but apparently wasn’t able to make the case, so I’m going to have to overcome the inertia of that decision. It doesn’t help that, “it’s too complicated,” was apparently a major factor in their decision to avoid Scala, and this is a major uptick in complexity.

That’s part of the problem. Martin’s decision to flex his unofficial BDFL clout on this one makes things look much less stable, and that is absolutely going to make this harder to sell.

2 Likes

I’m not convinced that he is really doing this. To me, it still feels like Martin is aiming for ‘rough consensus’.

I thought that I would ask a small set of my software engineering colleagues what they think of the two choices (varying experience up to about 20+ years of professional C and Python). They seemed to be split fairly evenly (11 vs 10) between the two choices below, with a slight preference for significant indentation.

  1. They prefer significant indentation
  2. They prefer brackets (but only with correct indentation)

I would also say that there seemed to be a slight bias towards the younger folks preferring significant indentation, and the more experienced folks preferring brackets.

I do wonder if the idea of trying to banish brackets from the code base is the wrong way of looking at this, and perhaps an alternative articulation would be to say that code must always be sensibly indented and braces can optionally be used to add additional clarity where required - just in the same way that sometimes brackets are added to expressions to make the operator precedence clear even where they are not strictly required.

Such an articulation would perhaps favour requiring no “:” or “with” for classes/objects etc, relying on whitespace and braces when needed.

E.g.

class foo(arg1: String, arg2: Int) extends bar
  def method ...

class bar(arg1: String, arg2: Int) 
  extends bar {

  def method ...
}

In general, I still feel that in some cases (mostly methods) the brackets are noise and I would happily leave them out. In other cases they are helpful and should be put in (e.g., longer methods/blocks/etc). I still think that a closing brace is better probably better than end if for a 5-10 line if body, and I’m not really sure that I see a huge amount of benefit of avoiding brackets for big things (like classes/objects/etc).

One last thing, if we did say that sensibly indented code is the primary goal then I think that having a minimum indent of 1 tab or 2 spaces would help avoid indentation bugs, and doesn’t seem to have any obvious downsides to me.

4 Likes

It’s a really big thread, but if you go back over it, it’s clear that while minor syntax tweaks are on the table, Martin’s been pretty clear that this is going in mostly because he wants it in. He said exactly that in the original post:

The biggest problem is that, as has been explicitly stated, this is going to be the recommended default, so when people look up Scala 3, this is what all the official stuff is going to look like.

The issue with this approach is that it takes something that, up to this point, has been something that requires little to no discussion because it had a very clear set of rules about when braces could be omitted, and widens it to, “whatever you think looks good.”

This means that teams are faced with one of three choices:

  1. Braces get added everywhere.
    This would be unfortunate because the current situation is a pretty good balance, and losing that would be a shame.

  2. Braces get entirely eliminated.
    This would discourage those who think it looks weird from picking up Scala, and make it harder for developers who have a difficult time distinguishing scope based on indentation to remain with Scala. We don’t exactly have a huge developer base to start from, so anything that makes it harder to hire or maintain Scala talent is going to make it harder to convince engineering teams to take up or stay with Scala.

  3. Braces get used “where appropriate.”
    Unfortunately this means a bunch of time and money wasted in style discussions during team meetings and code reviews, which is not going to help Scala’s reputation for inconsistency.

    It’s also highly subjective, so we can’t necessarily lean as much into the standard style guide or linters as we can for other features - as an example, I find the standard style that’s being proposed to be very difficult to read, so a linter which enforces only that would be mostly useless for me.

For something that we didn’t really need to think about, that’s a big step backwards.

4 Likes

I don’t agree that your 3rd choice needs to be bad - that depends on leadership and communication and getting priorities right in a software engineering team.

We already mix styles to get readable code and we can have guidelines and recommendations on how to mix braceless and braceful code even in the same file if it makes code more readable.

Compare to the language discussions that chief editors have with journalists at a news paper; there are both rules and freedom and often beautiful text if they are good (and sometimes ugly, of course, but that’s a bug :slight_smile: ).

1 Like

From my experience working with really huge codebases, I would say it was about <0.1% of time when I had to look for the beginning of the code block, most of the time, in neat codebases you would have files with 1/2 classes and a bit of nesting, in total less than 200 lines, so wouldn’t even bother about code blocks.
Second thing is any more or less advanced code editor support code block discovering