Make "fewerBraces" available outside snapshot releases

I just want to put in my vote that significant indention is pretty ugly and unreadable, but I am happy that it has been included since I think it will help Scala stay relevant in this increasingly Python-dominated world.

I don’t mind many flavors of Scala, and I quite liked that Scala permitted e.g. infix and postfix ops, but that teams could decide not to permit them (or permit them in limited cases) using scalafmt, which helpful rewrites uses away if you ask it to. However, Scala 3 has taken the opinion that the language itself should participate in style enforcement, requiring infix and import postfixOps to continue to make use of them. This seems reasonable to me, because it is in the direction of code syntax that is less magical, ambiguous, and confusing.

Reading this thread, I’m worried that Scala 3 is trending in the other direction for significant whitespace: having the language encourage or even enforce the magical, ambiguous, and confusing syntax you get from significant whitespace – snippets like xs.map x => x + 1 trigger the same worries to me as ys concat xs map f, which is legal Scala 2, but I believe now generally looked down upon. I can’t tell you how many times I’ve gotten lost trying to parse multi-line nested for comprehensions in Python, though of course you can’t put all the blame on significant whitespace there. I similarly find the whitespace-heavy Haskell to be a huge pain to read.

All that is to say I sincerely hope that the plan is not to actively encourage or enforce the parenless syntax, so that those of use who don’t like it can set a flag in scalafmt that wipes it away and continue to love the language as much as we do. And if the language does want to participate in enforcement and not outsource to scalafmt, then I hope that it is in the direction of preferring the braces (i.e. requiring import language.fewerBraces, even if it graduates out of experimental).

3 Likes

I only have a hundred thousand and change, but same deal. Would rather migrate to a uniform community standard than contribute to a hodgepodge, even if nobody but me is looking at my style of Scala.

The awkward part is that although our Scala 2 code looks fairly similar (only fairly), since Scala 3 has more options, it’s likely to diverge increasingly much.

My personal rule has been: in conditions where the braceless syntax works well, use it. Otherwise, if it’s even a little questionable, don’t. This is basically the same view I use with dot-free style: use the simplicity only when it is a significant improvement to clarity.

So, for instance, I’m totally happy rewriting

def something(a: A, b: B): C = {
  val d = f(a, b)
  makeC(d, d, d)
}

as

def something(a: A, b: B): C =
  val d = f(a, b)
  makeC(d, d, d)

It’s just plain better. No downsides. Just like I’ll write xs.map(_ drop 5) instead of xs.map(_.drop(5))–the second adds a lot of visual clutter without clarifying anything whatsoever.

(In practice, “only when better” has tended to mean that I never use : to open a block. The just plain better cases almost all have an opening symbol.)

If I were to instead to try the all-in approach you suggest, the existence of unsolvable problems is, well, a problem. Code is already hard enough to understand in those kinds of problematic cases; that’s one of the last places where any loss in clarity is acceptable. The reach of what was clearly a syntactic win could be extended, though.

Note that anything that requires 4-space indents I would probably consider a non-starter, because I have plenty of code indented too many levels for 4-space indents to be viable. The level of rewriting required to lower the indentation needed exceeds what I’m likely to want to do for anything complicated enough to have needed such indentation in the first place.

5 Likes

Trailing comma is an unfortunate victim of the fewer and fewer braces movement.

I wonder if we can reinstate trailing comma before end markers?

Scala code often has a lot of indentation levels because of nested methods and objects, ifs, pattern matching, and especially higher order functions. With 4 space indentation you would need a second screen just to see the most interesting part of the code, which is usually the most indented.

5 Likes

My own two cents on this. I’m not a huge fan of indented blocks (I’ve written more Java and XML than Python and yaml), but I’ve grown to like it in Scala. I find that 2 spaces are not enough and 4 are too much waste. I’m just finishing a book in which I’ve indented all the Scala code with 3 spaces.

I don’t know how much more braces I want to see removed. Like someone said earlier, at some point it’s fanaticism, and makes code harder to read.

Still, I’m a bit annoyed when I change:

for (_ <- 1 to n) do
   blah
   blah

into

n times {
   blah
   blah
}

or when

def f = 
   blah
   blah

becomes

def f = synchronized {
   blah
   blah
}

Even if it doesn’t save a line, I’d prefer something like

def f = synchronized:
   blah
   blah
end synchronized

to the version with braces. It makes it clear that the body of the function is synchronized, arguably more than with the braces.

1 Like

As much of the discussion has been centered around professionals and legacy code, I’d just like to add my experiences from teaching one semester with Scala 3 and optional braces.

It is very salient that beginners with no previous coding experience (around 30% of my students) find the indentation syntax much easier. The ones with prior coding experience in C-like syntax have a period to adopt but almost all embrace the new syntax after a while. The ones that come from Python have a smooth transition.

I think that the colon is very intuitive and works very good as indentation marker, and in general students find it intuitive.

