Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

My Journey in Scala, Part 1: Awakenings

DZone's Guide to

My Journey in Scala, Part 1: Awakenings

In the first part of his series about the journey from Javascript to Scala, covering concepts that 'plagued' him and wanting to ease the pain of others.

· Java Zone
Free Resource

Just released, a free O’Reilly book on Reactive Microsystems: The Evolution of Microservices at Scale. Brought to you in partnership with Lightbend.

When I started at Threat Stack over a year ago, I came in as a Platform Engineer expecting to work on JavaScript. I had no idea that Threat Stack would get bit by the Scala bug. But our first Scala app, created by another team member, went into production a couple of months after I joined, and I soon learned that Scala was way more than a passing fad at Threat Stack.

For me, it created an opportunity to learn a hot, in-demand, JVM-based language with a strong team and an excellent use case. But going from my life in JavaScript to my life in Scala involved a journey....

And that’s the goal of this blog post series: I’m going to chronicle my experiences learning Scala, and hopefully help anyone who is transitioning from JavaScript to Scala so they can make the trip with a little less head scratching and pain. I will introduce some of the concepts that plagued me from the onset, and explain how I thought through them.

I have really come to love Scala, even when it’s incredibly frustrating and painful, and I find it deeply rewarding to come through a difficult Scala problem with a lot more knowledge than I had at the outset.

What to Expect

Transitioning to Scala from JavaScript can be an overwhelming task. You will be going from a dynamic, anything goes language, to an immutable, functional, typed language. Some of the ways we just “get it done” in JavaScript will not work, and this can be very tough, especially if you haven’t touched a typed language in a few years. As a new Scala dev, Stack Overflow answers could leave me with more questions than I started with.

This post is based on my real-world experience, and in this series I will NOT be diving into any of the black magic of Scala. There are plenty of super smart people that know a ton about these things. (Check out this for example.) Instead, I will be focusing on the real world, which is all about getting stuff out the door that you feel good about, and bridging the gap from the super simple documentation examples to real-world applications.

The Journey Begins

My personal foray into Scala started when I needed to add an endpoint to an existing application. As always, when learning something, I looked for a good file to mimic when creating mine.

Here’s me after opening that file:

TS16031_ThreatStack_JourneyInScala_DogImage_BlogImg.jpg

I was exposed to a bunch of methods, mainly database related, which is pretty whatever. A few things stuck out, such as .toList, .apply, .flatMap — and the code style was completely different as well. There was a lot of function chaining, and it was also easily readable with no side effects and no real madness going on. I took some notes on what I saw and moved on.

Implementing My Stuff

So I wandered off on my merry way and started implementing my stuff. Renaming the database stuff was easy enough, but as always, what I need to do doesn’t match the documentation, or in this case, my example source. I think I’m doing all the things right, I have about ten methods deeply chained, but in the end I think we’re looking good. I’m noticing that Intellij has given me some red lines to work with and that I am actually returning List[List[String]], and I’m super sad because I really wanted just a List[String].

In JavaScript, I could have solved the problem easily with the code below:

var listString = [["Joe","Lucas"],["Dave","Ryan"],["Nick","Sam"]];

var newArray = [];


listString.forEach(function(interiorArray){

  interiorArray.forEach(function(string){

      newArray.push(string)

  });

});

. . . which would leave you with List[String] at the end. Pretty gross though. While this is a very simple example, whenever we modify an object outside of scope in JavaScript, we open ourselves up to some nasty side effects. In JavaScript, .push is a mutator, and we have instantly made our simple example more complex. In Scala, when we define a variable with val, it is immutable. Essentially, that means our example above won’t work and we’re screwed. We can’t just mutate a variable and keep on trucking.

Understanding this concept is critical to enjoying your time with Scala. You are being forced to think differently in a new pattern, and a lot of the convenience available in JavaScript is gone. Each method you write in Scala should be fairly tight and limited in scope. (But an excellent byproduct of this practice is easier-to-test code and much higher confidence.)

Take the following code, for example:

val foo = "foo"

val bar = "bar"


val listA = List(foo, bar)

val listB = listA.map(x => x)

This returns a new list, listB, populated with references to the objects foo and bar. While listB will point to a new object, the contents of the two lists will be identical and will share references. This immutability is a core concept with Scala. The following code does a check to make sure the object references are the same, and will print true twice:

listA.zip(listB).foreach{ case (x,y) => println(x.eq(y))}

Now back to our original issue of taking our List[List[String]] and flattening it to a List[String]. Fortunately, there are a few functions to help out here. Some we noted above. Scala actually provides a super simple answer to the problem of flattening List[List[String]] to List[String] via the .flatten() method, which will return a List[String].

So let’s prepend Hello <name> to each String in the list. In this case, we need to iterate through the items and modify them, which means .flatten will not work.

val listListString = List(List("Joe","Lucas"), List("Dave","Ryan"), List("Nick",”Sam"))

listListString.map(subList => {

    subList.map(string => s"Hello $string")

})


We’re still stuck with List[List[String]], but at least we have modified strings. We could call .flatten() on it again and reach the result we want. But fortunately, there’s a better way. One of the more epic functions in Scala is flatMap:

listListString.flatMap(subList => {

    subList.list(string => s"Hello $string")

})


This will take our modified List[List[String]] and flatten it as it maps onto a single List[String].

Another bit of fun with .map() is using one of the cooler things in Scala: _. If you’re coming from JavaScript, this is not lodash, but a placeholder. You’ll notice above in listA.map that I did a (x => x).

This can become annoying to type after about the thousandth time, so Scala allows you to do the following:

val list = List("foo", "bar")

list.map(_ == "foo")

The _ is a placeholder for x => x, which allows you to perform some operations with a bit less code, and it is somewhat cleaner to read.

Final Thoughts for Now

Well, that’s it for the first installment in my journey to learn Scala at Threat Stack. If it’s any consolation, I had to spend some real time remembering why this stuff was difficult in the first place, which was a pretty sweet feeling.

As you go on your own journey, there are plenty of resources to help you. I hope you have found this post useful. I’ll be writing new posts in the future to pass on some of the other insights I’ve gained about using Scala in the real world. (Until then, you might want to have a look at Scala @ Scale, Part 1: Leaving Unhandled Errors Behind for an example of how Threat Stack uses Scala for error handling.)

And remember: As always, the best way is to learn is to write some code for yourself!

Strategies and techniques for building scalable and resilient microservices to refactor a monolithic application step-by-step, a free O'Reilly book. Brought to you in partnership with Lightbend.

Topics:
scala ,javascript ,personal ,programming

Published at DZone with permission of Joe Baker, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}