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

Hi all, first time posting here! (*)

I would like to propose the idea of a community poll to have some actual datapoints regarding the effectiveness and usefulness of SIP 44, rather than implementing a patch for it.

SIP 44 had been a controversial enhancement that caused quite some debates among Scala devs in the past, and had a rough start due to IDE like IntelliJ or LSP (metals) having difficulties to support it properly, tools like scalafix/scoverage having a late adoption, and IDE features broken altogether (i.e. jump between start/end of a code block).

I think that, after 4 years from its introduction, it’s the perfect time to get some feedbacks from developers who used Scala 3 on real-world applications about how useful SIP 44 is, how widespread is its usage, and then decide between move this pre-SIP forward, or announce the deprecation of SIP 44.

What do you think?*
*
(*) although I’m working with Scala for more than 10 years

2 Likes

You’re going to find that some people use it a lot–and how you conduct the poll will determine how large that fraction is.

I use it all over the place for control constructs. Run a future?

Fu:
  do_slow_thing()

Something might cause an error?

Ask:
  val result = do_dangerous_thing().?
  baz(result)

Run a while loop on part of your array? No way!

xs.visit(3 to End-3): (x, i) =>
  buffer += foo(bar(x), i)

And so forth and so on. My code all now looks like this

    val results = results0 :+ Fu:
      val count = Atom(0)
      (path / Location.neuronPositionList.head.filename).parent.foreach: p =>
        if !p.exists then p.mkdirs().?
      Location.neuronPositionList.grouped(6).map: locs =>
        val need = locs.select: loc =>
          again || !(path / loc.filename).exists
        if need.nonEmpty then
          println(need.map(_.filename.path.name).map(x => f"$x%-11s").mkString("Fetching ", " ", ""))
        val work = need.copyWith: loc =>
          Fu:
            val got = nice{ requests.get(loc.url) }.?
            if got.statusCode != 200 then Err ?# "Could not get ${loc.url}, status code ${got.statusCode}"
            count.++
            (path / loc.filename).write(got.bytes).?
        work.fu().ask()
      .toArray.?? __ Unit

Now, whether or not that feels great, awful, or indifferent to you, it works really well for me. I use it to great effect to write a rather different, extremely efficient and low-ceremony code style. You will find other people who have too (with different libraries, so the details will differ).

For me, it is this alone that makes Scala very clearly my first-choice language. Otherwise it might be first, but it would be far less clear.

The SIP-44 ship has sailed, and it’s gotten to some very interesting shores. There are some SIPs that might make sense to revert based on experience, but this isn’t one of them.

However, that doesn’t mean that this proposal is a good idea. I kind of dislike it aesthetically, but on the other hand I run into it probably half a dozen times a day.

4 Likes

I would be more than happy to know what fraction that would be, big or small doesn’t matter, because at least we would have some concrete numbers to begin with, and have a honest discussion on this subject, instead of endlessly fencing each other the usual arguments “i think it’s good” vs “I think it’s not”.

Reason being: just because a SIP 44 was discussed, approved & implemented by the Scala Committee, doesn’t automatically mean that all the broader audience would find it useful in their day-to-day jobs. And to some, it actually prevented to move to Scala 3 until the rest of the ecosystem/IDE/tooling caught up. Therefore, after four years of public availability, I would argue that it is the perfect moment to gather feedbacks from the broader Scala community and what is their opinion on this because, other than trying to lure Python devs, it doesn’t bring any advancement in the language from an academic point of view, i.e. from a type/language theory standpoint.

See my points above about luring Python devs & type/language theory; as the old adagio goes: don’t cling to a mistake just because you spent a lot of time making it. if we have concrete polls we can discuss if the ship has to be decommissioned or not.

1 Like

Moderator action: Extracted from Pre-SIP: Allow single-line lambdas after `:` to keep that other discussion on topic.

2 Likes

But if the tooling has caught up, this is now irrelevant.

It is relevant if we’re discussing a change to syntax that will break tooling again. But it’s not relevant to the original.

In fact, if you reverted SIP-44, the tooling would all be broken again.

So if SIP-44 ought to be reverted, it would have to be because it compromised something really important like correctness in ways that couldn’t reasonably be fixed because it’s broken by design.

If you just want to know if it’s used in the wild, you can just grep:
rg ':\s+\w+\s+=>\s*$' Files.scala | rg -v 'case'

(This doesn’t catch everything by a long shot, but it will tell you whether it’s “extremely obscure” or “somewhat common” or “all over the place everywhere all the time”.)

That’s fair, but we should keep in mind that statistics about how much it is used are only half the story. Among projects that haven’t made the jump to Scala 3, a survey asking “why not?” might be fairly informative, at least in terms of understanding what the community wants and how to prioritize. (Something we have tended to be fairly bad about actually asking.)

