Using `try`/`finally` without `catch`

If I need to compute something but do some side effect before returning that value, is the correct idiom try/finally without catch ?

e.g.,

  def calculateSemesterAverage() = {
    import scala.io.Source

    def csv = Source.fromFile("some-file-to-parse.csv")
    try {
      for {line <- csv.getLines()
           if some_condition(line)
           data <- some_parser(line)
           }
        yield data
    } finally {
      csv.close()
    }
  }

Yes. Actually both finally and catch blocks are optional and you can have a standalone try, but that wouldn’t make sense:

try {
  2 + 3
}

That gives compiler warning:

A try without a catch or finally is equivalent to putting its body in a block; no exceptions are handled.

Side note: Scala 2.13 has Scala Standard Library 2.13.12 - scala.util.Using which should handle above your use case.

2 Likes

In case you can’t upgrade to 2.13 you may be interested in Resource from cats-effect.

When I teach this course the next time, I intend to either upgrade to 2.13 or 3.0. Not sure which is a better idea. I’m open to suggestions.

I am not sure what IDE you use, but I realized that upgrading to 3.0 with IntelliJ-Scala is not as easy as just chaning your build scripts.

Thanks @dubaut, for the heads-up. What resource should I study before attempting such an upgrade?

I am not sure about that. I asked in IntelliJ-Scala’s Gitter, with the conclusion that the documentation - back than - was not correct and needs to be adjusted.

I did not try this myself, but what I believe needs to be done is to delete all IntelliJ-related folders and files from the project, change the Scala version in the build.sbt and open it as a new project in IntelliJ.

But again: I did not try this myself, I lost the drive to migrate to 3.0 when I realized that this is not even streight-forward if you only take the tooling into account.

I can tell you that my course and textbooks are going to go from 2.12 to 3.0. My logic certainly might not apply to you though. The changes to collections in 2.13 break a lot of my code and examples for data structures. I also know that I’ll be going to 3.0 eventually. As such, moving to 2.13 is a lot of extra work that I’ve decided to skip. I will note that there are times I wish we were on 2.13 because many of the changes to the collections are things that I would like to be able to use, but it didn’t make sense for me.

Part of your answer to this might depend on when you are teaching this again and what libraries you are using. Some libraries might take a while to move to Scala 3. I think most of the common ones are already there though. The only one I use that doesn’t seem to have a version compiling with Dotty is ScalaFX and my understanding is that this is mostly because of the removal of DelayedInit and the need to find an alternative.

Yes, I believe you are right with your assumption. Another reason why I decided not to use ScalaFX and go for plain JavaFX and writing my own API wrapper where I need it.

I could do that for my plotting library, but for the textbook or other teaching applications, the ScalaFX wrapper is much easier for students.

Another problem with ScalaFX is the fact that they do not support FXML. And where they do it is just accidently.

Personally, I would say that if it was being taught again this year, I’d probably go for 2.13, since 3.0 is still in a bit of flux. (Although it’s settling down.) Next year, I’d probably go for 3.0…

2 Likes

That winds up not being a huge issue for me either. If I were teaching a course with more of a focus on GUIs and UI I would definitely want to cover FXML. At the level I’m using ScalaFX though that is just another topic that doesn’t fit into our schedule. I can also see how that would be a big deal for anything in industry.

Honestly, we have scaled things back to the point where out ScalaFX is mainly throwing up a Canvas on a window and having the student to graphics. Projects with visual elements are very important for some students, but laying out a bunch of buttons and other GUI elements often isn’t. The pedagogical argument is also challenging given that so many of the GUIs written these days are web based.

Thanks @tarsa, I didn’t know about 2.13’s Using. Looks like it could be used with older Scala versions without any effort.

1 Like

A 2.11 and 2.12 backport of Using will be included in the next release of scala-library-compat: https://github.com/scala/scala-library-compat/pull/319

2 Likes

@SethTisue I didn’t know about that library either. Thanks for the link.

This not correct. You can use FXML with ScalaFX either directly or, even better, using ScalaFXML https://github.com/vigoo/scalafxml

There’s one caveat with this idiom: An exception from the finally clause takes precedence over an exception from try. This is generally not what you want for resource management. After a resource-related exception occurs, the close() call will usually result in a follow-on error which may not show the actual cause of the original error.

1 Like

ScalaFXML is not an option for me, since it requires a compiler plugin. I try to stay away from compiler plugins.

Hi Seth, I tried to use Using and it didn’t behave like I thought.
I was trying to replace try/finally with Using.

I was using the following.

Screenshot 2020-07-24 at 11.37.30

And I changed to the following, but looks like it doesn’t have the same semantics.

Screenshot 2020-07-24 at 11.36.39

Am I on the right track, or did I miss the point completely?