Scala 3 significant indentation

Unless I’ve somehow missed something that I’ve been actively watching for, there is still a fairly vocal segment of the community (of which I am a part) that is at best unconvinced that syntax based on significant indentation is anything but a massive step backwards. The oft promised public discussion and feedback gathering about this has never materialized (there’s also never been a SIP proposal thread for this, which is passing strange considering how big of an impact this has on the language), in favor of statements which presume that this is simply The Way It Will Be or “You’ll like it, if you give it a chance” (I did, and it was just as bad as it ever was in Python).

Because of these statements, it’s unlikely that if the promised opportunity to give feedback ever materializes, that there will be confidence that the feedback provided will be taken seriously - aside from the perception that the decision is already made, even if we are heard there simply isn’t time to walk back the current decision, given the published timelines.

If it’s going to be done by fiat, we’ll have to learn to live with it or forgo Scala 3, we literally have no other option but forking the language (which is prohibitively expensive), but it would be nice if we could get the courtesy of acknowledgment that this process is a polite fiction. Aside from the utility in managing expectations, it would be nice to have closure on this matter.

14 Likes

I would rather have this meta-discussion in a different thread.
I do not accept your premise that the process is fiction, well, definitely not all of it.
The part that the community has a chance to provide feedback and suggestions takes place. You can see so clearly in this thread alone that three weeks out of RC1, Martin is willing to take a change with a late proposal by the community.
So you ARE being heard. It does not mean everything you say manages to change people’s mind, and not every suggestion is being responded to.
What IS a problem in the process is the lack of public discussion by the SIP committee which has not convened publicly for some time now. And when you compare it with “old-way” of doing SIPs back in Scala-2 land, it is very asymmetric. Just see how much time spend in public SIP meeting discussion on minor changes like trailing-commas vs. NONE for indentation syntax. So from a bystander’s view, it looks like the community has no effect over decision making, which is not so.
Regarding the decision process itself, I do believe that Martin has some prerogative to force the hand when he wishes so, even beyond the official right to veto out a change.

As for the indentation syntax, I myself am still on the fence. I can see the benefits, but I also think that this will definitely split the way things are done. We will have to keep both syntax styles. I see no way around it, but it may help bring more people into Scala. I was a strong objector at first, especially when it was first introduced during a time where there were far more important things to discuss and do and it seemed too distracting.

2 Likes

What you are basically saying is that the powers to be will unilaterally make decisions on those things they deeply care about, and for things they care less about, they will open the field for community feedback.

It’s not as bad as Python - it is far worse. In Python, indentation replaces all braces, but in Scala, it would be a mix of indentation, parentheses and braces.

7 Likes

@curoli got very close to describing how I view this issue:

The problem is that the powers that be will unilaterally make decisions on those things they deeply care about while pretending not to.

I have no expectation that Linus will give any input I have on the Linux kernel any attention. That doesn’t bother me, because there’s never been any indication that would be the case. On this matter, however, we’ve repeatedly been told there would be a public discussion and opportunity to provide feedback, and that simply hasn’t materialized, and that’s a big problem.

The biggest part of the problem is the disconnect between, “we take the feedback from the community into account,” and the perception that what’s actually happening is, “we take the feedback we like from the community into account.” This means that, however much the powers that be seem to be willing to take community input on the stuff they don’t care about, it’s still very much a polite fiction because it’s entirely at their whim, and that’s not how it’s presented.

If the process can be a fiction for a change this disruptive, that means that the process is a fiction for anything less disruptive than this, it’s just more convincing in some cases than others. This case is particularly glaring because the dodges have been rather obvious. I don’t know if this is because the powers that be simply don’t care, or if they’re worried they won’t be able to make their case if they try to actually sell it. My guess is the latter, as the current implementation is full of irregularities, and the situations where it does work tend come up more often in library code than in application code.

