Posts in the “scala” category

Scala objects are final (singleton objects)

As a quick note, objects created with object are final by default in Scala. I don’t think this is shown in Scala 2, but it’s made clear in the Scala 3 REPL:

scala> final object Foo
1 |final object Foo
  |^^^^^
  |final modifier is redundant for objects
// defined object Foo

Because the object keyword in Scala creates a singleton object, attempting to mark it as final is redundant. Putting this another way, as described in the Scala Tour, an object defines a class that has exactly one instance.

A simple Scala call-by-name example

Here’s a simple Scala call-by-name example. I’ll show the normal approach to writing a method and passing in a parameter, and then show a call-by-name (pass by name) example.

1) A “normal” Scala method (call-by-value)

Here I show how to pass a parameter to a method “normally,” i.e., call by value:

On curly braces and thunks in Scala

Today I spent some time going down the road of “What is a thunk in Scala?” Here’s some relevant text from this Wikipedia page. Note that I have deleted some lines, and modified others:

In computer programming, a thunk is a subroutine used to inject an additional calculation into another subroutine. Thunks are primarily used to delay a calculation until its result is needed, or to insert operations at the beginning or end of the other subroutine.

The term originated as a humorous, incorrect, past participle of “think.” That is, a “thunk value” becomes available after its calculation routine is thought through, or executed.

An anonymous class example in Scala

Sometimes I get away from writing Scala for a while, and when I come back to it I see a piece of code that looks like this following example and I wonder, “What is Foo, and how does this code work?”:

val f1 = Foo {
    println("hello from the `f1` instance")
    "this is the result of the block of code"
}

Well, one way it can work is that Foo can be a class that accepts a function parameter, and so everything inside those curly braces is the argument to Foo. For example, this code shows how a Foo class can be defined to accept a function as a constructor parameter:

case class Foo[A, B](f: A => B) {
    // more code here ...
}

That code says that Foo is a Scala case class that takes one constructor parameter, which is a function that transforms a generic type A into a resulting generic type B.

Going back to the first code I showed, everything inside the curly braces is that first argument to Foo:

Scala anonymous class example - passing a block of code

Informally speaking, everything inside a set of curly braces in Scala can be thought of as “a block of code,” and typically that block of code has some return value, such as "hello" in this example.

Scala 3 error: “Class differs only in case” (case-insensitive filesystems)

I was surprised to see this Scala 3 compiler error just now:

Class differs only in case ... Such classes will
overwrite one another on case-insensitive filesystems

What happened was that I created this code:

trait Hello:
    def greet = "hello"
trait Hi:
    def greet = "hi"

class Greeter extends Hello, Hi:
    override def greet = "I greet thee!"
    
@main def greeter =
    val g = Greeter()
    println(g.greet == "I greet thee!")   // true

And apparently the Greeter class and greeter method collide with one another to create this compiler error message:

[error] -- Error: src/main/scala/traits/mixin_order/MixinOrder.scala:18:10 
[error] 18 |    class Greeter extends Hello, Hi:
[error]    |          ^
[error]    |     |class Greeter differs only in case from
                 |class greeter in package mixins.test1.
Such classes will overwrite one another on case-insensitive filesystems.
[error] one error found

I don’t know if this error will continue to stay like this in Scala 3, but that’s the way it works today.

Definition of a “fold” in programming

I was just updating my Scala fold/reduce tutorial, and noticed that I start with this definition of a fold in computer programming from the excellent book, Learn You a Haskell for Great Good:

Folds can be used to implement any function where you traverse a list once, element by element, and then return something based on that. Whenever you want to traverse a list to return something, chances are you want a fold. That’s why folds are, along with maps and filters, one of the most useful types of functions in functional programming.”

That’s a great definition because it includes (almost) everything, so I’ll add this:

  • You traverse an entire list, once
  • Element by element
  • You apply your own custom algorithm to the elements as you traverse the list
  • In the end, you return a single value based off of that traversal and the application of your algorithm

If you’re interested in the definition of a fold in computer programming, I hope that’s helpful. See my fold/reduce tutorial for many more details.

Looking into writing a Scala 3 testing framework

As a brief note to self, I started looking into writing my own Scala testing framework, mostly because the main current frameworks are not currently available for Scala 3.0-M3. That led me to this Minitest blog post, the Minitest repository, and finally this sbt test-interface repository. It looks like if you want to write your own testing framework to work with sbt, that interface is what you need to implement.

I just tested Minitest with Scala 3, and it seems to work, so for now I’m not going any further. But I was happy to find that interface project, because I have often wondered what it would take to write a testing framework to work with sbt.

The Scala 3 scalac -source 3.1 option

If you ever need to use the Scala 3 -source option with scalac or the SBT build.sbt file, the correct syntax is:

-source:3.1

It’s not clear from the scalac help text how the -source option should be used, and I just figured that out in my build.sbt file, which has these scalac options:

scalacOptions ++= Seq(
  "-deprecation",         // emit warning and location for usages of deprecated APIs
  "-explain",             // explain errors in more detail
  "-explain-types",       // explain type errors in more detail
  "-feature",             // emit warning and location for usages of features that should be imported explicitly
  "-indent",              // allow significant indentation.
  "-new-syntax",          // require `then` and `do` in control expressions.
  "-print-lines",         // show source code line numbers.
  "-unchecked",           // enable additional warnings where generated code depends on assumptions
  "-Ykind-projector",     // allow `*` as wildcard to be compatible with kind projector
  "-Xfatal-warnings",     // fail the compilation if there are any warnings
  "-Xmigration",          // warn about constructs whose behavior may have changed since version
  "-source:3.1"
)

