Posts in the “scala” category

Scala 3: An apply/factory method that takes a varargs/tuple parameter

Here’s a brief Scala 3 example that shows how to:

  1. Create a companion object,
  2. Create an apply method in that companion object that acts as a factory method,
  3. Define that apply method to take a varargs tuple parameter, and
  4. Create new Person instances using that factory method.

Here’s the complete source code for this example:

Scala tuple examples and syntax

Scala FAQ: Can you share some examples of using tuples in Scala?

A Scala tuple is a class that can contain a miscellaneous collection of elements. I like to think of them as a little bag or container you can use to hold things and pass them around.

You create a tuple with the following syntax, enclosing its elements in parentheses. Here's a tuple that contains an Int and a String:

[toc hidden:1]

How to append when writing to a text file in a Java or Scala application

As a quick Scala/Java tip, to append to a file when writing to a text file in a Scala or Java application, create your FileWriter with the append flag set to true, like this:

val bw = new BufferedWriter(new FileWriter(new File("/tmp/file.out"), true))  // <-- 'true'
bw.write("Hello, world\n")
bw.close

FileWriter takes two arguments, so that code might be easier to read when it’s formatted like this:

val bw = new BufferedWriter(
    new FileWriter(
        new File("/tmp/file.out"),
        true
    )
)
bw.write("Hello, world\n")
bw.close


Note: Appending to a text file with Scala 3

As a quick update, a great thing about Scala 3 is that you can get rid of all those new keywords, so the first part of that last example looks like this in Scala 3:

val bw = BufferedWriter(
    FileWriter(
        File("/tmp/file.out"),
        true
    )
)

Functional programming books, comparison

Since I’ve written two functional programming (FP) books, I thought it might help to provide a comparison of them.

The short story is that both FP books have “limited technical jargon,” and as shown, The Little FP Book essentially has one purpose, which is to help Java/Kotlin/OOP developers learn functional programming as fast as possible, using a technique that I “discovered” over the last few years. Conversely, The Big FP Book covers many topics in great detail.

If you’re interested in more details, here are links to the two books:

Scala “split string” examples (field separator, delimiter)

Scala String FAQ: How do I split a String in Scala based on a field separator, such as a String I get from a comma-separated value (CSV) file or pipe-delimited file.

Solution

Use one of the split methods that are available on Scala/Java String objects. For instance, this example in the Scala REPL shows how to split a string based on a blank space:

How to iterate over Scala Lists with foreach and for

Scala List/sequence FAQ: How do I iterate over a Scala List (or more generally, a Scala sequence) using the foreach method or for loop?

There are a number of ways to iterate over a Scala List using the foreach method — which is available to Scala sequences like List, Array, ArrayBuffer, Vector, Seq, etc. — and the for comprehension, and I'll show a few of those approaches here.

Scala: A “sum of the squares” algorithm using map/sum and foldLeft

As a quick Scala fold/reduce example, I just needed to write a “sum of the squares” algorithm for a “Pearson Correlation” function I’m working on, and initially wrote it like this using map and sum:

val sumOfTheSquares = movieRatingsMap.values
                                     .map(rating => Math.pow(rating, 2))
                                     .sum

If you know Scala, and know that movieRatingsMap is a Map of movies and my ratings of those movies, I think that line of code is fairly easy to read. That line can also be written like this:

Scala: How to define a generic method parameter that must extend a base type (bounds)

In today’s installation of “how to have fun with Scala,” if you want to (a) define a Scala method that takes an input parameter, and (b) that parameter has a generic type, and (c) you further want to further declare that the parameter must extend some base type, then (d) use this “bounds” syntax:

def getName[A <: RequiredBaseType](a: A) = ???

This example can be read as, “The parameter a has the generic type A, and A must be a subtype of RequiredBaseType.”

A complete Scala bounds example

As a concrete example of how using bounds works, start with a simple base type, such as this Scala trait:

trait SentientBeing {
    def name: String
}

Next, extend that base trait with a few more traits:

trait AnimalWithLegs extends SentientBeing
trait TwoLeggedAnimal extends AnimalWithLegs
trait FourLeggedAnimal extends AnimalWithLegs

Then extend those with some concrete case classes:

case class Dog(name: String) extends FourLeggedAnimal
case class Person(name: String, age: Int) extends TwoLeggedAnimal
case class Snake(name: String) extends SentientBeing

Notice that Snake extends SentientBeing, but not AnimalWithLegs.

Now that you have all the types you need, define a method that takes a parameter that has a generic type that must extend some base type. To see how everything works, define it this way the first time:

def getName[A <: SentientBeing](a: A): String = a.name

Because the base type (or “super type”) is SentientBeing, all of these calls work just fine:

getName(Person("Fred", 20))
getName(Dog("Rover"))
getName(Snake("Noodles"))

(Copy and paste those into the Scala REPL if you want to verify they work as advertised.)

Now extend AnimalWithLegs

Next, change getName so the generic type A must be a subtype of AnimalWithLegs:

def getName[A <: AnimalWithLegs](a: A): String = a.name

Now, when you run the same three method calls again, you’ll see that the Snake example fails because it doesn’t extend AnimalWithLegs:

getName(Person("Fred", 20))
getName(Dog("Rover"))
getName(Snake("Noodles"))   //error

Here’s what the two sets of getName examples look like in the Scala REPL:

Show a Scala method with generic type parameter

(Right-click that image and select “View image” to see it larger.)

The Scala “type parameter bounds” error

As shown, the second Snake example results in this error message:

scala> getName(Snake("Noodles"))
<console>:15: error: inferred type arguments [Snake] do not conform to method getName's 
type parameter bounds [A <: AnimalWithLegs]
       getName(Snake("Noodles"))
       ^
<console>:15: error: type mismatch;
 found   : Snake
 required: A
       getName(Snake("Noodles"))
                    ^

This is because the type Snake does not extend AnimalWithLegs. (At least not in my world.)

Technical matters: ‘A’ has an “upper bound”

Technically what’s happening here is that I’m defining A with an “upper bound.” Bounds let you place restrictions on type parameters, and in this example I’m saying, “A must be a subtype of the type AnimalWithLegs”:

def getName[A <: AnimalWithLegs](a: A): String = a.name

More generally, this is how you say, “A must be a subtype of B”:

A <: B

I write more about this topic in, An introduction to Scala Types, so please see that article for a few more details.

How to read “difficult” Scala method type signatures

When I first saw Scala generic type and multiple-parameter group code like this ~12 years ago, my initial thought was, “Wow, maybe I need to think about a different career”:

def race[A, B](lh: IO[A], rh: IO[B])(implicit cs: ContextShift[IO]): IO[Either[A, B]]

But in the end, as Rocky once said, it ain’t so bad. :)

Rocky: You ain’t so bad

Scala 3, Scala CLI, JDBC, and SQL (examples)

As a brief “note to self” today, here are two examples of how to perform SQL queries with Scala 3, using (a) plain JDBC, and also (b) using a little Scala 3 library known as SimpleSQL. These examples use Scala CLI, which as I have mentioned before, makes these examples so much easier to share with you.

Scala: How to execute (exec) external system commands

Scala exec FAQ: How do I execute external system commands in Scala?

When it comes to executing external system commands, Scala is a dramatic improvement over Java. The operators Scala makes available are much more like Perl or Ruby, and the operators themselves are consistent with traditional shell commands, and are therefore easy to remember. Let's take a look at a few examples.