Even I (one of the loudest voices against indentation-based syntax) have accepted that it’s a reality and that isn’t going to change. But I do find the code examples being published by the team to be increasingly incomprehensible as they’ve tried ever-harder to strip out every possible parenthesis, and I still don’t understand why anybody likes this style, which seems to me much less consistent and teachable than the old style.

It’s made me much more cautious about encouraging my team to move to Scala 3 (despite how much I love everything else about it), and I’m only likely to do so with some firm guidelines about syntax. And if we ever switched to indentation-only (which nobody is saying, but keeps feeling like the goal being pursued), it might well drive me away from Scala entirely.

3 Likes

Absolutely! But that’s quite a different thing than asking about SIP-44 with a goal of acceptance or removal.

I’m sure one can use it in a way that makes code incomprehensible, just like people used infix, or chaining, or symbolic names, or whatever else.

But one can also use it just to elide clutter. And that’s great. You can get to the meat of things faster without losing anything, as long as the indentation actually leaps out at you. If you’re one of the people for whom it doesn’t, it’s probably infuriating.

It did take me a while to adjust, but now that I have I find that I both write and understand code better than before.

Key to that, though, is (1) keep braceless style short; and (2) brace classes and objects and class-like things (e.g. extension blocks) unless they are extremely short. end is okay, but it solves the clutter problem by introducing even more clutter and that isn’t really a win in my book.

If you start including end everywhere, it’s basically just writing Pascal instead of C.

Yeah, exactly. (I’ve been making the same Pascal observation for quite a while.)

For small blocks in which I am strictly removing existing syntax, I think it’s great. But all the new syntax that has been added in order to allow you operate without braces feels counter-productive to me, not to mention ugly. It feels to me like the result comes out worse than where we started.

So long as I can set a firm scalafmt standard for my team saying that eliding braces is okay, with a cap on the size of the block allowed before braces get added, and probably some rules against using all this added syntax, I’m basically okay – that would result in an evolutionary path that I believe in, with enough guardrails to keep the team aligned.

It’s just terribly disconcerting to keep feeling like all braces and parens are being deprecated, at the social level if not (yet) the technical one. The result is that it feels like the community is diverging, in rather the sorts of ways we swore we were going to avoid at the beginning of the Scala 3 project.

5 Likes

I believe one of the difficulties with end markers is that people are unclear about where to put them. Certainly not every time a construct closes, that would indeed be Pascal (or Ruby).

So here’s what I found to work really well for us:

Use an end marker if the closing scope extends over at least one empty line.

That’s it! One might think one also needs a size limit, something like “use an end marker if the closing scope has more than N lines total”. Occasionally that may be true. But in most cases if you feel like you need an end marker because the scope it closes is too long you should consider at the same time breaking the scope up into sections with blank lines between. Once you have done that, the rule in quotes applies.

Pieces of code between blank lines are like paragraphs in prose. And end marker is recommended if several paragraphs follow each other in a nested context.

With curly braces we get visual vertical space added automatically because we put closing braces on separate lines. With indentation we can add vertical space where it makes the most sense. That does require more thought but leads to a better result.

I think that strategy works when you have a style that uses few blank lines to begin with.

Personally, I need more breathing room; I need clear chunks, as cognitive scientists say. So I have a style that has more blank lines. Ironically, because I don’t have the lines with just the } anymore, I have to compensate with more blank lines. Moreover, virtually every time I close more than 1 block at a time, I need an end marker to visualize things accurately.

The end result is that I have a lot of end markers. Or, I have to make a trade-off and introduce fewer blank lines than I would like in order not to need the end markers. But then I make it harder for my brain again, because there isn’t enough breathing room anymore, and I need to concentrate harder.

With enough thought put into the formatting of each method I write, I get to something I can comfortably read. But I shouldn’t be spending all that time thinking about the perfect placement of blank lines and end markers. I wasn’t spending that time when writing braces.

6 Likes

I think your last paragraph pretty much concludes the issue with the “fewer braces” syntax. It is not the sytnax itself – it is nice and slick. The problem is a new turmoil of choice that Scala3 introduces: should I close a block with end or not, or should I fall back to curly braces? I find myself thinking too much about formatting, which I didn’t with Scala2 and which I shouldn’t do.

3 Likes

I have a really hard time understanding the value of this.

If the syntax doesn’t appeal to you, don’t use it.

If you spend hours a day choosing between ways to write your code, just make a proper scalafmt config and stick to it.

For me, the trick is to not fall into any of those camps. I’ve written both Python, Java, Typescript, Elixir, Lua and Kotlin for years. I think the freedom this gives is amazing, because the code gets amazingly easy to read. Occasionally I need { } if code blocks gets big, but that’s usually a smell of need for refactoring.

