Should we gather usage statistics about SIP-44 (fewer braces)?

It seems like a reasonable compromise. I wonder if it could be implemented in ScalaFmt.

Currently ScalaFmt already has certain “end markers” options, but they are based on line counting and are tricky to get right since require tweaking those numbers.

The above rule seems rather straigtworward.

UPD: asked ScalaFmt folks in their Discord channel about it.

It would be great if this rule could be implemented in ScalaFmt. Usage of end markers was the one thing where I was initially unsure what to recommend. Over time, the rule “use an end marker if it closes a scope with blank lines” emerged and it now feels quite natural.

1 Like

I’m not so sure, the overwhelming majority of the senior and above devs I know face-to-face dislike braceless style, so while I may well be in the minority overall, that dislike coming from difficulty reading braceless style is hardly unique to me. I might be a more extreme case, but the class of people who find it quite unfriendly hardly seems an outlier.

And I imagine they’d be similarly annoyed if they were working in a language that had decades of history at indentation = 1, before that changed in a way that was outside the normal process.

You do understand how far Scala 3 is behind in the tooling space, right? Particularly since eliding what is already in the code is significantly simpler than inferring what is not. This extension would effective need to duplicate the work of the Scala compiler (as Jetbrains has done for IntelliJ)

2 Likes

When you put it this way, it truly does feel like you are gaslighting us. We are the problem, despite us having coded in other significant indentation languages AND having given this scala syntax a good try. It’s still our fault for not coming to reason, oh woe us.

3 Likes

Let me take the liberty to bring up yet another POV regarding the matter, that has not been discussed here yet. Please do not take it as I am trying to speak against the braceless syntax – I am not. But I’d just like to highlight yet another issue that the new syntax brings into focus that was not around at the time it was being initially designed.

You have probably guessed it already: LLMs and AI agents. Let’s face it: we cannot simply ignore it anymore. Perhaps there are some research projects that can afford to feel unimpacted for now. But it won’t last and for the vast majority of programmers who work in the industry it is no longer optional.

In a nutshell, the problem with the “braceless syntax” for LLMs is the following. Due to the tokenization phase the programs written in the old syntax with braces and the new one look very different. Far more different than they appear to humans. Therefore old-style programs in Scala that were used in LLM training data are not as useful for Scala3 as we’d like them to be. In other words, it is not just a small incremental change for LLMs.

Moreover, indentation-based syntax is more expensive to train on (mostly due to tokenization issues as well). Yes, there’s Python as an example that it is not a blocker, but… For every 1 line of Scala3 code there are thousands and thousands of lines of Python in training data. Which in turn leads to yet another curious issue: “Python Interference” (I don’t want to expand it here – it can be looked up).

Yes, all these issues can be overcome with several tricks. For example, technically it is possible to convert the braceless syntax to the old style before feeding it into LLM and then convert their output back. Alternatively, there could be solutions based on Scala AST, for example. In any case, it requires quite robust tooling for Scala projects that doesn’t seem to be around currently.

Meanwhile, Java is also evolving and incorporating more and more functional features. But its evolution is rather incremental – no flipping between coding styles is necessary. And LLMs seem to be more benevolent about that.

Consequently, Scala’s shift towards the braceless syntax may unintentionally disadvantage its ecosystem in AI-assisted programming compared to languages with more stable and/or brace-based syntax.

I looked this up and didn’t find anything. It sounds interesting, could you post some references?

which languages? Is it primarily python, or the other modern fp languages Martin mentioned?

were you following the list of recommendations Martin gave?

Just genuine questions. The only way we can make progress on figuring out why some people hate it while others love it, beyond assuming it’s arbitrary taste, is to examine each others habits and see concrete examples. Do you have any?

If we were to gather usage statistics, I think this is what would be most important to analyze, not simply surveying opinions. We should observe and compare the coding habits of those who love the syntax and those who hate it. We might find clear trends.

It’s not even to say that one group has better habits, just that the habits are different (e.g. people who prefer long functions vs people who prefer lots of small subfunctions).

I’m honestly surprised that you’re trying to argue that your preferred syntax style is objectively superior based on anecdotes.

Naively I would assume that the more senior a professional is the less he/she would focus on superficial aspects such as syntax, annoying as it can be sometimes.

I do the same in all cases but one: don’t use end markers at all. Instead, if something contains defs, use braces.

And yes, with these rules, I find the readability substantially enhanced over Scala 2.

I don’t think this really suggests that interference is the main problem. There are lots more lines of Java and C and C++ with curly braces than there are lines of Scala 2; if it learned Scala 2 well enough (I would argue it didn’t fully) then it should be able to learn Scala 3 well enough–it’s already the same order of magnitude of of discrepancy in frequency.

That’s a good idea–maybe the coverage won’t be great because it’s hard to find everyone, but a combined survey / code review does sound like it might be a lot more actionable. But it’s a lot of work. Who is going to put in that kind of time?

It kind of goes both ways, because after you’ve been doing something for a while and you have seen multiple times very clearly why something is actually making things quite noticeably worse, it can be a drag to put up with it, even if it’s possible.

But one has to be careful to disentangle hard-earned wisdom from incidental practice learned at a formative age by people of a similar generation.

