SIDEBAR
»
S
I
D
E
B
A
R
«
Scala Refactoring: Quiet-my-scope with an Implicit Parameter vs. Pimp-my-lib with an Implicit Conversion Method
May 30th, 2011 by Brian Maso

The following two code snippets are equivalent, differing only on what the client code ends up looking like, but yielding in all other ways similar results:

// --------------------
// In LibraryCode.scala...
package library.code;
 
// client code expected to import the following method and provide
// an implicit Thing value for t -- a "quiet-my-scope" patterned method.
def addedFeatureToSomeThing(implicit Thing t) = ...
 
// --------------------
// In ClientCode.scala...
import library.code._
 
// An implicit Thing value
implicit val someThing: Thing = ...
 
// Use of the someThing value as an implicit parameter to the library method
val result = addedFeatureToSomeThing

The code above can be refactored to the pimp-my-lib style which follows, and vice versa:

// --------------------
// In LibraryCode.scala
package library.code;
 
// client code expected to import the following implicit conversion method,
// which effectively adds a new method "addedFeature" to the Thing class in the importing scope.
implicit def convertThingToAddFeature(t: Thing) = new {
    def addedFeature = ...
    }
 
// --------------------
// In ClientCode.scala...
import library.code._
 
val someThing: Thing = ...
 
// Use of the pimp-my-lib-patterned convertThingToAddFeature implicit conversion method
val result = someThing.addedFeature

In both cases, the imported LibraryCode.scala provides a callable method which requires state in the form of a Thing object. I’m assuming the Thing type is also defined external to the client code — probably in a third-party library.

The first pattern, which to the best of my knowledge doesn’t have a name, you have a method in the local scope which accepts an implicit parameter, and effectively allows you to pass a single in-scope object to multiple methods without needing to repeat yourself. I’m going to dub this the “quiet-my-scope pattern“, because it reducesĀ  the visual chatter that would otherwise be caused by passing the same object to multiple method calls — and I’ll just hope that name sticks.

The second is the famous pimp-my-lib pattern, which is well-known throughout Scalaland to be used to “add” methods to externally-defined classes.

Using implicits we have these two API patterns to choose from — they are equivalent, in so far as an implementation of either one can be mechanically transformed in to the other, only style and convenience being a differentiator between them. You might find it useful to keep around this alternative to the pimp-my-lib pattern, as in some APIs it will yield more readable, more convenient code.

Try it out: the next time you find yourself augmenting an existing class with methods using the pimp-my-lib pattern, take 5 minutes to refactor your solution to methods with implicit parameters (using the sample Thing code above as a guide). You won’t lose much time in the exercise, and you may find you’ll end up with better code.

Similarly, the next time you find yourself defining a method with an implicit parameter, take 5 minutes to work through what a refactored solution with a pimp-my-lib style method would look like. You may like the result quite a bit more than what you started with.

def addedFeatureToSomeThing(implicit Thing t) = …

 


Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

»  Substance:WordPress   »  Style:Ahren Ahimsa