Line Filters in Scala

Here’s the translation of the Go line filter program to Scala, along with explanations in Markdown format suitable for Hugo:

A line filter is a common type of program that reads input on stdin, processes it, and then prints some derived result to stdout. grep and sed are common line filters.

Here’s an example line filter in Scala that writes a capitalized version of all input text. You can use this pattern to write your own Scala line filters.

import scala.io.StdIn
import scala.util.{Try, Success, Failure}

object LineFilter {
  def main(args: Array[String]): Unit = {
    // We use scala.io.StdIn to read from standard input
    // and process the input line by line
    Iterator.continually(Try(StdIn.readLine()))
      .takeWhile {
        case Success(line) => line != null
        case Failure(_) => false
      }
      .foreach {
        case Success(line) =>
          // Convert the line to uppercase and print it
          println(line.toUpperCase)
        case Failure(e) =>
          // If there's an error reading the input, print it to stderr
          System.err.println(s"error: ${e.getMessage}")
          System.exit(1)
      }
  }
}

This Scala program does the following:

  1. We use scala.io.StdIn to read from standard input.

  2. We create an infinite iterator with Iterator.continually that tries to read a line from stdin.

  3. We use takeWhile to continue reading until we reach the end of the input (when readLine returns null) or an error occurs.

  4. For each line, we convert it to uppercase using toUpperCase and print it.

  5. If an error occurs while reading, we print the error message to stderr and exit the program.

To try out our line filter, first make a file with a few lowercase lines.

$ echo 'hello'   > /tmp/lines
$ echo 'filter' >> /tmp/lines

Then use the line filter to get uppercase lines.

$ cat /tmp/lines | scala LineFilter.scala
HELLO
FILTER

This Scala version accomplishes the same task as the original program, reading lines from standard input, converting them to uppercase, and printing the result. It uses Scala’s functional features like Iterator and pattern matching to handle the input processing and error checking.