In my use case, I allow users to pass a Map as a lookup table of cases (doh). Now, switch expression logic is in common need of handling default cases. It seems that Map.withDefault and Map.withDefaultValue should cover this in a manner transparent to my code. My problem is that I have a sort of second choice default value I want to use if the user provided Map does not have custom default handling (is not defined on the whole domain). Unfortunately, both of the former methods apply only to, nomen omen, apply, and there is no way to poll this other than extremely ugly, brittle tricks like checking map.getClass.getName. What I need is code equivalent to getOrElse or getas if the default value applied to these methods. I do not want to replace or override pre existing defaults, just to provide my own if the map does not define a default and a lookup is a miss.
It seems like I’m stuck with calling apply and catching NoSuchElementException. However, aside of the design issue that, in my case, lack of a default value is not some kind of an error and would be better of handled explicitly, throwing an exception is several orders of magnitude more expensive than get or getOrElse (actually, the expensive part is the filling of the stack trace in the exception - of which a large part is executed lazily, but JVM still needs to populate an internal field with ‘non java’ raw stack trace).
Any ideas how to handle it elegantly, with minimal increse of the interface surface? I don’t want to require my own MapPossiblyWithDefault and I’d rather avoid explicitly adding a ‘default case’ entry as an additional parameter to the Map.
withDefault & withDefaultValue are usually considered bad practices, precisely because they would get attached to the whole life of the map and no way to tell if they already have a default or no.
The best would be to just use getOrElse and allow the user to pass or not a default like this:
Matching with Map.WithDefault is ugly (I don’t even know why this type is public). Also, any decorator implementation would fail this match, not mentioning potential custom Maps.
I agree though that it would be more intuitive if applyOrElse used the default value. Probably impossible to change now due to all the existing code…