{"id":1384,"date":"2018-04-19T18:20:18","date_gmt":"2018-04-19T16:20:18","guid":{"rendered":"https:\/\/andr83.io\/?p=1384"},"modified":"2020-01-04T01:22:53","modified_gmt":"2020-01-03T23:22:53","slug":"understanding-implicit-in-scala","status":"publish","type":"post","link":"https:\/\/andr83.io\/en\/1384\/","title":{"rendered":"Understanding implicit in Scala"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\">4<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span>\n<p>During last year I have had several conversations with my friends from Java world about their experience in Scala. Most of them tried to use Scala as better Java of course and after back with reason &#8211; Scala is too powerful and there are many ways to do one thing. The main concern was (surprised \ud83d\ude09 ) about implicit. I agree that implicit is an ambiguous feature of Scala and in the wrong hands, it can be a reason for awful application design and a lot of errors. I think everyone in Scala faced with compilation problems related to implicit resolution and the first time it could be like crashing into the wall &#8211; what to do? where to look? how to solve this error? It can make you google issue or even read the documentation! Usually, it solved by adding some imports and we forget about the problem. But why we had to add additional imports? What was the real reason for the issue? In this post, I would like to explain more about implicit usage practices in Scala and I hope they will cease to be scary and confusing.<\/p>\n\n\n\n<p>The most common way implicit used are:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Implicit parameters<\/li><li>Implicit conversions<\/li><li>Implicit classes (&#8220;Pimp My Library&#8221; pattern)<\/li><li>Type classes<\/li><\/ul>\n\n\n\n<p>There are a lot of articles and documentation about this topic but not a lot of examples how to use it in the real world. In this post, I want to show how is possible to create Scala-friendly API for a beautiful Java library <del>Typesafe<\/del> <a href=\"https:\/\/github.com\/lightbend\/config\" target=\"_blank\" rel=\"noopener noreferrer\">Lightbend Config<\/a>. At first, we must respond to the question &#8211; what is wrong with native Java API? Let&#8217;s take a look at the example from the documentation:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-scala\">import com.typesafe.config.ConfigFactory\n\nval conf = ConfigFactory.load();\nval foo = config.getString(&quot;simple-lib.foo&quot;)\nval bar = config.getInt(&quot;simple-lib.bar&quot;)<\/code><\/pre>\n\n\n\n<p>I see here 2 problems:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Error handling. For example, if the method <code>getInt<\/code> could not return value of proper type it will throw an exception. But we want to write clear code without exceptions.<\/li><li>Extensibility. This API has support for some default Java types but what if we would like to add more? For example, <code>LocalDate<\/code> or Scala native types.<\/li><\/ol>\n\n\n\n<p>Let&#8217;s start with the second problem. The Java way to solve it &#8211; inheritance. We can extend a base class with new functionality and add required methods. It can work if you are the owner of the code otherwise usually it&#8217;s problematic. Here we can remember we write on Scala and try to use <a href=\"https:\/\/www.artima.com\/weblogs\/viewpost.jsp?thread=179766\" target=\"_blank\" rel=\"noopener noreferrer\">&#8220;Pimp My Library&#8221;<\/a> pattern:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-scala\">implicit class RichConfig(val config: Config) extends AnyVal {\n  def getLocalDate(path: String): LocalDate = LocalDate.parse(config.getString(path), DateTimeFormatter.ISO_DATE)\n}<\/code><\/pre>\n\n\n\n<p>And after we can use as it was defined in original code:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-scala\">val date = config.getLocalDate(&quot;some-string-date&quot;)<\/code><\/pre>\n\n\n\n<p>Not bad. But we still need to keep all extensions in one <code>RichConfig<\/code> or have potential &#8220;Ambiguous implicit values&#8221; error if the same functionality will define in separate implicit classes. &#8220;Pimp My Library&#8221; is great and power pattern but must be used neatly and in place.<\/p>\n\n\n\n<p>Can we do better? Initially let&#8217;s remember that inheritance in Java usually used as a way to implement polymorphism. It&#8217;s so-called subtype polymorphism. But there are other types of polymorphism. Wikipedia says at least about:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Subtyping<\/li><li>Parametric polymorphism<\/li><li>Ad-hoc polymorphism<\/li><\/ol>\n\n\n\n<p>One interesting for us is the ad-hoc polymorphism.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-style-default is-layout-flow wp-block-quote-is-layout-flow\"><p style=\"text-align: left;\">In programming languages, ad-hoc polymorphism is a kind of polymorphism in which polymorphic functions can be applied to arguments of different types, because a polymorphic function can denote a number of distinct and potentially heterogeneous implementations depending on the type of argument(s) to which it is applied. It is also known as function overloading or operator overloading. The term ad hoc in this context is not intended to be pejorative; it refers simply to the fact that this type of polymorphism is not a fundamental feature of the type system.<\/p><p style=\"text-align: right;\"><a href=\"https:\/\/en.wikipedia.org\/wiki\/Ad_hoc_polymorphism\">Wikipedia<\/a><\/p><\/blockquote>\n\n\n\n<p>In Scala ad-hoc polymorphism can be implemented with <strong>type class<\/strong> pattern. It came from Haskel where type classes are part of the language. Simply it&#8217;s a generic <code>Foo[T]<\/code> parametrised by some type <code>T<\/code> and this type used in implicit resolution to get a required implementation of <code>Foo[T]<\/code>. Maybe sounds complex but it&#8217;s simple and fun.<\/p>\n\n\n\n<p>For example, we can define generic config reader as:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-scala\">trait Reader[A] {\n  def read(config: Config, path: String): Either[Throwable, A]\n}<\/code><\/pre>\n\n\n\n<p><code>Either<\/code> here to solve the first problem &#8211; error handling. No more exceptions! We can define a type alias for our result type and add few implementations.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-scala\">trait Reader[A] {\n  def read(config: Config, path: String): Reader.Result[A]\n}\n\nobject Reader {\n  type Result[A] = Either[Throwable, A]\n\n  def apply[A](read: (Config, String) =&gt; A): Reader[A] = new Reader[A] {\n    def read[A](config: Config, path: String): Result[A] = Try(read(config, path)).toEither\n  }\n\n  implicit val intReader = Reader[Int]((config: Config, path: String) =&gt; config.getInt(path))\n  implicit val stringReader = Reader[String]((config: Config, path: String) =&gt; config.getString(path))\n  implicit val localDateReader = Reader[LocalDate]((config: Config, path: String) =&gt; LocalDate.parse(config.getString(path), DateTimeFormatter.ISO_DATE);)\n}<\/code><\/pre>\n\n\n\n<p>So we have created type class <code>Reader<\/code> with implementations for <code>Int<\/code>, <code>String<\/code> and <code>LocalDate<\/code> types. Now we need to make config to work with our <code>Reader<\/code>. And here is a good way to use implicit classes to extend the syntax of original <code>Config<\/code> class and implicit parameter to pass <code>Reader<\/code> instance of a required type:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">implicit class ConfigSyntax(config: Config) extends AnyVal {\n  def as[A](path: String)(implicit reader: Reader[A]): Reader.Result[A] = reader.read(config, path)\n}<\/code><\/pre>\n\n\n\n<p>We can even rewrite it to cleaner form using <strong>context bounds<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">implicit class ConfigSyntax(config: Config) extends AnyVal {\n  def as[A : Reader](path: String): Reader.Result[A] = implicitly[Reader[A]].read(config, path)\n}<\/code><\/pre>\n\n\n\n<p>And usage example:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-scala\">val foo = config.as[String](&quot;simple-lib.foo&quot;)\nval bar = config.as[Int](&quot;simple-lib.bar&quot;)<\/code><\/pre>\n\n\n\n<p>Type classes are a power tool to extend functionality without changing existing code. It gives much more freedom and flexibility comparing with subtyping. If you need add support for new type &#8211; just implement required type class instance and put in the scope. Also, it&#8217;s simple to override default implementation using implicit resolution <a href=\"https:\/\/www.scala-lang.org\/files\/archive\/spec\/2.12\/06-expressions.html#overloading-resolution\" target=\"_blank\" rel=\"noopener noreferrer\">order<\/a>. For example, we can define our custom <code>LocalDate<\/code> reader and it will be used instead of default one:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-scala\">implicit val localDateReader2 = Reader[LocalDate]((config: Config, path: String) =&gt;\n  Instant\n    .ofEpochMilli(config.getLong(path))\n    .atZone(ZoneId.systemDefault())\n    .toLocalDate()\n)<\/code><\/pre>\n\n\n\n<p>As we can see implicit when used properly can help a lot to write clean and extensible code. Implicit can help you extend third-party libraries without code modification and write cleaner code with implicit parameters. They are fine if you write generic code and want to use ad-hoc polymorphism with type classes. You should not worry about complex class hierarchy just split your code into functional parts and implement it separately. \u00abDivide and rule\u00bb in action.<\/p>\n\n\n\n<p>Github <a href=\"https:\/\/github.com\/andr83\/scalaconfig\" target=\"_blank\" rel=\"noopener noreferrer\">link<\/a> to scala-config project.<\/p>\n<div class=\"likebtn_container\" style=\"\"><!-- LikeBtn.com BEGIN --><span class=\"likebtn-wrapper\"  data-identifier=\"post_1384\"  data-site_id=\"5a427b726fd08b4346b93df5\"  data-theme=\"youtube\"  data-lang=\"ru\"  data-show_like_label=\"false\"  data-dislike_enabled=\"false\"  data-share_enabled=\"false\"  data-counter_type=\"subtract_dislikes\"  data-voting_enabled=\"false\"  data-voting_cancelable=\"false\"  data-tooltip_enabled=\"false\"  data-style=\"\"  data-unlike_allowed=\"\"  data-show_copyright=\"\"  data-item_url=\"https:\/\/andr83.io\/en\/1384\/\"  data-item_title=\"Understanding implicit in Scala\"  data-item_image=\"https:\/\/andr83.io\/wp-content\/uploads\/2018\/04\/magic_hat-950x458.png\"  data-item_date=\"2018-04-19T18:20:18+03:00\"  data-engine=\"WordPress\"  data-plugin_v=\"2.6.54\"  data-prx=\"https:\/\/andr83.io\/wp-admin\/admin-ajax.php?action=likebtn_prx\"  data-event_handler=\"likebtn_eh\" ><\/span><!-- LikeBtn.com END --><\/div>","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\">4<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span> During last year I have had several conversations with my friends from Java world about their experience in Scala. Most of them tried to use Scala as better Java of course and after returned back with reason &#8211; Scala is too powerful and there are a lot of ways to do one thing. The main concern was about implicit. <\/p>\n<div class=\"likebtn_container\" style=\"\"><!-- LikeBtn.com BEGIN --><span class=\"likebtn-wrapper\"  data-identifier=\"post_1384\"  data-site_id=\"5a427b726fd08b4346b93df5\"  data-theme=\"youtube\"  data-lang=\"ru\"  data-show_like_label=\"false\"  data-dislike_enabled=\"false\"  data-share_enabled=\"false\"  data-counter_type=\"subtract_dislikes\"  data-voting_enabled=\"false\"  data-voting_cancelable=\"false\"  data-tooltip_enabled=\"false\"  data-style=\"\"  data-unlike_allowed=\"\"  data-show_copyright=\"\"  data-item_url=\"https:\/\/andr83.io\/en\/1384\/\"  data-item_title=\"Understanding implicit in Scala\"  data-item_image=\"https:\/\/andr83.io\/wp-content\/uploads\/2018\/04\/magic_hat-950x458.png\"  data-item_date=\"2018-04-19T18:20:18+03:00\"  data-engine=\"WordPress\"  data-plugin_v=\"2.6.54\"  data-prx=\"https:\/\/andr83.io\/wp-admin\/admin-ajax.php?action=likebtn_prx\"  data-event_handler=\"likebtn_eh\" ><\/span><!-- LikeBtn.com END --><\/div>","protected":false},"author":1,"featured_media":1508,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"image","meta":{"_uag_custom_page_level_css":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[54],"tags":[100,99,98,101],"class_list":["post-1384","post","type-post","status-publish","format-image","has-post-thumbnail","hentry","category-development","tag-fp","tag-implicit","tag-scala","tag-type-class","post_format-post-format-image","masonry-post","generate-columns","tablet-grid-50","mobile-grid-100","grid-parent","grid-50","no-featured-image-padding"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/andr83.io\/wp-content\/uploads\/2018\/04\/magic_hat.png","uagb_featured_image_src":{"full":["https:\/\/andr83.io\/wp-content\/uploads\/2018\/04\/magic_hat.png",1212,584,false],"thumbnail":["https:\/\/andr83.io\/wp-content\/uploads\/2018\/04\/magic_hat-150x150.png",150,150,true],"medium":["https:\/\/andr83.io\/wp-content\/uploads\/2018\/04\/magic_hat-600x289.png",600,289,true],"medium_large":["https:\/\/andr83.io\/wp-content\/uploads\/2018\/04\/magic_hat.png",768,370,false],"large":["https:\/\/andr83.io\/wp-content\/uploads\/2018\/04\/magic_hat-950x458.png",950,458,true],"1536x1536":["https:\/\/andr83.io\/wp-content\/uploads\/2018\/04\/magic_hat.png",1212,584,false],"2048x2048":["https:\/\/andr83.io\/wp-content\/uploads\/2018\/04\/magic_hat.png",1212,584,false]},"uagb_author_info":{"display_name":"andr83","author_link":"https:\/\/andr83.io\/en\/author\/andr83\/"},"uagb_comment_info":0,"uagb_excerpt":"Reading Time: 4 minutes During last year I have had several conversations with my friends from Java world about their experience in Scala. Most of them tried to use Scala as better Java of course and after returned back with reason - Scala is too powerful and there are a lot of ways to do&hellip;","jetpack_shortlink":"https:\/\/wp.me\/p9rlG0-mk","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/andr83.io\/en\/wp-json\/wp\/v2\/posts\/1384"}],"collection":[{"href":"https:\/\/andr83.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/andr83.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/andr83.io\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/andr83.io\/en\/wp-json\/wp\/v2\/comments?post=1384"}],"version-history":[{"count":18,"href":"https:\/\/andr83.io\/en\/wp-json\/wp\/v2\/posts\/1384\/revisions"}],"predecessor-version":[{"id":6944,"href":"https:\/\/andr83.io\/en\/wp-json\/wp\/v2\/posts\/1384\/revisions\/6944"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/andr83.io\/en\/wp-json\/wp\/v2\/media\/1508"}],"wp:attachment":[{"href":"https:\/\/andr83.io\/en\/wp-json\/wp\/v2\/media?parent=1384"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andr83.io\/en\/wp-json\/wp\/v2\/categories?post=1384"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andr83.io\/en\/wp-json\/wp\/v2\/tags?post=1384"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}