<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tim Britton</title>
    <description>The latest articles on DEV Community by Tim Britton (@tim_britton).</description>
    <link>https://dev.to/tim_britton</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F339133%2Fae3bc198-12c3-42e1-8f9f-884a1578534c.jpeg</url>
      <title>DEV Community: Tim Britton</title>
      <link>https://dev.to/tim_britton</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tim_britton"/>
    <language>en</language>
    <item>
      <title>Kotlin DSL: An Introduction</title>
      <dc:creator>Tim Britton</dc:creator>
      <pubDate>Sat, 25 Apr 2020 01:50:25 +0000</pubDate>
      <link>https://dev.to/tim_britton/kotlin-dsl-an-introduction-5f62</link>
      <guid>https://dev.to/tim_britton/kotlin-dsl-an-introduction-5f62</guid>
      <description>&lt;p&gt;I am a pretty big proponent of Kotlin as a language and for the last three years, I have had the opportunity to build a platform utilizing Kotlin in conjunction with Vertx.  I think one of the best parts of Kotlin is you can always discover a better way of doing something.  In this article, I am going to discuss how to write a Kotlin DSL and provide a simple example of a DSL I wrote recently for one of my toy projects.&lt;/p&gt;

&lt;p&gt;Let start by discussing what a DSL is in the first place.  DSL stands for &lt;strong&gt;D&lt;/strong&gt;omain &lt;strong&gt;S&lt;/strong&gt;pecific &lt;strong&gt;L&lt;/strong&gt;anguage which I would further define as modifying the syntax of Kotlin to adhere to a given concept in your broader system.&lt;/p&gt;

&lt;p&gt;Kotlin enables you to build these DSLs via specific language features the three features I want to highlight are &lt;strong&gt;Lambda Syntax&lt;/strong&gt;, &lt;strong&gt;Higher-Order Functions&lt;/strong&gt; and &lt;strong&gt;Extension Functions&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lambda Syntax
&lt;/h3&gt;

&lt;p&gt;The syntax for Lambda Functions is different than other languages and has some built-in functionality that is unique.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;listOfLetters&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//yields list ["a", "b", "c"]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Lambda is not a parameter to map but is after the map function name.
&lt;/li&gt;
&lt;li&gt;The input to the Lambda is automatically given a name &lt;code&gt;it&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Higher Order Functions
&lt;/h3&gt;

&lt;p&gt;Kotlin has higher-order functions which means you are able to pass functions into other functions&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
 &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;b&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//prints `B`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Extension Functions
&lt;/h3&gt;

&lt;p&gt;Extension Functions allow you to expand other classes with new functionality without updating the class itself.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;meow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MEOW"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;kitten&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;kitten&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;meow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;//prints `MEOW`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When you combine these three features you are able to customize Kotlin to fit the needs of what you are working on.&lt;/p&gt;

&lt;p&gt;For one of my toy projects, I'm working on I wrote a DSL for creating tables for generating random value objects.&lt;/p&gt;

&lt;p&gt;When utilizing this DSL you can write the following:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;COMMON_ACTION_COST_TABLE&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="n"&gt;simpleTable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ActionCost&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"Common Action Cost Table"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="m"&gt;2.0&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nc"&gt;ActionCost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ONE&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nf"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="m"&gt;30.0&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nc"&gt;ActionCost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;TWO&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nf"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="m"&gt;20.0&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nc"&gt;ActionCost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;THREE&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nf"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="m"&gt;20.0&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nc"&gt;ActionCost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;FOUR&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nf"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="m"&gt;18.0&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nc"&gt;ActionCost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;FIVE&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nf"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="m"&gt;10.0&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nc"&gt;ActionCost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SIX&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;What this code does is create a named table that associates a percentage to a give &lt;code&gt;ActionCost&lt;/code&gt;.  You can then call &lt;code&gt;random()&lt;/code&gt; to get a random value from the table where if you call it 100 times you will likely get &lt;code&gt;ActionCost.ONE&lt;/code&gt; two percent of the time.&lt;/p&gt;

&lt;p&gt;The class yielded by the simpleTable method is: &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: I'm not working with doubles because rounding sucks.  Also wouldn't recommend using this on anything productive.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The DSL for constructing this data structure looks like so:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The DSL is composed of two extension methods providing the easy to use and understandable structure and the final extension validates the data within the structure since we want the percentage to add to 100.&lt;/p&gt;

&lt;p&gt;When I wrote this DSL I wanted to be able to visually identify potential bugs with the percentages I assigned to a given entity and be able to quickly make a change to what could be a pretty large set of entries.&lt;/p&gt;

&lt;p&gt;Well with that I hope you were able to learn something about how DSLs work in Kotlin.  Feel free to drop a comment below If you have questions or comments or if you are interested in seeing other DSLs I have written.&lt;/p&gt;

&lt;p&gt;If there is enough interest I might do a live rewrite of the Vertx Web DSL and write up an article on how to write a DSL for an existing framework.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>dsl</category>
    </item>
  </channel>
</rss>