The problem is that we’re not being heard, we’re not even being outright ignored. We’re being told, “lets put a pin in this,” and it’s become clear that it won’t be revisited or that if we do manage to make enough of a stink to force this through the published process our feedback won’t go directly into the round file.

If he’d just said outright, “this is how it’s going to be, put up or shut up,” this would be a dead issue. Promising there would be a discussion on the matter, then switching to treating it like there’s consensus after almost a year of silence is uncomfortably close to gaslighting. Particularly galling was the Dotty Language Survey, which treated a single semester of 2nd year CS students as somehow representative of Scala developers as a whole. There are a lot of things that 2nd years CS students think are a good idea that don’t work out in the real world.

5 Likes

While we’re on the topic of indentation, what I’m afraid of is that even if 99% of current Scala developers love it, what can happen is that many Scala codebases will mix styles, exacerbating one of the major reasons a lot of people have a bad taste in the mouth about Scala, that code varies too much. Personally I like that braces and parens are interchangeable except that multiple statements require the former and multiple values require the latter, but many people don’t. I am very nervous that this new divergence will seriously hurt adoption and Scala’s [potential] popularity.

7 Likes

There is always scalafmt that can force a style. Even currently there are various ways to write exactly the same executional code but in a different way. You already know that the answer is always scalafix, so put scalafmt alongside it :wink:

4 Likes

If scalafix is always the answer what’s the deal with infix? The only reason it exists is to give people less choice in how to write an expression.

So optional infix bad. Optional braces and optional end markers good.

4 Likes

I agree, but please remain on topic.

Unless Scala 2.13 is retrofitted with the given/using/extension constructs, you will anyway have mixed styles for years to come, as a huge base of Scala 2 projects will be around for long time, and for cross-building you have to stick to implicit. That’s kind of the price to pay for a smooth transition that doesn’t just kill off everything that has been written for Scala so far. By the time 2.13 is no longer a concern, it will probably also have become clear if indentation-based style has been widely adopted or widely rejected. (My bet is the former).

2 Likes

I thought Martin’s comments were just about that it is present in scala3 (a given). As long as it remains rewritable then we can convert later, if desired, once everyone uses it extensively and then decides after a discussion.

I always thought it would require being used in the wild before a real discussion could ever take place and hence this discussion was much further in the future.

Was there a commitment to make a final decision prior to a 3.0 GA release?

I usually do not comment on SIP issues but I got so tired of so many layers of braces with little added value that I’m hoping it would really make “typing” and “reading” easier like I feel that it is in python.

I am sure that for every person that feels this way, there’s a person that feels the exact opposite.

6 Likes

Indeed. And also let’s all please keep in mind that most people here aren’t noobs with no programming experience. Even though I’m sure it’s not anyone’s intention, it can come across as dismissive and even a bit condescending to keep throwing around the “I’m telling you it’s good and you’ll learn love it once you give it a chance / get used to it” response. I presume that most programmers have worked in other languages before and a decent subset will already have experience in indentation-based languages. It’s unfair to always attribute their objections to inexperience.

I’m an example. I’ve experience in both styles and I’ve come to think that braces are better than whitespace. I’m not super passionate about it but overall I find there are no real advantages to one other the other, but, subtle and significant disadvantages to whitespace.

10 Likes

Btw can we clarify what the plan is? I was previously under the impression that one style would be chosen for Scala 3 and be the only style supported from 3.0 onwards. Then reading the above it sounds like both styles may be available simultaneously and then in the far future, one dropped. It would be really good to clarify what the story is.

2 Likes

Well, this was said on the gitter channel

So brace are going to stay no matter what (?) yielding even more styles of writing code.

3 Likes

Although I sympathize with the sentiment that there is not a lot of transparency on this issue, Martin Odersky is moving mountains to nail down “asless givens” very late in the development cycle. I think the claim he isn’t listening is unfair. Indeed, one may say that Martin must go to the mountain.

I would say it’s the process equivalent of an implementation restriction.