I spend 0 time on this in practice.

3 Likes

I think the major value would be guiding how the official documentation is written, which can inform how library authors write their documentation.

At least my experience is that, at least for the code examples I’ve seen in the wild, not only can it be used to make code incomprehensible, it generally is being used to write code that is incomprehensible (at least to me).

The upshot of this is that documentation is becoming increasingly hard to follow. The Specs2 documentation is one example of a situation where I had to update some legacy tests and I spent far more time in the docs than should have been necessary, largely due to how difficult I found it to read their code samples.

Because of how polarizing this change has been, the poll would have to be done very carefully to avoid the perception of it being used to justify one side or the other, but with that caveat, I think it would be good data to have.

6 Likes

Well, that’s a broader issue of accessibility, though this may be one of the most important cases.

Not everyone has the same level of difficulty with seeing indentation (or seeing braces, for that matter). It would be good to know how prevalent this is.

It is more important than usual as a change than if it had been here from the outset, because people who already settled on Scala expecting one experience are then forced to have a different experience (or quit).

However, I’m not sure that a survey is actually the right way to go to investigate that, because that conflates grumpiness about change in general with a cognitive processing difference that cannot easily be overcome. I’d rather see a psychophysical test. That might be too difficult to set up, so the survey would be the best proxy we could hope for. But I like to at least anticipate what the right measurement would be to answer the question in an maximally actionable way.

2 Likes

Wow, I didn’t expect to have a dedicated topic about this!
I’ll try to respond to any of you, as I saw lots of interesting points being made (thx a lot!).

That is why i never said to revert, but to deprecate it. And that would mean making a reasonable sunsetting plan (i.e. start with deprecation and then, maybe the time Scala 4 or 5 gets released, remove the functionality altogether, giving everybody sufficient time to adapt their existing codebase).

This is a very good summary of my thoughts; syntax is getting way terse, more close to a code-golf exercise, rather than something that should be understood by engineers with a variety of different backgrounds.

However, I do admit its usefulness when it comes to educational snippets: if used carefully, leads to nice & concise examples that fits into a tweet/linkedin post. But yeah.. that is, for me, the only good example I can find for SIP 44.

That is actually a very good compromise I could live with :heart:

Same shared feeling here as well :frowning:

Yup, I fall into this category as well: I need clear, visual separation of the code blocks I’m working with, in order to ease my reasoning process. I would have quoted all your message, but it would have made mine way too long (of what already is :sweat_smile: )

100% agree on this

Well, we should to start from somewhere, shouldn’t we? “Conflating grumpiness” feels more like a potential issue, than a realistic one.

I’ve found significant whitespace impractical for anything beyond trying to squeeze your code into presentation slides, and the default of “braces allowed, whitespace allowed” isn’t a good compromise.

The feature being on by default actively gets into the way of writing code fast, because it introduces ambiguity when there used to be none (whitespace can make or break your compilation, whereas it used to be just the formatter’s problem). That’s just the tip of the iceberg.

If it’s any datapoint, https://makescalacurlyagain.com/ (i know, i know… not my domain choice, but it’s easy to memorize) has 25 stars.

Teams at the company I work for are mostly disabling significant whitespace as well. Those that decided to go for fewer-braces a couple years back, have since made the move back to braces.

Doing a poll would be nice, but it cannot be limited to this forum, and given how strongly people feel about the feature (both ways) I doubt anything can be done at this point.

3 Likes

Indeed; my idea was to advertise it on multiple mediums (Reddit, Twitter, LinkedIn, ScalaTimes) such that we can reach out most of the Scala users. More ideas are welcome !

I’d rather find individuals that work at large companies (4k+ employees), that use or have used scala to some significance, and have them conduct polls internally and report back (with some mechanisms to ensure non-tampering).

By large and far most people don’t engage in these forums and those that do clump together and form vocal minorities that inundate every conversation drowning any nuance. Meanwhile those that were ignored or drowned in the noise at some point, leave and don’t return due to the unpleasant experience.

This data gathering, which was suggested so many times, feels like one of those things where you’re damned if you do and damned if you don’t.

3 Likes

And thrice damned if you do it poorly :cry:

The alternative though is to proceed more-or-less blindly

Oh absolutely. I think it’s better to trust the decisions made, for better or worse, and go fully with it. The middle path feels worse to me. You alienate both “sides” and cause lots of attrition for teams that would like to do a project in it.

In the end, no matter what you do, you’ll lose users, but hopefully you’ll also gain users that appreciated your choices. I say this as someone in the braces camp, but I’ve already made my peace with the fact that I (an ex-java developer) am no longer the target audience, and I’ve enjoyed scala for close to 17 years now.

1 Like