Making scala easier and more popular, with compiler level switches

The biggest problem with using only feature found in Java is that:

  • It would exclude a number of features that are nice and easy to use at least in their basic form, such as case classes, pattern matching, powerful type inference and uniform access.

  • You can do pure functional code in Java. It’s a lot more work than in Scala, and therefore less common, but it’s entirely possible. The resulting code would be at least as hard to understand as the Scala analog.

I sympathize with the OP’s desire for compiler-enforced complexity levels for Scala. I recall a similar discussion a few years ago. I may have even initiated that discussion, but I honestly don’t recall. In that discussion, I pointed out that Ada (remember Ada?) has something called the Ravenscar profile, which is a restricted version of Ada for safety-critical applications. There is also something called Spark Ada, which is even more restricted and has additional features (including programming by contract). Spark Ada is for really safety-critical stuff (railroad switching and nuclear missile launches?).

But these restricted versions of Ada are not intended for novice programmers. They are languages subsets with ostensibly “dangerous” language features removed.

Others here have weighed in on the technical problems with the concept of different level of the Scala language enforced by the compiler. I would like to comment on the underlying problem that the OP may be missing.

The underlying problem in my view is that too many programmers use advanced language features when they are not needed. Programming is a constant cost/benefit analysis where “cost” is in terms of complexity, so let’s call it a “complexity/benefit” analysis. If something can be programmed more than one way, the simplest way should normally be chosen. But too many programmers use a more complicated feature than they need for a particular problem. Sometimes they do it to “show off” their skills, and other times they do it simply because it is the first solution that came to mind, and they didn’t bother to look for a simpler solution.

My view is that the supposed “complexity” problem of Scala is widely misunderstood. Scala is designed to do many things, from simple to complicated. Good programmers do simple things is Scala with simple code. Bad programmers do simple things in Scala with unnecessarily complicated code. Good programmers do complex things in Scala with code that, although it may not be simple, is usually simpler than what is required in other languages. Scala gets its undeserved reputation as an unnecessarily complicated language from the bad programmers, I believe.

Getting back to the OP, I think what you need are task managers who can break programming problems down to various complexity levels and assign programmers accordingly. Then have senior mentors and code reviewers that can tell the junior programmers when they are using unnecessarily complicated language features to solve the problem they are assigned. If the simpler features can’t do the job, then the task may need to be bumped to the next level.

But basic features such as immutable case classes should be used for even the simplest problems. The idea is not just to use Scala as a Java with a different syntax.

And if there are several alternative ways to do something, using different features, different people will have different opinions on which one is the simplest.

So that step – “sort them” – is where your premise breaks down. You’re assuming that there exists a single, clear, appropriate order, and I am certain that you are wrong.

Seriously: the features that are “easy” for someone coming from Java are not the same as the ones that are “easy” for someone coming from JavaScript, or even C#. And a lot of the features that you think of as somewhat “advanced” (including the FP way of looking at things) are often easier for someone completely new to programming, who doesn’t have to unlearn bad habits from imperative languages.

Hence, while I agree that a graduated approach can be helpful, I think that trying to ram it into the compiler is misguided – it’s vastly harder than you think to implement, difficult to define correctly, and very low-value in practice.

It makes far more sense for something like this to be adopted project-by-project, with projects deciding what makes sense for them, and enforcing it using external tools. That can be done in a more nuanced way, understanding the needs of the project and its own community, rather than trying to artificially enforce something across the entire Scala world. (And it could be done in months, rather than the years it would take to do at the compiler level.)

Basically, this needs an open-source ethos: there’s nothing like working code. The right way to tackle this is probably to build something in Scalafix, promulgate it, get into discussions with like-minded folks about where the lines should be, how to define different versions of the levels, and evolve it from there. That could actually work – unlike trying to get the compiler team to do it for you, which I strongly suspect will prove to be a non-starter…

1 Like

I agree with @jducoeur (and earlier comments from @martijnhoekstra and @Ichoran). Make it work for yourself first, then see if others think it’s interesting. There are many ways to constrain the Scala dialect your team uses, including:

  • Compiler Flags. There are a bunch, and they are extremely useful for constraining the kinds of programs you can write. I have a starting set of 45 flags (!) that I use for new projects.
  • Scalastyle. This is a syntax-driven style checker that’s a bit heavy-handed but it can be useful for enforcing the way you use aspects of the language.
  • WartRemover. This is a compiler plugin that lets you turn off unsafe parts of the language such as asInstanceOf, Option#get, and null. It’s becoming a bit dated and will likely be subsumed by …
  • Scalafix. This is a linter and code rewriter that can enforce arbitrarily elaborate code preferences. It is infinitely customizable.

Some combination of the tools above should get you to the point where you define “Level 1 Scala” and try it out with your team.

Good luck, have fun!


PS - The idea of language levels goes back a long time. They have existed for more than a decade in Racket (and its predecessors) and have worked very well as a teaching tool. But Scheme and Scala are very different languages, and teaching total beginners is very different from teaching experienced programmers.

2 Likes