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

Sorry if coming late to the party, but just wanted to add that in general this is one change that I am not happy with. I basically agree with Alex’s thoughts on the matter (see On Scala 3's Optional Braces - Alexandru Nedelcu and Scala 3 / No Indent - Alexandru Nedelcu ) but the tl;dr is that the new syntax has hyper optimized for one narrow use case (code on presentation slides, maybe using Scala as a config language like yaml but thats a stretch???) while at the same time significantly complicating the language on so many levels, i.e.

So I would really like to an honest and scientific (as much as we can) approach to figuring out what the broader Scala community thinks of this fewer braces SIP, as its also creating a big divide in how code is written (and Scala doesn’t exactly need more divides than it already has)

3 Likes

I strongly disagree with this presentation. Indentation-based syntax has been the single most important productivity booster in Scala 3 for me and my group. And we work daily on code bases in the 100Ks of lines of code. It find it simply brilliant because it lets me focus on what’s important.

So to day “this is only for presentation slides” is completely wrong as far as I am concerned. All modern new languages have indentation based syntax: Scala, F#, Haskell, Lean. Everybody now learns with an indentation based syntax (Python). So like it or not, it’s the future.

5 Likes

Thats fine, I am just saying its obvious that this isn’t the case for everyone and its not just a few people that have the opposite opinion. A lot of us also work with massive Scala codebases daily and we are saying this because we experience it everyday, so I don’t know why you would bring this up.

Rust, Go and Kotlin say otherwise and all of these are newer then the languages you mention (aside from Lean from what I can tell). All of these languages are also more “successful” than the ones you mentioned (Scala included)

Everybody is a bit hyperbolic

Sure, I mean you make the decisions but its not helpful when you make statements in absolutes especially when you have holes in your logic. I mean you just claimed that new successful languages have Python like syntax even though none of the most successful new languages (lets say new means within 10 years ago) have no whitespace significant syntax at all (Rust, Go, Kotlin, Typescript). Hell, you could even argue there are even languages that have died in trying to push whitespace significant syntax as a major feature (look at Coffeescript which was basically a Rubyesque dialogue of Javascript with a few extra features, the language is entirely dead now).

In fact the only mainstream popular languages that have whitespace significant syntax are Ruby and Python, and Ruby is also following a similar to fate to Scala in regards to its usage.

I get it that you and the people that you work with find it easier, but it would have been best to just leave it at that

5 Likes

We can of course disagree whether we personally find indentation helpful or not. What I was objecting to, and why I wrote this, was your statement that indentation based syntax is only good for presentation slides. That was stated as an absolute, not a personal preference, and that’s clearly not the case. Otherwise, let’s just agree to disagree, on personal preferences and what the future might hold :wink:.

5 Likes

I was trying to articulate that it was in effect it appears that it was optimized for clean/short bite sized code (which does mean its slightly easier to read such code with whitespace significant indention) but for more complex code with more varying structure/nesting it makes it harder as you have to use more brain capacity to reason about where the code is “sitting”.

This is of course subjective, but other people have also made similar statements so I am not alone in this.

I wasn’t trying to state it as an absolute, apologies if it came across that way.

4 Likes

maybe using Scala as a config language like yaml but thats a stretch???

It’s a stretch, but not a very long one: scala-3-is-yaml.scala · GitHub

5 Likes

I’ll focus on this one statement:

In Uruguay, all universities will give you a whirl of java, c, c++, javascript and python (with some smidges of pascal or modula in UDELAR’s FING). The following information comes from some kids I know that finished their universities in the last 3-5 years:

In Vancouver, Simon Fraser University:

python, C, C++, js, that custom one we wrote for the compiler, kotlin, arduino-C. Most courses would probably be tied python/C

In Glasgow, university of Strathclyde:

Core language was very clunky java, but I took a terrible course in agda in my last year, and there was some C for the systems class

in Norway, university of University of Tromsø and later University of Bergen

First learned C at one and Java in another, though my university later switched to Python. I learned Haskell in the FP course and used C++ with a lot of macros in the concurrency class

In Carnegie Mellon (this friend of mine went into academia and now works on Lean)

I was taught programming in C and SML
and to some extent bash (LOL)
and had other courses with programming expectations in python, c++, ocaml

At University Stuttgart:

University Stuttgart taught mostly Java, there was a single mandatory course that explored other programming paradigms via various languages, which included Ada, C, Lisp, Pascal, a lot of Haskell, and Prolog.
there was another optional course that taught MIPS and RISC assembly iirc

Then you also have pre university courses taught to kids. I’ve seen everything from scratch, godot, unrealengine blueprints, to javascript and python. Python is surely used, as is everything else, and summing all the braces-based ones stacked against python+haskell, they are by far what they are exposed to.

In frankness (maybe more than this argument calls for), saying “Scala, F#, Haskell, Lean” are new languages, or that they are popular, while ignoring typescript, golang, rust, kotlin, swift, zig, dart and others, which are way more popular (not zig in particular) and newer… I can’t take that as anything but a bad faith argument, because there’s no way you don’t know this…

P.S: the lean committer is very against the notion that lean is indentation based.
He says:

most idiomatic lean code is in the pure fragment which doesn’t have any whitespace sensitivity. It has indentation sensitivity to prevent you from making stupid syntax mistakes like nested matches, but most syntax is whitespace agnostic.
lean has whitespace sensitive syntax in a few places, namely tactics, do notation, and match exprs
All with very good justification for being whitespace sensitive to avoid confusions.

Like you can’t write a multi line if statement in do notation without braces just by indenting. Braces are required.

5 Likes

Can’t speak for other countries but in Norway almost all universities and colleges educate programming in Python it seems.

exclusively? because I think that’s the point. Every one I listed (mostly) included python there, but so did a lot of C-likes.

Not exclusively, but most students will take Python as an introduction to programming, like Odersky says.

I find the exact opposite. I use braces more often when trying to make slides because I want to fit more stuff vertically so I do if foo then { bar; baz } and such more than I ever would in real code where vertical space is not at such a premium!

Furthermore, I find that the real advantage of braceless syntax is not to have the same coding style you always did except without braces, but to be able to adopt a better coding style.

The key thing it enables is low-effort context blocks. If you embrace this, it’s useful everywhere.

// Short functions
def foo(x: Int): Bar =
  val y = x*x + 4x + 3
  Bar(y, y*y, -y)

// Rust-style direct error handling
val data = Ask:
  val input = read(path).?
  parse(input).?.touch(Instant.now)

// Custom control flow
defer(f.close()):
  println(s"Reading $f (${f.size} bytes)")
  if f.size > 0 then
    println(s"Content: ${f.read()}!")
  else println("Empty")

// Nontrivial variable creation
val foo =
  val bar = BarFactory.create()
  FooFactory.fromBars(bar, bar.label, baz(bar.id))

and so forth and so on. Being able to get tiny low-ceremony blocks is a big deal. Imagine you had to write xs.map(lambda def (x: String): String = x.trim) just to get xs.map(_.trim). That Scala lets you do the latter is actually a really big deal for high-productivity low-superfluous-distraction code. Braceless syntax isn’t as big a relative improvement, but it still is really helpful if you use it to enable new patterns that would have always been good except were too painful to use before.

For things that already worked well, like class bodies, I keep braces. It’s clearer. There is some argument that end with a label that tells you what you’re ending is superior, but honestly, if the code is so big that I’ve lost that context, I’ve probably already done something wrong. That really doesn’t take much of my time either way–because most of the time if it’s too long to know what the end is, you also don’t know what the middle is when both beginning and end are out of view. So, meh. But for the tiny stuff it’s brilliant.

I do agree that it’s valuable to figure out what general sentiment in this area is. I’m not sure how actionable it is, though. It would be quite surprising if some people are burned by it so severely that on balance the better option isn’t to embrace it as an option; and it would also be quite surprising if everyone loved it so much that on balance the better option is to remove braces as an option.

So I kind of don’t see what we are likely to learn that would be actionable, aside possibly from education and/or bug fixes. If there are advantages that are being passed over, maybe one could learn what is being missed. Or, if there are pain points that aren’t as obvious as they should be, maybe they can be addressed and fixed with tooling or minor syntax changes.

Beyond that, diversity that is not too hard to handle has advantages, and removal has bigger downsides than lack of addition.

4 Likes

I’ve avoided weighing in again because Scala has recently become a “Not my circus, not my monkeys” situation, but at this point I think it’s probably worth mentioning that the company I work for is moving away from Scala for greenfield projects.

Fewer braces/significant whitespace isn’t the only reason for that change, but it was significant enough that if it wasn’t part of Scala 3 we’d probably still be watching for when the dust settles and things stabilize a bit more - instead we’re evaluating replacements.

Just something to keep in mind when sending out the surveys, so the sample doesn’t end up getting too skewed.

1 Like

Sad but true. One of the reasons why some teams begin drifting away from Scala is that the Scala community is filled with drama and tensions. Unfortunately, the “fewer braces” syntax only created yet another point of tension without bringing any substantial value to the language itself (in my opinion).

4 Likes

Exactly, people can disagree about whether the new indentation significant syntax is better or not (and a lot of it is subjective by definition) but I think the more pertinent point is was doing such a change really necessary? As was shown before, there is very little evidence (one way or another) that syntax is significant factor for a language. None of the most popular new languages (Kotlin, Go, Typescript, Rust) have whitespace significant syntax and there are languages that have died because they largely brought whitespace significant syntax along with other syntax improvements without much else (Coffeescript).

8 Likes

I think we need a more precise question, because changes are almost never “really necessary”.

It’s very on-brand for Scala–in most places Scala will figure out for you what can be figured out. No types? It will figure out the type. Need context? It’s got you covered. Indentation instead of braces? Sure, that’s clear. Symbolic operators? Do what you gotta.

Also, for some people (e.g. me) it has made quite a noticeable improvement in my productivity, especially for reading code.

So what do you mean by “really necessary”?

I do agree that it’s been a divisive change. Was it worth it? Harder to say, especially since we can’t run the alternative experiment.

2 Likes

In my opinion it’s pretty simple: unlike many other great innovations in Scala3, SIP-44 doesn’t introduce new language features. It simply provides an alternative way of what Scala code can look like. In other words, it is just an alternative syntax for the existing features.

Therefore, it doesn’t enrich the language itself. It does create additional hassle for the migration as well as managing cross-building codebases.

2 Likes

Isn’t that true of all syntactic sugar? For comprehensions, lambdas, semicolon inference, etc.?

There has to be something more precise to say about the change than that.

1 Like

The issue here is framing, I think a mistake is being done where it appears that changes that are being added to Scala on the basis that its always positive (at worst no benefit at all) where as in reality any change has very real cost and I would argue that the benefits need to greatly outweigh the cost. I also get a sense that we cherry picked the change from other languages when those languages have designs that mitigate the negatives of whitespace significant syntax, i.e. Ruby may be as expressive as Scala but it deliberately has left in a lot of ending keywords to help with these issues and Python is deliberately designed to be a much simpler language with far less language constructs.

As you have noted, the change is very divisive (its created yet another split in the community), its made it overall harder for Scala to have unified codebases that look similar (and Scala is a language that already has many issues in this area) and it also gives the impression that all of this effort (and it was quite a large amount as tooling like scalafmt also had to adapt) we are still not done yet in the journey because of the issues we are dealing with as a fallout (i.e. nesting of structured blocks is one)

And while it may have been productive for some, for others its the opposite. The general sense I get (also personally) is that while it may have made it easier to read trivial code, it made it harder to understand code with more complex structures.

6 Likes

No, for comprehension I would classify as something entirely different as its changing the fundamental structure on an lexical token/AST level (i.e. removing map/flatMap and replacing it with for/<-/=), same deal with lambda’s.

Semicolon inference is a better example, but like with all things its a spectrum. Not only did we have semicolon inference right at the start, but its also far easier to implement and much less of a significant change. I would also strongly argue that its also much less divisive, its much more universally accepted that semicolons inference is a net benefit by almost everyone.

3 Likes

Isn’t the plan for braceful syntax to stick around permanently as an alternative syntax, and to allow people to disable significant whitespace with -no-indent?

If so, I don’t see how it can cause migration issues when moving from Scala 2, because the new syntax can just be turned off.

I’m asking because while I think significant whitespace vs. braces is largely a matter of personal taste (I prefer braces), I really don’t like the idea of having to reformat all code in an existing project that migrated from Scala 2, even if that process can be automated.

I’m hoping braceful syntax sticks around permanently, we’d be very unhappy about being forced to migrate existing code to significant whitespace syntax in some future Scala version.

5 Likes