They tend not to use end markes spontaneously, but I asked them about code on my slides and most seem to think that nested structures get more readable with an outer end marker.

6 Likes

@odersky @sjrd I’d very much like to see fewerBraces available outside nightly, so I can use that in my teaching using stable releases. Is it possible to be included in the 3.2 series?

3 Likes

There is already a PR for it, but it was pushed to 3.3.0-RC1 milestone which will probably see light of day at end of 2022.

There was discussion of SIP meeting approval requirement, but other changes to the languages get merged without it, so I don’t understand where things are. And I don’t understand where things are with SIP meetings in general. It has been literally years since the latest one.

1 Like

I find comments like this somewhat troubling.

An unpleasant truth is we kind of suck at teaching CS and Software Development to students who do not fit a particular profile. This is understandable, as this is still really new, and in comparison to how long it took us to figure out how to teach skills like geometry and algebra to those who do not have an inclination towards those subjects, we’re doing ridiculously well.

That doesn’t change that, at least as recently as when I graduated in 2013, it was an open joke (and source of much frustration) among the Professors and TAs that CS 201 (the algorithms course) was less a class that effectively taught algorithms, and more a filter to eliminate the roughly 50% of the students that weren’t inclined toward the subject.

Python’s syntax has always been controversial, and I would hope that between all the archived threads trying to hash out how the Python community feels about it, and the discussions on this forum, it’s clear that, for at least at least a segment of the population, code without punctuation to delimit scope is not simply something that we can “get used to.” The degree to which this is met with a dismissive, “get used to it, or just do something else,” is also particularly worrisome.

There’s a chronic shortage of developers already, and maybe the solution to that is code that eschews punctuation in favor of indentation - but the introduction of this sort of change should be done with deliberation and be based on evidence rather than gut feelings, because telling students “don’t worry, you’ll get used to it” is a good way to push someone out of a CS program if it’s something they can’t get used to. And if we’re going to write these people off as acceptable losses, we’d better be really certain the change is going to bring in more people than it pushes away.

The same argument applies to Scala mindshare among developers, but at least there we’re just shooting ourselves in the foot, rather than our entire industry.

1 Like

@morgen-peschke Note that my experience regards teaching with optional braces as in Scala 3.0 and not with fewerBraces as in nightly (sorry if this was unclear in my previous post). I thus “extrapolate” the usefulness of fewerBraces from optional braces, but it is entirely my best guess and not based on empirical evidence (but for optional braces I do have empirical observations, that make me pretty sure that optional braces work better for a vast majority – where we start with braces to explain the concept of local scope and then drop them similarly as we do when explaining the use of semicolon and what a multi-line statement is etc… This way of teaching local scope by actually starting off with an explicit token is something you can’t do with Python if I understand it correctly. The braces help to initially understand the concepts of scope etc as you learn about it, but as they take up speed almost all students seems to prefer to skip the braces).

Ok thanks @soronpo ; good to know a tentative schedule for fewerBraces. As my course starts in late August I will not assume fewerBraces and just go with optional braces as last year (as I don’t want to require potentially unstable nightly even if it is easy to work with nightly using scala-cli). ((But it would have been nice if we could try it already the coming fall…))

This dismissiveness is pretty much what I’m worried about. This statement is trivially untrue because myself and others like me have pointed out that we’re an existence proof that this is not true for everyone.

To be told that our lived experiences are irrelevant and the difficulties we’re having with this will go away with either tooling (that has as of yet failed to materialize) or if we’d just work at it harder, is incredibly frustrating. I’ve tried the tooling, and I’ve made concerted effort on multiple occasions since at least as far back as 2009 to get past this, both in my spare time and professionally, so I’m intimately familiar with what I’m talking about when I say that if my college had mandated the use of Python, I probably wouldn’t have been able to graduate through that program.

Might as well tell a dyslexic to stop being a drama queen and just focus harder, because you’re “pretty sure the standard curriculum is better for all.”

My point is not that this style doesn’t work well for some, or even most. My point is that it can be a serious barrier, and if we do this we should be both clear about what this will cost, and spend enough time to get it right that we aren’t adding a fairly substantial patch to the syntax to try and fix it only 2 minor versions later.

2 Likes

I just updated my post with “vast majority” instead of “for all”. Sorry if my approximation was upsetting. Good that braces are optional so that they can be used when preferred. My students can use the style that they find help their learning the best. We discuss reading ergonomics a lot but our teachers in the first course do not enforce a coding standard. (Misleading indentation, not inline with the semantics of scope, will loose points though, with or without braces…)

I appreciate the update. Few things kill discussion faster than approximating someone out of the conversation.

It goes beyond that though, if all your sample code, any scaffolding you provide, and code snippets in exam problems use a style that’s illegible to a portion of your students, they’re going to be working at a considerable disadvantage.

Granted, it’s less severe, but imagine the pushback if you distributed a syllabus printed in red ink on green paper.

