Posts in the “scala” category

Scala: How to read input from one file while writing output to another file

Without much introduction or discussion, here’s a Scala example that shows how to read from one text file while simultaneously writing the uppercase version of the text to a second output file:

import java.io.{BufferedWriter, File, FileWriter}
import utils.IOUtils.using

object SemiStreaming extends App {

    val inFile  = "/Users/al/tmp/in.dat"
    val outFile = "/Users/al/tmp/out.dat"

    // caution: this throws a FileNotFoundException if inFile doesn't exist
    using(io.Source.fromFile(inFile)) { inputFile =>
        using(new BufferedWriter(new FileWriter(new File(outFile), true))) { outputFile =>
            for (line <- inputFile.getLines) {
                outputFile.write(line.toUpperCase + "\n")
            }
        }
    }

}

This example uses the using construct, which I’ve discussed in other Scala file-reading tutorials on this website.

An example Scala ‘App’ for the Cats “IO Monad” article

As a quick note, if you’re interested in using the IO monad described in this IO Monad for Cats article, here’s the source code for a complete Scala App based on that article:

import cats.effect.IO

object Program extends App {

    val program = for {
        _    <- IO { println("Welcome to Scala!  What's your name?") }
        name <- IO { scala.io.StdIn.readLine }
        _    <- IO { println(s"Well hello, $name!") }
    } yield ()

    program.unsafeRunSync() 
}

And here’s a build.sbt file you can use to run that App with SBT:

name := "CatsIOMonadExample"

version := "0.1"

scalaVersion := "2.12.2"

libraryDependencies ++= Seq(
    "org.typelevel" %% "cats" % "0.9.0",
    "org.typelevel" %% "cats-effect" % "0.3"
)

Running the App looks like this:

> run
[info] Compiling 1 Scala source ...
[info] Running Program 
Welcome to Scala!  What's your name?
Fred
Well hello, Fred!

See that article for more information. I just wanted to show a complete example, including the necessary SBT dependencies.

August, 2019 update: The Cats dependencies are now:

libraryDependencies ++= Seq(
   "org.typelevel" %% "cats-core" % "2.0.0-RC1",
   "org.typelevel" %% "cats-effect" % "1.3.1"
)

Scala style: Side-effect methods with no parameters should be declared with parentheses

As a note about Scala style, this Scala page strongly encourages that side-effect methods that takes no parameters should be declared with parentheses:

“However, this syntax (leaving off parentheses) should only be used when the method in question has no side-effects (purely-functional). In other words, it would be acceptable to omit parentheses when calling queue.size, but not when calling println() (or openGarageDoor()). This convention mirrors the method declaration convention given above.”

“Religiously observing this convention will dramatically improve code readability and will make it much easier to understand at a glance the most basic operation of any given method. Resist the urge to omit parentheses simply to save two characters!”

Hello, Scala (free preview)

Note: The print version of Hello, Scala on Amazon will be going up to $20 (USD) this Saturday, April 13, 2019. It’s currently just $10, so you know, buy it while it’s on sale and all that. :)

If you like free things, here’s a link to a free preview (PDF) of the new version of my book, “Hello, Scala.” The book is 257 pages long, and the free preview contains the first 120 pages of it, so I hope it’s a significant preview.

July, 2019 Update: Hello, Scala was previously available in PDF and Kindle versions, but hopefully there are some big changes coming, so those versions are no longer for sale.

How to use JavaPlot from the Scala REPL

If you want to use the JavaPlot library from the Scala REPL, it’s pretty easy to get started with. Just download and unpack the JavaPlot distribution and then find the JavaPlot.jar file in the dist directory of the package. Copy that jar file to the current directory, and then start a Scala REPL session like this:

Fixing the Scala error: java.lang.NoSuchMethodError: scala.Product.$init$

As a note to self, when you see a Scala error message that looks like this:

java.lang.NoSuchMethodError: scala.Product.$init$(Lscala/Product;)V

it probably means that you have a mismatch in the Scala versions you’re using in your project. For instance, I just tried to use a library I compiled with Scala 2.12 with Spark, which was compiled with Scala 2.11, and I got that error message. In this case I was able to resolve the problem by recompiling my library with Scala 2.11.

Simplify, simplify, simplify (programming Scala methods)

I saw a Scala method recently that was written like this:

def abs (i: Int): Int = {
    if (i < 0) -i
    else i
}

There’s nothing wrong with this method, especially if you’re new to Scala. The method does one thing, and it’s very readable. However, it’s important to know that you can do a number of things to simplify the method, and by the time you’re done with the simplifications it will be easier to read.

A Scala `for` loop as a method body

I don’t remember where I saw this code, but I took a photo of it a while back, and it shows a for loop as a Scala method body. I don’t think I’ve ever written anything like that before, so it impressed me enough that I took a picture of it.

Making your Scala code more concise (and your intent more clear)

I was trying to write some code last night while I was very tired, and while the code itself isn't difficult in any way, the thought process I went through demonstrates how your code can become more concise as your understanding of Scala evolves, so I thought I'd share the experience here.

While working on my Sarah application, I was rewriting the Brain class, and I started off writing a method that looked like this: