Functional Programming Strategies

Subscribe
Archives
August 1, 2023

Scala developers don't give an F[_]!

Hello!

It's been a bit longer than the scheduled two weeks between emails. Since I last emailed you, I've had COVID (not recommended) and some family came to visit (recommended). Back to normal (mostly; it's school holidays) now.

My previous emails have intentionally been quite terse. In this email I'm going to break the pattern and experiment with longer content. Let me know what you think of this experiment. If you just want to know about the book(s) read the paragraph immediately below.

Book Updates

  • I've completed Part One (11 chapters) of Creative Scala

  • I made a small amount of progress on the algebraic data types chapter in Scala with Cats

Last update I said I wanted to focus on the algebraic data types chapter in Scala with Cats, but I was getting distracted by all the almost complete material in Creative Scala. I decided to finish off that material so I could stop thinking about it.

Scala Days Madrid

As you may know, Scala Days Madrid is coming up in a bit over a month. I am really looking forward to seeing people in-person for the first time in about 3 years. If you want to attend, and don't yet have a ticket, you can use the code NOEL-15 for a 15% discount.

Like the sucker I am, I've agreed to do a few things at Scala Days in addition to my talk: running a ScalaBridge event on the first day, and speaking on a panel on the last day.

The ScalaBridge event should be a good opportunity to test some of the material that's being created for Creative Scala / ScalaBridge London. (SB London uses Creative Scala.) Based on the signups so far, the students will have quite a range of Scala knowledge. I'm planning to develop 2-4 worksheets that cover projects of different difficulty.

The simplest project will be the Spirograph project in Creative Scala. This will be quick to write as I just need to point students to the existing material.

For the hardest project, I'm thinking of building a simple interpreter for a Scala-like language. What I know so far:

  • The language should be called Stoop, which is a small set of stairs (get it?)
  • I'll probably want to provide a parser. Building a parser is time consuming and isn't so important for the main goals of the project. I'll probably use Parsley for this.
  • A tree walking interpreter is probably all that would be achievable in a single day. However it would be very cool to implement a bytecode interpreter and visualize the interpreter using an LED matrix like this one.

If you know anyone who may be interested in ScalaBridge (either Madrid or London) please let them know! It's very easy for us to reach potential mentors for these events, but much harder to reach potential students.

API Design: Don't Give A F[_]!

My talk at Scala Days will be about API design, using a library I'm working on as an example. This material will probably end up in Scala with Cats (which is increasingly feeling like it should have a different name, or perhaps be an entirely different book.)

Here I want to talk about something that doesn't really fit in the context of the talk, which I call "tagless final theatre".

It's fairly common to see Scala projects written in a tagless final style. Now, I'm a big fan of tagless final and I use it a lot in my projects. I have good reason to do so: a lot of my projects are addressing the expression problem and need the extensibility that tagless final provides. However, usually when I see it in industry it's in the context of web services which don't have this requirement. It's very common to see code like

trait SomeCoolWebService[F[_]: Sync] {
  def myAwesomeWebServiceMethod: F[Unit] = ???
}

which is immediately followed by

trait SomeCoolWebServiceImpl extends SomeCoolWebService[IO]

My issue here is abstracting over the effect type F. The reasons given are usually something like it allows easier testing or it makes it clear what the dependencies of the service are.

In practice I don't find that either really works out. As soon as F is constrained with a context bound (the Sync in my example) it basically becomes impossible to test without using IO directly. As for listing dependencies, I just don't find this valuable in the context of a typical microservice that is a few thousand lines of code. It's easy enough to read all the code and see what is being used.

There are two big downsides of this code. Firstly, it's hard to onboard new developers who have to learn a whole bunch of new concepts to be productive. Secondly, it's just easier to develop when working with concrete types. The type errors are simpler, you don't have to ship implicit given values all around the code base, and you don't have to worry about getting the imports correct for all the implicit class extension methods you need to use abstract effect types.

I think a lot of teams use this style because they think it's the right thing to do (it's definitely pushed in certain parts of the Scala community) but don't actually assess whether it brings them any value in their context. Now let me be clear: I absolutely do believe that abstracting over effects has benefits in some contexts. If you're writing a library, particularly an open source library that will be used by many diverse teams, abstracting over effects can be the right thing to do. However, in the context of code that used only within a company with a fairly tightly controlled stack, that is application level and so will not be abstracted over, and is fairly small in scope, I just don't see the benefit. What I do see is teams making their lives significantly harder in service of an abstract principle that doesn't help them in any way

So that's my advice to Scala developers: stop with the tagless final theatre and don't give a F[_], unless you know you'll benefit from this additional abstraction.

That's all for this newsletter. Let me know if you enjoyed the longer edition.

Regards,
Noel

Don't miss what's next. Subscribe to Functional Programming Strategies:
Powered by Buttondown, the easiest way to start and grow your newsletter.