Scala 2.13 is now available
scala-lang.org
scala-lang.org
When I joined a few years ago, I was honestly not most excited about working with Scala, but the more I got into it, the more I realised that Scala got a lot of things just right.
In particular, I really miss working with the collections and futures API whenever I switch to another language.
And it's overall a pretty good package: very predictable behaviour, easy to debug (IntelliJ Idea helps a lot here), fast runtime and high quality libraries available for pretty much anything you might need.
1. The community was terribly split between FP purists who wanted to write Haskell on the JVM and pragmatists who leaned more towards the "better Java" side of things. Plus the occasional ex-Rubyists who came up with method names consisting solely of interpunction ("embedded DSL!"). Has any side won? It would be nice to have anything resembling "idiomatic Scala" out there.
2. The compilation times were horrid, really blocking a fast edit-compile-run(-tests) loop, often making my attention wander away etc. Has this improved sufficiently much that you can edit code, switch to the browser (or wherever) and pretty much immediately see the result?
And as always with benchmarks, your workload may give you different results. 2.13 will especially help with code bases that heavily use the collections library.
Yes, compiling a ~200 file project from scratch takes ~5 minutes, but it has scalaz, shapeless and a ton of other libraries, but this is basically only required when you import/open the project for the first time.
Using types for side effects (eg Slick does it for DB IO) and error handling (see also Rust's Result type) is great.
Scala's for-comprehension (which is Haskell's "do" notation) is a bit awkward (you have to understand that it's a syntactic sugar, and you have to learn about monad transformers, because you have to align the types, so if you started with an Option you have to return an Option, so you have to wrap your Futures and Lists, but it's pretty automatic).
There are a few things that seems harder if you are used to less pure languages, let's say you can't just manage a request context "somewhere" and rely on the dark arts of whatever Java (or Python's Flask) frameworks do. You have to pass around a context. Use implicits. For async Scala already wants you to pass around the execution context. And that's a good thing. Less black magic is always nice in the long term.
Going full FP can be ... painful. When all you see is functions, functions getting passed function, that return functions, that can be called with other functions that ...
Yes, sure, in the end the data is passed/transformed/filtered/mapped/reduced the same, but usually reading FP code is a lot less straightforward than it should be. (For example nice chained functions / data-pipelines are great, easy to read, etc. But going overboard with currying and function passing is not.)
Exactly. "Functional purists" write code that caters to their aesthetics. It's completely unreadable and a pain in the ass to debug, but it sure looks really nice and clean.
If pure functional programming really is a major benefit, it should show in the number of successful software projects. I don't see it.
For example, the other day there was a PR for creating a simple csv report and they wrote something like
val buffer = new StringBuffer()
buffer.add(header)
buffer.add("\n")
someList.forEach { item =>
val values: List[String] = someTransformation(item)
buffer.add(values.mkString(","))
buffer.add("\n")
}
buffer.toString
which is fine and readable, but it doesn't really seem like having side-effects (even though the scope was contained in the function and there weren't any worries about thread safety) aren't worth it over doing something like val rows: List[String] = someList.map { item =>
val values: List[String] = someTransformation(item)
values.mkString(",")
}
(header :: rows).mkString("\n") + "\n" // I forgot whether they appended the string with a line break or not...I actually also find it more readable, but that’s a personal preference
1) is more readable (fight me)
2) doesn't rely on internal optimizations for string concatenation, in order to be as efficient
3) doesn't create extra garbage (linked lists)
In fact, the only thing I would change is make it a for loop instead.
(header :: rows).mkString("", "\n", "\n")
My two cents: I prefer the second solution. Maybe it's because I have never programmed in Java.In idiomatic example of this style is the ByteString library that is used by akka.
> The 2.13.0 release improves Scala in the following areas:
> - Collections: Standard library collections have been overhauled for simplicity, performance, and safety. This is the centerpiece of the release.
> - Standard library: Future is faster and more robust. Elsewhere, useful classes and methods have been added.
> - Language: Literal types, partial unification, by-name implicits, more.
> - Compiler: 5-10% faster, deterministic output, improved optimizer.
Full release note here: https://github.com/scala/scala/releases/tag/v2.13.0
Basically tackling the core problems with the language, with minimal feature creep or additional complexity (I must admit to contributing to that creep in a small way)
Partial type application is frustratingly cumbersome. For the last 3 releases or so - which is what, 6 years of language development? - people have been using the kind-projector plugin to the point that it's now pretty much entrenched. Any kind of built in solution - even if it were just bundling kind-projector into the compiler - would have been better for the ecosystem in terms of things like good compilation errors (which experienced users don't notice, but can be a major pain for newcomers).
The situation for enums is even worse, with what must be a dozen competing libraries/macros/..., none of which manages to be as nice as Java's "enum" (to the extent that I actually write enums in Java when writing Scala). I get that everyone has their own preferences, but even if the solution was just to adopt the Java solution directly (but allow writing the body in Scala) that would be a huge advance from where we currently are.
I love Scala but I really wish the developers had solved these two cases before, effectively, freezing development of new language features for 5 years and counting.
And it's similar for the lampepfl/dotty repo (since 2018-01-01: 52 people, <10 active contributors) whereas the problem space is vast, the compiler is very intricate and brittle, the tasks at hand are many, and the language is complex, so trying any solution takes a lot of time and serious reviewing effort to try to make sure it doesn't cause any unintended problems.
And at the same time there are a lot of actively maintained libraries/frameworks/tools, but the overlap of the maintainers of those with the compiler maintainers is significant.
So all in all it's not surprising that things are not progressing super fast.
Other issues like better compiler errors and nicer tooling are being worked on. Both Scala and SBT have advanced a lot on that regard, and I'm eager to see what's next.
(It's possible that there's a better explanation in some of the meeting videos that have started being published; in principle that's a great move,but I'm not able to follow videos and there have never been any written transcripts/minutes available (I have asked))
I work at a fashion renting company and our backends are built on top of Scala stack.
Contrary to popular belief, Scala is actually quite a simple language. Most of our engineers came from PHP or Python, or Ruby and all have expressed how type safety gave them great assurances that everything works if it compiles.
On top of that the behaviour of the language is very predictable! We almost never use debugger because we can predict quite successfully what went wrong in case of bugs.
Lagom was such a nice framework, coupled with Akka service discovery makes building Event Sourced application so simple.
And for the same reasons.
First step was to learn SBT, which in itself is simple (building projects, dependencies, plugins).
Later we have them do scala exercises (scala-exercises.org) to understand Scala basics, and the philosophy behind Scala, onboard on Framework (Play/Lagom).
Then we move on to Slick, and then Future API, error handling with Try, for yield comprehension, map and flatMap, collections, and of course implicits.
The rest would be comments on pull request.
Interesting. Then why do some people say it is not? Anecdotal, mind you, and don't have links right now.
<edit>
what makes me think it is a simple language (especially if you are writing microservices):
- class is a class, and you don't really need to explain the modifier
- object is just an object, like if a class is instantiated, and it is a singleton
- trait gives you mixin, cake pattern / self type
- Future makes async programming simple
- for yield -> to avoid nested map / flatMap
- val for everything, instead of final static
- case class, such a life saver to build immutable data objects
Some libraries like Slick adds up complexity but the benefit i think far outweigh the difficulty of learning it.
Now onto 2.14 and Scala 3!
Scala already doesn't offer binary compatibility between major releases, which in itself is a bit cumbersome but it allows them to innovate the compiler. So the change will not be as drastic as it might look.
In addition, 2.14 is meant to be a release that eases the transition to Scala 3.
* Scala 2.14 and Scala 3 will be binary compatible (via an intermediate form called TASTY)
* The Scala 3.0 compiler will accept most Scala 2.14 source minus some deprecations that have been coming for a while
* Scala is a compiled language and a statically typed one at that, so any source incompatibility or library API incompatibility will be caught by the compiler; fix the issues pointed out and you're migrated.
Except for some really well motivated very advanced language features (eg view bounds) most code should be source compatible, and Scala 3/Dotty is able to use Scala 2 libraries and there's plans for forwards compatibility with Scala 2.14 (2.14 being able to use Scala 3 dependencies)
The big exception is macro's, because they depend heavily on Scala 2 compiler internals. A lot of things you require macro's in Scala 2 will become language features in 3, but for other cases the macro system for 3 is still in active development.
In the abstract, it's the only mainstream language to offer both higher-kinded types and traditional OO ("extends") inheritance. From one side it offers all the good stuff of OCaml, F#, Swift, Kotlin, or Rust, but with a better type system that makes handling secondary concerns via "context-like" types a breeze. From the other side, it offers similar power to Haskell, but with more understandable performance, a better library/tool ecosystem (IDE, profiler and so on), less reliance on memory-unsafe code in practice (a lot of things in Haskell require C-wrapping libraries for things like image formats, whereas the corresponding cases in Scala wrap Java instead), and the ability to use traditional OO style if you want.
Bazel works well too: https://github.com/bazelbuild/rules_scala
But I do accept that sbt is not everybody's cup of tea.
Sure it is not perfect, but the alternatives are much worse and most of the issues people have with SBT projects are other people abusing the build file.
The REPL, fast incremental builds, continuous unit testing, shared SBT sessions, etc makes my day so much better.
I live all day long with: `~testOnly *WalabySpec -- -z killRoo`.
Whenever I have to jump into an app using Maven or only slightly better Gradle it is so frustrating.
Oh, and it's much faster nowadays.
Anyway I don't think it's worth dwelling on popularity. Networking and political effects seem to be more powerful than the merits of a language.
Not best of both, but it's the ability to solve the task with either FP or OO depending on the task and do it seamlessly.
> Networking and political effects seem to be more powerful than the merits of a language.
That's probably more true than anything, also it's not hipster enough to convince your regular clojurescript aficionados.
It seems that if you want a multi-paradigm language, Scala is excellent. But if you just want to go down the functional route or OO route (without overlap), there are arguably better choices.
I seldom see conference talks how to optimize Maven builds, Gradle talks about build optimization, at least one per Java conference, and several per Android one.
Just Google IO 2019 had three talks about it.
I've never had a gradle build that didn't manage to remember I've only just compiled the code and haven't changed any of it. I can't remember ever having a maven build that could tell I didn't need to compile every single time. And the same the whole of the way down the stack.
Nice attempt to imply gradle isn't declarative though.
Again just Google IO 2019 has three talks about tackling build performance issues.
Maven never required a build performance profiler tool.
Gradle is just like Ant, give DevOps a programming language DSL and they will make a mess of build scripts.
See https://scala-ci.typesafe.com/grafana/dashboard/db/scala-ben...
Also SBT has been much less of a nuisance recently. They've made quite some effort to get rid of the most obscure syntax and with the recent improvements in compiler speed it's inching to 'acceptable' territory.
I admit that I really love the language, though.
All of these factors contributed to Scala adopters like LinkedIn subsequently retracing their steps and doing new development only in Java.
So, academic origins are fine (many good programming languages have academic or at least research-influenced origins), but an academic attitude to the development work that a language should support (predictability of breaking changes, possibility of good IDE support) harms the adoption of a language.
Note that I'm not saying Scala is bad, it just wasn't an easy enough transition for me to justify climbing the plateau. Clojure ended up being a similar situation. These languages are also optimized around writing large software projects and that was a hindrance rather than a benefit to someone that does more scripting than anything.
Also many people are doing scripting on Node runtime instead of JVM.
Sometimes Scala teams are more expensive to set up. So there are budget-friendlier alternatives (Java, PHP, Python, NodeJS) for many projects.
Don't get me wrong - Kotlin is a nice language. But Scala is one of the most language to bring novel ideas in to the industry. There will be even dependent type in Scala 3.
A lot of people are keep bashing languages like Scala for complexity. I don't think they are wrong but in this way the industry is moving slow compared to the reckless style in 90s. People are just too caution with new languages nowadays, which makes things harder for new ones. New languages have to add a lot of compromises to get attraction.
There's still a long way from carpentry to engineering.
Can anyone share their experience where moving from Scala to Java yielded measurable benefits, besides "it's more fun to program in Scala"?
You can't underestimate how much the motivation of developers and their enjoyment and engagement with a project, feature, or any given code change actually impacts the overall delivery.
Now, if you don't find it more fun, more engaging and more motivating, disregard this. But my point is, any language, tooling, environment, team culture, etc., which will bring you "more fun" will actually make you deliver way better software as a side effect.
This is a pretty huge deal. Our backend API depends pretty much exclusively on these, and everything is wrapped in them. Performance enhancements for these will bubble into basically every Scala Play app.