A story about editing Functional Programming, Simplified

Once upon a pre-pandemic day, I was sitting in the waiting area of a doctor’s office, writing notes all over my functional programming book as I edited it. Another patient came over and asked if the book was any good.

I was kind of immersed in what I was doing, so without looking up I said, “I hope so.” Then I looked up and started to add more, but just then he got called in before I could say any more. :)

Scala 3 `@main` will have more functionality

On this Contributors thread I just saw this comment by Martin Odersky that I didn’t notice before: “For the moment Scala-3’s @main only covers a small subset of what Mainargs can do. But the plan is to extend that.”

This comment came after Li Haoyi shared an example of his MainArgs library, and it seems like the implication is that the @main annotation in Scala 3 may eventually be able to handle command-line arguments.

A Scala “timer” shell script (plays a sound file after x minutes)

This short article shows how to write a command-line timer in Scala. There are simple ways to do this as just a regular Unix/Linux shell script, but I wanted to use Scala, in part so I could try to remember how to use the Java sound libraries. (I also initially thought about writing this is a GUI app, but decided to just make it a command-line app.)

I wanted a simple command-line timer, so I wrote one in Scala.

How to write infix methods with extension methods in Scala 3

Here’s an example of how to use the Scala 3 @infix annotation to create an infix method, while using the technique with extension methods at the same time:

import scala.annotation.infix

extension (i: Int)
   @infix def plus(j: Int) = i + j
   @infix def times(j: Int) = i + j

That code adds the extension methods plus and times to the Scala Int class, while also letting them be used as infix methods. The REPL shows the result:

scala> 1 plus 1
val res0: Int = 2

scala> 2 times 2
val res1: Int = 4

In summary, if you wanted to see how to write infix methods and extension methods with Scala 3, I hope this example is helpful

Scala: How to download and process XML data (such as an RSS feed)

I was looking for a good way to access XML resources (like RSS feeds) in Scala, and I currently like the idea of using ScalaJ-HTTP to access the URL and download the XML content, and then using the Scala XML library to process the XML string I download from the URL.

This example Scala program shows my current approach:

import scalaj.http.{Http, HttpResponse}
import scala.xml.XML

object GetXml extends App
{
    // get the xml content using scalaj-http
    val response: HttpResponse[String] = Http("http://www.chicagotribune.com/sports/rss2.0.xml")
                                        .timeout(connTimeoutMs = 2000, readTimeoutMs = 5000)
                                        .asString
    val xmlString = response.body

    // convert the `String` to a `scala.xml.Elem`
    val xml = XML.loadString(xmlString)

    // handle the xml as desired ...
    val titleNodes = (xml \\ "item" \ "title")
    val headlines = for {
        t <- titleNodes
    } yield t.text
    headlines.foreach(println)

}

A few notes about this application:

  • I like using ScalaJ-HTTP to download the content as an HTTP GET request, in part because I like to be able to easily set timeout values on the GET request.
  • Once I get the XML from the URL, it’s easy to convert that to a Scala XML object using XML.loadString.
  • Once I have the XML like that, I can then process it however I want to.

The build.sbt file

If you want to test this on your own computer, the only other thing you need (besides having Scala and SBT installed) is a build.sbt file to go along with it. Here’s mine:

name := "ScalajHttpXml"

version := "1.0"

scalaVersion := "2.11.7"

resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"

libraryDependencies ++= Seq(
    "org.scalaj" %% "scalaj-http" % "2.3.0",
    "org.scala-lang.modules" %% "scala-xml" % "1.0.3"
)

scalacOptions += "-deprecation"

Once you have that Scala source code and build.sbt file, you can test this Scala/HTTP/XML solution on your system. (Note that the Scala XML project is now separate from the base Scala libraries.)

How to load an XML URL in Scala (contents of an XML web page)

Scala XML FAQ: How do I load an XML URL in Scala? (How do I read/download the contents of an XML URL in Scala?)

To load the contents of an XML URL (web page) in Scala, such as an RSS news feed or RESTful web service, just use the load method of the Scala XML class:

val xml = XML.load("http://www.devdaily.com/rss.xml")

Here's an example of what this looks like in the Scala REPL:

Scala: How to append varargs parameters to an ArrayBuffer

As a brief note, if you need to use a varargs parameter with a Scala method, and those varargs parameters should be added to an ArrayBuffer, I can confirm that this code works with Scala 2.13:

import scala.collection.mutable.ArrayBuffer
val xs = ArrayBuffer[String]()

// add one element to the ArrayBuffer
xs += "a"   // ArrayBuffer(a)

// now create a method with a varargs parameter
def appendStrings(strings: ArrayBuffer[String], varargsStrings: String*): Unit = 
    xs.appendAll(varargsStrings)

// now add multiple varargs parameters to the ArrayBuffer
appendStrings(xs, "b", "c")
xs   // ArrayBuffer(a, b, c)

I just confirmed that this code works with Scala 2.13 and Scala 3.0.0