2 Likes

I agree that if we decided to gather the stats, they should include some surrounding context. I don’t think though that parameters like “love” or “hate” or “code habbits” actually matter – they are quite subjective anyway. I’d rather suggest to focus on more objective parameters, e.g.:

  • the code style used (mostly braces/mostly sign.indentation/mixed);
  • short term (<1y) / mid term (~1-3+ ys) / long term project;
  • team size;
  • approx code base size;
  • was migrated from Scala2 / started in Scala3 from the beginning;
  • the current code style is used from the beginning or was changed along the way (doesn’t matter why – just changed or not);
  • tools that are incorporated into the project workflow (specifically, code formatters or style checkers that are used project-wide);
  • IDE used on the project (although this one may or may not be really important).

It would be also important to allow to report the usage anonymously. But some kind of protection against voting multiple times (deliberate or unintentional) could come in handy.

True, but braces are much easier to “comprehend” for LLMs than indentations. It is because LLMs do not work with code directly, they work with tokens. When code with braces is tokenized, then the braces can be represented by the same tokens regardless of the indentation (it’s not a rule, but most probably they will be). Indents, on the other hand, require separate set of tokens for every nesting level (and LLMs have to pay attention to them).

It’s not a road block – LLMs can deal with that anyway. Python is a good example, but keep in mind that comparing to Scala:

  • Python code is represented in training data in overwhelming amounts;
  • (if my memory serves me) indents in Python are still not that diverse and somewhat limited.

Therefore, Scala3 braceless syntax can be confusing for LLMs for 2 reasons simultaneously:

  • it may correspond to some Scala code with braces (which is still 90-90% of all Scala code around), but it may look different to LLMs because of the tokenization.
  • it may also mimic Python code so LLMs are more likely to hallucinate in somewhat Python-ish.

Everybody has different tastes as I said in my comment, and there’s no arguing about that. I was responding to posts that said they have not tried it much yet but it looks unreadable to them, and also I have seen some uncertainty what a proper style for braceless syntax should look like. That’s why I explained the coding guidelines I follow and encouraged everyone who wants to give it a shot to try them. That’s it. If you don’t like the syntax, no need to use it.

1 Like

Besides self-types, the other specific wart mentioned by Ichoran is addressed in SIP-77 Method Block End Markers.

The new SIP page doesn’t make it findable for me.

I just closed my old issue about whether end can end a simple expression in a multi-line infix expr.

That example was

def i = 42

def f(b: Boolean) =
  if b then 42 else 17
  + 27

def g(b: Boolean) =
    if b then i else 17
    end if
  + 27

def k =
  for res <- List(1, 2) yield
    if res == 1 then "one!" else "two!"
    end if
  + "end"

which I mention here to point out that expectations or assumptions require re-education, especially as syntax evolves.

This is more in the area of whether to “fully parenthesize” Boolean expressions. (That is an unsolved research problem. It is not yet addressed by leading infix syntax.)

My comment on my ticket was: “Not all usages benefit from fewer brackets.”

In relation to the current thread, it would be great if the industry had a system for archiving failed projects for postmortem analysis. That is, failed private projects with proprietary code; FOSS operates under different constraints. I would not care if programmers are uncomfortable while succeeding, but I would care if a feature makes projects fail at a higher rate.

I’m honestly surprised that you’re trying to argue that your preferred syntax style is objectively superior based on anecdotes.

I don’t think you’re reading that post correctly. He’s saying that dismissing his concerns as “an outlier” is unfounded, because the person doing it has no idea whether this opinion is actually rare.

2 Likes

In Elixir at least you get the end marker for free when hitting enter after a function definition in vscode. Maybe it could be an option you can enable for scala as well. It was really handy.

Maybe just one more random datapoint.

I realized that I quite often click on braces to have the matching brace highlighted. To do so, I click somewhere after the line the brace is on (usually the opening brace), which does select the brace as those are always at the end of the line. The highlighting helps me a lot to figure out where a scope ends.

Without braces there is nothing to click on.
IntelliJ can highlight a matching end marker if one clicks on the opening keyword, but that requires clicking on, say, the if keyword, even though I want to know the scope of the else block.

That may make quite an impact on perceived usability for me.

The indent lines can also be clicked to highlight them (IntelliJ), but there its also harder to figure out where to click, as that requires figuring out what line opens the scope and where that begins, and then clicking at the right colum (and empty lines cannot be clicked).

I don’t have a good idea how that kind of visual help could be restored, but a similar UI for visualizing where an indented block ends would be quite interesting to compare.

This may also be why I find end markers with names mostly distracting, because the highlighting provides the same information but interactively and with less effort.

2 Likes

I would care quite a bit, because prioritizing project success while disregarding programmer discomfort is the path to crunch, burnout, and churn.

Got it in one, and probably said better than I would have :+1:

I am not claiming that disliking significant whitespace is rare - I think that is the majority opinion considering all programmers in the world. I think being ‘unable’ to get used to whitespace. no matter how much time you spend with it, as seemingly a biological fact about your eyeballs or visual cognition, is rare, and I would point to the popularity of python in the new generations of programmers as evidence for that assumption. But yes it would be great to have actual data on this and not just personal wagers.