Let’s stipulate that the feature is “optional braces.”

As already hinted, it’s the same as if you felt strongly about using semi-colons. For example, the following semi is optional:

for (x <- xs ; if x > 0) yield x + 1

as is this one:

v match { case p() => x ; case q() => y }

and this entirely apart from the line-ending semi, which may or may not be optional:

def f: Int = 42;
  + 17

as attested

➜  ~ scala
Welcome to Scala 2.13.4 (OpenJDK 64-Bit Server VM, Java 11.0.9.1).
Type in expressions for evaluation. Or try :help.

scala> {
     | def f: Int = 42
     |   + 17
     | f
     | }
         + 17
         ^
On line 3: warning: Line starts with an operator that in future
       will be taken as an infix expression continued from the previous line.
       To force the previous interpretation as a separate statement,
       add an explicit `;`, add an empty line, or remove spaces after the operator.
         + 17
         ^
On line 3: warning: a pure expression does nothing in statement position; multiline expressions might require enclosing parentheses
val res0: Int = 42

scala>
:quit
➜  ~ scala -Xsource:3
Welcome to Scala 2.13.4 (OpenJDK 64-Bit Server VM, Java 11.0.9.1).
Type in expressions for evaluation. Or try :help.

scala> {
     | def f: Int = 42
     |   + 17
     | f
     | }
val res0: Int = 59

scala>

Needless to add,

➜  ~ ~/scala3-3.0.0-M1/bin/scala
Starting scala3 REPL...
scala> {
     | def f: Int = 42
     |   + 17
     | f
     | }
def f: Int
val res0: Int = 59

scala>  

Let’s also stipulate that if you’re not doing K&R braces, you’re not really doing braces anyway.

braces and parens are interchangeable

Let’s agree that this has no syntactic basis.

For example, to explain f(x) and f { x }, you might say that f(x, y) is the anomaly. If a function just takes an arg, it doesn’t matter if the arg looks like an expression or a block. (Apologies to the educators.)

Another optional chestnut is extends:

scala> object X extends { def x = 42 }
object X

scala> X.x
val res0: Int = 42

I would suggest that the uproar over optionality has much in common with differences over the formatting of comments. Scala acknowledges two or three formats, of which all but one are misguided and wrong. Such is the state of political discourse in America. But I think the important thing is that people can make headway in whatever it is they undertake.

3 Likes

No. The indentation syntax has always been called “optional braces” (by analogy with scala’s existing optional semicolons support): https://dotty.epfl.ch/docs/reference/other-new-features/indentation.html

I think the name “optional braces” is a bit misleading, because it might be read as making all braces optional. But actually, the proposal only makes some braces optional, while other braces are still required.

I’d be willing to endorse the rubric “some optional braces”, if we also advertised “some optional semi-colons”, because not all semis are optional. Depending, as some wise person must have said, on context.

2 Likes

Oh ok thanks, I guess I missed that. In that case what’s the long-term plan or motivation for this experiment? Is it that if i works out well and is favoured for many years, that braces might go away in 4.0 or something? Is the long-term vision whitespace default, braces optional like it will in 3.0+ and then one day the Scala stops calling it experimental? Is it literally just an experiment to see where it leads, no long-term vision in mind? Maybe it’s just me but I’d appreciate a bit more context to understand this better.

4 Likes

Yes, maybe “Sometimes optional semicolons” is more accurate.

On the other hand, it is different in practical terms. Your example with the +17 is a bit strained, because the +17 serves no purpose.

In my code, I’m not sure if I have even a single semicolon, but there are plenty of places that cannot be written without braces, for example I have methods that look like this:

def m(f: A => B)(g: C => D): R = ...

and then are typically called like this:

val result = m { a =>
...
}{ c =>
...
}

and as far as I know, the above call cannot be written without braces.

I guess they can do the recursive Fibonacci numbers in CS 101 without braces, but I don’t think that should be the standard.

3 Likes