After some functional programming on day two, it’s time for the third and final day of Scala in Seven Languages in Seven Weeks.
Scala, Day 3: Thoughts
After two lengthy chapters on the object oriented and functional programming syntax/options in Scala, the third day rushes through some of the most intriguing features, including pattern matching and concurrency via actors. I would have preferred to spend a bit more time on these complicated topics.
In fact, I had the same complaint on Day 3 of IO, where we also blasted through a discussion of concurrency in just a few pages. I respect the difficulties of plowing through seven different languages in a single book and don’t expect deep discussions of any one of them, but I think the book would’ve been stronger if it had a greater bias towards the more advanced “day 3” topics of each language instead of basic syntax discussions in day 1 or 2.
Scala, Day 3: Problems
Extend the “sizer” application to count and size links
Take the sizer application (code, output) and add a message to count the number of links on a page. Follow these links and calculate their size as well, so you get the total size for each page.
The code:
The output:
This problem was a great way to experiment with actors in Scala. The sequential solution is self explanatory, so here’s an outline of the concurrent one:
- The
caller
createsB
Base Actors
, one for each of theB
base URLs. - The
caller
then callsreceive
to await a message from eachBase Actor
. - Each
Base Actor
concurrently loads its base URL, finds the links on the page, and createsL
Link Actors
, one for each of theL
links on the page. - The
Base Actor
then callsreceive
to await a message from each of itsLink Actors
. - Each
Link Actor
concurrently loads the page for its given link and sends a message to its parentBase Actor
with the size of that page. - When the
Base Actor
has received a message form each of hisLink Actors
, it sends a message to thecaller
with the total size. - When the
caller
has receivedB
messages from theBase Actors
, we are done.
The sequential code takes nearly 20 seconds to run while the concurrent code
takes less than 3 seconds, a 7x improvement. The concurrent code is definitely
more complicated, but not unreasonably so. Even though it was my first time
using Scala actors, the code took less than 30 minutes to get working, much of
it spent learning about the self keyword. In fact, I find it very easy to
reason about Scala’s actors, which is not something I can say for Java’s
synchronized
keyword, Executors
, Runnable
, and various other concurrency
constructs.
Wrapping up Scala
I’m a bit torn when it comes to Scala. Most of the time, I saw it as a vastly improved version of Java. The support for closures, functional programming, pattern matching, and actors all seem like genuinely useful tools that would dramatically improve productivity, code readability, correctness, and expressiveness. I’ve already used Scala in a few of my projects to build some features that would’ve been nearly impossible or incredibly ugly in Java.
However, even in my limited exposure to Scala, I’ve already come across a number of hiccups. As I mentioned on day 1, the API docs are not helpful and look like they are written for academics. The IDE support is vastly inferior compared to Java. I’ve now tried both Eclipse and IntelliJ, and each one has significant problems: e.g. missing compile errors on some code; finding errors on other code that’s actually valid; broken/missing auto complete; issues with the refactor/rename functionality; poor support for running scripts. The compiler is slow. The type hierarchies are complicated. Type inference doesn’t always work as well as you’d hope.
However, there is one issue that worries me above all else: feature overload. It seems like Scala is trying to be all things to all people. It’s object oriented; it’s functional; it has type inference; it has lots of syntactic sugar; it has actors; it’s compatible with Java; it has first class support for XML; they are even trying to add macros. While all of these features could lead to an incredibly powerful language, they could also lead to one that’s incredibly complicated and difficult to use.
User experience counts. Not only for products, but for programming languages too.
How many features can you pile into one language before it becomes too cumbersome? How much syntax sugar do you need to understand to be able to read or write code? How many paradigms and mental models do I need to juggle to follow along? Do so many options make a language more flexible or less? Will there be such a thing as “idiomatic Scala” or will it be a free-for-all? Is it better to have a dozen ways to do something or one “proper” and well known way?
I don’t know the answers to these questions, but I suspect they’ll have a large impact on Scala’s adoption. In the meantime, I’ll keep hacking away at it to see what I can learn.
On to Erlang
Read on to learn about the next language in the book, Erlang.
Yevgeniy Brikman
If you enjoyed this post, you may also like my books. If you need help with DevOps, reach out to me at Gruntwork.