Regularly I have students that are color blind, have a diagnosis on the autistic spectrum, need silent rooms to concentrate, need visual aid due to sight impairment, hearing aid, etc. I have taught approaching 1000 students with Scala as first language since 2016 and last year almost 200 with optional braces and I have not yet observed a single “brace blind” student. (That does not mean they do not exist.)

My experience tell me that what students need in order to be fluent in reading scopes that are nested is a firm understanding of the concept of name scopes, shadowing etc. Once they are comfortable with those ideas the reading of code does not seem to be hampered by inferred braces, but for the students I have met instead increase readability, just like with inferred semicolons.

I have observed a significant effect of the influence of previous habits from those that have coded using mandatory braces before, but it seems to take around one week to get used to reading and writing code with inferred braces and the vast majority prefers them after getting used to them.

A small minority hang on to braces longer, but my understanding is that this small minority find braceful code more familiar or aesthetically pleasing, rather than not readable, and it is exclusively students with pre-experience with mandatory braces. I might investigate this a bit more the coming fall. That’s another reason I’d like fewerBraces so that we can work with them and investigate how the learning goes. Teaching is learning :slight_smile:

3 Likes

As someone who grew up in the 80s and 90s, and falls into 2 of the above categories, I can tell you that unless explicit effort is made to normalize a systemic difficulty, it’s all too easy to internalize it as something you are just too stupid or lazy to “get”.

This is incredibly hard to unlearn. It took reading your comment 5 times, and going back and forth on it 3 or 4 times, to decide to mention that having no line breaks makes your comment really hard to visually parse - and this is both a fairly common issue (particularly for people who are, like myself, on the autism spectrum), and relevant to the discussion at hand.

Point is, I wouldn’t put too much stock in your students not bringing this up to you. If they can’t read a program they’re supposed to analyze for an exam, they’re far more likely to write it off as a personal failure to handle exam stress, rather than approaching you about a visual processing issue that’s not really discussed often.

For context, my first 2 languages did not have braces (HyperScript and AppleScript use begin/end blocks) and I have no issues programming in Ruby, so this isn’t universally related to familiarity.

Braces themselves aren’t the issue, it’s the lack of explicit scope delimiters. Braces are just a common solution because they’re already in the language and begin/end blocks are awkward when chaining method calls that accept lambdas.

1 Like

Just added line brakes. Sorry for that. I also find my previous post easier to read now :slight_smile:

1 Like

Thanks for the pun! “Embrace” gets me every time.

I guess the new syntax after a while is

while b
do body

for the bonus pun.

Also thanks for the thoughtful conversation. I feel strongly that people deserve access to computer stuff as to music, art, literature, and clean water, food, and a warm bed.

5 Likes

Colon is a vambrace that protects us from bad scope, a bracelet shining as a token of bracelessness. </Non-concrete poetry>

2 Likes

My 2 cents …

I’ve worked extensively with Python, and with CoffeeScript. And have played with F# and Haskell, which also have significant white-space.

I never liked significant white-space because:

  • it can lead to situations in which the compiler gets confused, multiple interpretations being possible, as it happened in CoffeeScript; this is less of a concern in Scala, because it’s statically typed, and there are no instances in which you expect a function value and get a dictionary instead, but still, after all this time, the concern persists;
  • it can lead to the syntax becoming conservative; Python has not implemented multi-line anonymous functions, not just because of their culture, but also because it would cause trouble with existing syntax;
  • there are multiple ways to express white-space, see the endless spaces vs tabs debate, and you need smart good tooling to recognize this and do conversion on the spot, which is much easier when you have braces, and more difficult when that whitespace has meaning;
  • in Python, it led to very long lines of code, although this happened as a combination with other Python warts and practices;
  • in Python, you really need 4-space indentation, in order to visually discern where blocks begin or end; I remember experimenting with 2-spaces in my own code, and it wasn’t working well;
  • operations that are simple in Scala 2, like reformatting, or copy/pasting of blocks of code, become more complicated, increasing tooling dependence;

I don’t like that Scala switched to significant whitespace syntax, as I feel that Python had success not because of its significant syntax, but in spite of it. But then I don’t really care that much, as long as it’s properly implemented and a standard.

My wish is for the syntax to be clear, with no ambiguity. And preferably with the number of choices limited.

I don’t think we can say that the syntax is unambiguous, and Scala has been sliding more and more towards Perl’s TIMTOWTDI. We aren’t able to write in the Klingon language yet, but we aren’t very far; and it’s not just the new significant whitespace, but also the ambiguity of new keywords; like I’m still struggling to like given and using instead of implicit, and I can’t find a reason to, especially as both exist and usage of given yields surprises, but that’s for another day, another rant :slight_smile:

Either way, I believe that such experimental syntax changes shouldn’t be rushed, and it isn’t too late to retract them completely.

4 Likes