Scala Map.mapValues returns a (lazy) view. Hilarity ensues.

Here's a bit of a gotcha that caught me out.

TL:DR; be careful if you ever use mapValues in Scala.

I'm gonna say that mapValues is a bit of stupid name. If you have a Map and you apply mapValues, it's not totally unreasonable to assume it will apply map to the values (not least because that is exactly what it appears to do). However, it turns out that mapValues doesn't return a new Map like you might expect, it actually returns a view on the original map and applies your original transformation function whenever you access the map.

A practical example –

I had some code that calculated some numbers inside a statistical model using mapValues. The numbers are a bit expensive to calculate, so I calculate them once up front, and then reuse them later. However, because mapValues returned a view on my original map, when I looked a value up in my map later, while I thought I was just accessing a value, my code was actually recalculating the whole thing from scratch. Instead of calculating each of the the numbers once, I was calculating them each tens of thousands of times. Which explains how I managed to turn a method that ran in a couple of seconds into a method that ran for an hour.

There is a good explanation of the issue here:

And a Gist with an example code here (from which I stole the title of this post).