tag:blogger.com,1999:blog-15869647670327984232024-03-13T22:19:21.381+05:30Abstrakt Nonsense| @missingfaktor's weblogZimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.comBlogger34125tag:blogger.com,1999:blog-1586964767032798423.post-82362725223140185612017-03-27T05:12:00.004+05:302017-03-27T05:13:39.654+05:30This blog has a new home<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">This blog has now been migrated to <a href="http://www.rahulsteapot.com/writing/">Rahul's Teapot</a>, my new Jekyll and Git powered website. I will no longer be writing here.</span><br />
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">We had a good run, Blogger. Thank you, and so long. 🙇🏽👋🏾</span></div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-81866115667609537232014-09-08T22:16:00.000+05:302014-09-08T22:16:43.896+05:30TDD is Dead, Long Live TyDD!<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: arial;">The inaugural meetup of our Young Haskell Padawans group was held yesterday. I have posted the slides for my talk "TDD is Dead, Long Live TyDD" on </span><a href="https://github.com/missingfaktor/young-haskell-padawans-1-long-live-tydd" style="color: #1155cc; font-family: arial;">github</a><span style="background-color: white; color: #222222; font-family: arial;"> and </span><a href="https://speakerdeck.com/missingfaktor/tdd-is-dead-long-live-tydd" style="color: #1155cc; font-family: arial;">speakerdeck</a><span style="background-color: white; color: #222222; font-family: arial;">. I have said it in the README on github, but saying it again: The keynote file has presenter notes which contain the references to various papers and blogs I mentioned.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9VXM1-mbqVzgC9OrTXreKT4PooLCuFPl9mD11SAacC1nzkIyd6g7ADw5I-QvM59e803uxzQLJl27W6gDhBHB2ZfREkROUwzYkeOZeskCA8Dp2iAdlVa34GWDzJbA2mMWbLIMhac9x9_0/s1600/0.DSCN0024.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9VXM1-mbqVzgC9OrTXreKT4PooLCuFPl9mD11SAacC1nzkIyd6g7ADw5I-QvM59e803uxzQLJl27W6gDhBHB2ZfREkROUwzYkeOZeskCA8Dp2iAdlVa34GWDzJbA2mMWbLIMhac9x9_0/s1600/0.DSCN0024.JPG" height="300" width="400" /></a></div>
<br /></div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-20971397534036825812014-08-10T03:38:00.000+05:302014-08-10T03:39:53.108+05:30Types of `map` function in Haskell, Scala, and Clojure<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<i>(I tweeted <a href="https://twitter.com/missingfaktor/status/497983269410189312" style="color: #1155cc;">this picture</a> a few hours ago. It was not supposed to assert Haskell's superiority over Scala and Clojure or anything like that, but many seem to have perceived it so. For the FUD that I inadvertently created, apologies. Here is an attempt to rectify my error, with a more nuanced and fairer analysis of the topic.)</i></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
The all too familiar `map` function has a staggering limitation – it works only for lists. Its type looks like this, when written in Scala notation.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<pre class="" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.200000762939453px; margin-top: 0em;"><span class="" style="color: #008800; font-weight: bold;">def</span> <span class="" style="color: #880000;">map</span><span class="">[</span><span class="" style="color: #880000;">A</span>, <span class="" style="color: #880000;">B</span><span class="">]</span><span class="">(</span><span class="" style="color: #003377;">f</span><span class="">:</span> <span class="" style="color: #880000;">A</span> <span class="">=</span><span class="">></span> <span class="" style="color: #880000;">B</span>, <span class="" style="color: #003377;">xs</span><span class="">:</span> <span class="" style="color: #880000;">List</span><span class="">[</span><span class="" style="color: #880000;">A</span><span class="">]</span><span class="">)</span><span class="">:</span> <span class="" style="color: #880000;">List</span><span class="">[</span><span class="" style="color: #880000;">B</span><span class="">]</span></pre>
</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Wouldn't it be nice if we could "map over" other things? Like vectors, perhaps? </div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Various languages have explored this, and other <b>dimensions of generalization</b>, in a number of ways. Among those, we will specifically look at Haskell, Scala, and Clojure.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<b>Haskell</b></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Haskell has a type-class called `Functor` that <b>allows arbitrary structures to dictate how they should be mapped over</b>. (If this were OO-world, this type-class may have been labelled `Mappable`.) The function is called `fmap`, because `map` was already taken by lists.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
This is what the definition looks like:</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<pre class="" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.200000762939453px; margin-top: 0em;"><span class=""><span class="" style="color: #008800; font-weight: bold;">class</span> <span class="" style="color: #003366; font-weight: bold;">Functor</span> <span class="" style="color: #003377;">f</span> <span class="" style="color: #008800; font-weight: bold;">where</span></span>
<span class=""> <span class="" style="color: #880000;">fmap</span> <span class="" style="color: #008800; font-weight: bold;">::</span> (<span class="" style="color: #003377;">a</span> <span class="" style="color: #008800; font-weight: bold;">-></span> <span class="" style="color: #003377;">b</span>) <span class="" style="color: #008800; font-weight: bold;">-></span> <span class="" style="color: #003377;">f</span> <span class="" style="color: #003377;">a</span> <span class="" style="color: #008800; font-weight: bold;">-></span> <span class="" style="color: #003377;">f</span> <span class="" style="color: #003377;">b</span></span></pre>
</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Or in Scala notation:</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<pre class="" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.200000762939453px; margin-top: 0em;"><span class="" style="color: #008800; font-weight: bold;">trait</span> <span class="" style="color: #880000;">Functor</span><span class="">[</span><span class="" style="color: #880000;">F</span><span class="">[</span>_<span class="">]</span><span class="">]</span> <span class="">{</span>
<span class="" style="color: #008800; font-weight: bold;">def</span> <span class="" style="color: #880000;">fmap</span><span class="">[</span><span class="" style="color: #880000;">A</span>, <span class="" style="color: #880000;">B</span><span class="">]</span><span class="">(</span><span class="" style="color: #003377;">f</span><span class="">:</span> <span class="" style="color: #880000;">A</span> <span class="">=</span><span class="">></span> <span class="" style="color: #880000;">B</span>, <span class="" style="color: #003377;">x</span><span class="">:</span> <span class="" style="color: #880000;">F</span><span class="">[</span><span class="" style="color: #880000;">A</span><span class="">]</span><span class="">)</span><span class="">:</span> <span class="" style="color: #880000;">F</span><span class="">[</span><span class="" style="color: #880000;">B</span><span class="">]</span>
<span class="">}</span></pre>
</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Note my use of a very unassuming term "structure". What I am trying to imply here is that the thing to be mapped over need not be a container. Here are a couple of examples of things that are functors, but not containers.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<pre class="" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.200000762939453px; margin-top: 0em;"><span class="" style="color: #888888;">// Identity</span>
<span class="" style="color: #008800; font-weight: bold;">type</span> <span class="" style="color: #880000;">Id</span><span class="">[</span><span class="" style="color: #880000;">A</span><span class="">]</span> <span class="">=</span> <span class="" style="color: #880000;">A</span>
<span class="">implicit</span> <span class="" style="color: #008800; font-weight: bold;">val</span> <span class="" style="color: #880000;">identityFunctor</span> <span class="">=</span> <span class="" style="color: #008800; font-weight: bold;">new</span> <span class="" style="color: #880000;">Functor</span><span class="">[</span><span class="" style="color: #880000;">Id</span><span class="">]</span> <span class="">{</span>
<span class="" style="color: #008800; font-weight: bold;">def</span> <span class="" style="color: #880000;">fmap</span><span class="">[</span><span class="" style="color: #880000;">A</span>, <span class="" style="color: #880000;">B</span><span class="">]</span><span class="">(</span><span class="" style="color: #003377;">f</span><span class="">:</span> <span class="" style="color: #880000;">A</span> <span class="">=</span><span class="">></span> <span class="" style="color: #880000;">B</span>, <span class="" style="color: #003377;">x</span><span class="">:</span> <span class="" style="color: #880000;">Id</span><span class="">[</span><span class="" style="color: #880000;">A</span><span class="">]</span><span class="">)</span><span class="">:</span> <span class="" style="color: #880000;">Id</span><span class="">[</span><span class="" style="color: #880000;">B</span><span class="">]</span> <span class="">=</span> f<span class="">(</span>x<span class="">)</span>
<span class="">}</span>
<span class="" style="color: #888888;">// Functions</span>
<span class="" style="color: #008800; font-weight: bold;">trait</span> <span class="" style="color: #880000;">FuncFrom</span><span class="">[</span><span class="" style="color: #880000;">A</span><span class="">]</span> <span class="">{</span>
<span class="" style="color: #008800; font-weight: bold;">type</span> <span class="" style="color: #880000;">To</span><span class="">[</span><span class="" style="color: #880000;">B</span><span class="">]</span> <span class="">=</span> <span class="" style="color: #880000;">A</span> <span class="">=</span><span class="">></span> <span class="" style="color: #880000;">B</span>
<span class="">}</span>
<span class="">implicit</span> <span class="" style="color: #008800; font-weight: bold;">def</span> <span class="" style="color: #880000;">functionFunctor</span><span class="">[</span><span class="" style="color: #880000;">S</span><span class="">]</span> <span class="">=</span> <span class="" style="color: #008800; font-weight: bold;">new</span> <span class="" style="color: #880000;">Functor</span><span class="">[</span><span class="" style="color: #880000;">FuncFrom</span><span class="">[</span><span class="" style="color: #880000;">S</span><span class="">]</span>#<span class="" style="color: #880000;">To</span><span class="">]</span> <span class="">{</span>
<span class="" style="color: #008800; font-weight: bold;">def</span> <span class="" style="color: #880000;">fmap</span><span class="">[</span><span class="" style="color: #880000;">A</span>, <span class="" style="color: #880000;">B</span><span class="">]</span><span class="">(</span><span class="" style="color: #003377;">f</span><span class="">:</span> <span class="" style="color: #880000;">FuncFrom</span><span class="">[</span><span class="" style="color: #880000;">A</span><span class="">]</span>#<span class="" style="color: #880000;">To</span><span class="">[</span><span class="" style="color: #880000;">B</span><span class="">]</span>, <span class="" style="color: #003377;">x</span><span class="">:</span> <span class="" style="color: #880000;">FuncFrom</span><span class="">[</span><span class="" style="color: #880000;">S</span><span class="">]</span>#<span class="" style="color: #880000;">To</span><span class="">[</span><span class="" style="color: #880000;">A</span><span class="">]</span><span class="">)</span><span class="">:</span> <span class="" style="color: #880000;">FuncFrom</span><span class="">[</span><span class="" style="color: #880000;">S</span><span class="">]</span>#<span class="" style="color: #880000;">To</span><span class="">[</span><span class="" style="color: #880000;">B</span><span class="">]</span> <span class="">=</span> f.compose<span class="">(</span>x<span class="">)</span>
<span class="">}</span></pre>
</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Sometimes it's possible to infer a functor instance for a data type from its structure. Haskell provides multiple facilities for doing this. (DeriveFunctor, DeriveGeneric, TH etc.)</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<b><br /></b></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<b>Scala</b></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
In Scala, map is typed so that <b>it can choose the most suitable result type for the occasion</b>. Here is what its type looks like, when seen in all its glory:</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<pre class="" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 1.3em; margin-top: 0em;"><span class="" style="color: #008800; font-weight: bold;">def</span> <span class="" style="color: #880000;">map</span><span class="">[</span><span class="" style="color: #880000;">A</span>, <span class="" style="color: #880000;">B</span>, <span class="" style="color: #880000;">That</span><span class="">]</span><span class="">(</span><span class="" style="color: #003377;">f</span><span class="">:</span> <span class="" style="color: #880000;">A</span> <span class="" style="color: black;">=</span><span class="" style="color: black;">></span> <span class="" style="color: #880000;">B</span>, <span class="" style="color: #003377;">coll</span><span class="">:</span> <span class="" style="color: #880000;">FilterMonadic</span><span class="">[</span><span class="" style="color: #880000;">A</span>, <span class="" style="color: #880000;">Repr</span><span class="">]</span><span class="">)</span>
<span class="">(</span><span class="">implicit</span> <span class="" style="color: #003377;">bf</span><span class="">:</span> <span class="" style="color: #880000;">CanBuildFrom</span><span class="">[</span><span class="" style="color: #880000;">Repr</span>, <span class="" style="color: #880000;">B</span>, <span class="" style="color: #880000;">That</span><span class="">]</span><span class="">)</span><span class="" style="color: black;">:</span> <span class="" style="color: #880000;">That</span>
</pre>
</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Here are some examples of the wonderful things it can do. (Pasted from REPL; see the types on the left.)</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<pre class="" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.200000762939453px; margin-top: 0em;">scala<span class="">></span> <span class=""><span class="" style="color: #008800; font-weight: bold;">import</span> <span class="" style="color: #003377;">collection.</span><span class="" style="color: #003377;">immutable.</span><span class="" style="color: #003377;">_</span></span>
<span class=""><span class="" style="color: #008800; font-weight: bold;">import</span> <span class="" style="color: #003377;">collection.</span><span class="" style="color: #003377;">immutable.</span><span class="" style="color: #003377;">_</span></span>
scala<span class="">></span> <span class="" style="color: #008800; font-weight: bold;">val</span> <span class="" style="color: #880000;">b</span> <span class="">=</span> <span class="" style="color: #880000;">BitSet</span><span class="">(</span><span class="" style="color: #0000dd; font-weight: bold;">3</span>, <span class="" style="color: #0000dd; font-weight: bold;">8</span>, <span class="" style="color: #0000dd; font-weight: bold;">9</span><span class="">)</span>
b<span class="">:</span> scala.collection.immutable.<span class="" style="color: #880000;">BitSet</span> <span class="">=</span> <span class="" style="color: #880000;">BitSet</span><span class="">(</span><span class="" style="color: #0000dd; font-weight: bold;">3</span>, <span class="" style="color: #0000dd; font-weight: bold;">8</span>, <span class="" style="color: #0000dd; font-weight: bold;">9</span><span class="">)</span>
scala<span class="">></span> b.map<span class="">(</span>_ <span class="">+</span> <span class="" style="color: #0000dd; font-weight: bold;">1</span><span class="">)</span>
res2<span class="">:</span> scala.collection.immutable.<span class="" style="color: #880000;">BitSet</span> <span class="">=</span> <span class="" style="color: #880000;">BitSet</span><span class="">(</span><span class="" style="color: #0000dd; font-weight: bold;">4</span>, <span class="" style="color: #0000dd; font-weight: bold;">9</span>, <span class="" style="color: #0000dd; font-weight: bold;">10</span><span class="">)</span>
scala<span class="">></span> b.map<span class="">(</span>_.toString<span class="">)</span>
res3<span class="">:</span> scala.collection.immutable.<span class="" style="color: #880000;">SortedSet</span><span class="">[</span><span class="" style="color: #008800; font-weight: bold;">String</span><span class="">]</span> <span class="">=</span> <span class="" style="color: #880000;">TreeSet</span><span class="">(</span><span class="" style="color: #0000dd; font-weight: bold;">3</span>, <span class="" style="color: #0000dd; font-weight: bold;">8</span>, <span class="" style="color: #0000dd; font-weight: bold;">9</span><span class="">)</span>
scala<span class="">></span> <span class="" style="color: #008800; font-weight: bold;">val</span> <span class="" style="color: #880000;">m</span> <span class="">=</span> <span class="" style="color: #880000;">Map</span><span class="">(</span><span class="" style="color: #0000dd; font-weight: bold;">3</span> <span class="">-</span><span class="">></span> <span class="" style="color: #dd2200;">"hello"</span>, <span class="" style="color: #0000dd; font-weight: bold;">4</span> <span class="">-</span><span class="">></span> <span class="" style="color: #dd2200;">"world"</span><span class="">)</span>
m<span class="">:</span> scala.collection.immutable.<span class="" style="color: #880000;">Map</span><span class="">[</span><span class="" style="color: #008800; font-weight: bold;">Int</span>,<span class="" style="color: #008800; font-weight: bold;">String</span><span class="">]</span> <span class="">=</span> <span class="" style="color: #880000;">Map</span><span class="">(</span><span class="" style="color: #0000dd; font-weight: bold;">3</span> <span class="">-</span><span class="">></span> hello, <span class="" style="color: #0000dd; font-weight: bold;">4</span> <span class="">-</span><span class="">></span> world<span class="">)</span>
scala<span class="">></span> m.map <span class="">{</span> <span class="" style="color: #008800; font-weight: bold;">case</span> <span class="">(</span>k, v<span class="">)</span> <span class="">=</span><span class="">></span> <span class="">(</span>k, v<span class="">(</span><span class="" style="color: #0000dd; font-weight: bold;">0</span><span class="">)</span><span class="">)</span> <span class="">}</span>
res4<span class="">:</span> scala.collection.immutable.<span class="" style="color: #880000;">Map</span><span class="">[</span><span class="" style="color: #008800; font-weight: bold;">Int</span>,<span class="" style="color: #008800; font-weight: bold;">Char</span><span class="">]</span> <span class="">=</span> <span class="" style="color: #880000;">Map</span><span class="">(</span><span class="" style="color: #0000dd; font-weight: bold;">3</span> <span class="">-</span><span class="">></span> h, <span class="" style="color: #0000dd; font-weight: bold;">4</span> <span class="">-</span><span class="">></span> w<span class="">)</span>
scala<span class="">></span> m.map <span class="">{</span> <span class="" style="color: #008800; font-weight: bold;">case</span> <span class="">(</span>k, v<span class="">)</span> <span class="">=</span><span class="">></span> v <span class="">}</span>
res5<span class="">:</span> scala.collection.immutable.<span class="" style="color: #880000;">Iterable</span><span class="">[</span><span class="" style="color: #008800; font-weight: bold;">String</span><span class="">]</span> <span class="">=</span> <span class="" style="color: #880000;">List</span><span class="">(</span>hello, world<span class="">)</span></pre>
</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
This is achieved with a sophisticated/complex abstraction called `CanBuildFrom`. I highly recommend reading <a href="http://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html" style="color: #1155cc;"><span id="goog_647050688"></span>this document<span id="goog_647050689"></span></a> to understand the philosophy behind the architecture of Scala collections.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
The best part about this framework is that it's relatively easy for your custom collections to fit in, while needing to provide only the minimum required details. The document I linked above exemplifies this point with a custom collection class called `RNA`.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Now, the type signature arguably <a href="http://stackoverflow.com/questions/1722726/is-the-scala-2-8-collections-library-a-case-of-the-longest-suicide-note-in-hist" style="color: #1155cc;">looks quite involved/scary</a>. To address the issue, at least partially, Scala team devised something called <a href="http://stackoverflow.com/questions/4106817/scaladoc-use-case" style="color: #1155cc;">use-case</a>, which shows simplified/compressed signatures in the documentation.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
The Scala collections framework has received an immense criticism for the complexity of its design. Some argue the <a href="http://yz.mit.edu/wp/true-scala-complexity/" style="color: #1155cc;">extension is not quite as natural as advertised</a>, and the implementation leaks through in many ways. Paul Philips, the man who needs no introduction in Scala circles, <a href="https://www.youtube.com/watch?v=uiJycy6dFSQ" style="color: #1155cc;">criticizes its very foundations</a>, and exemplifies his points with a numerousgotchas, bugs, and extension difficulties the design has led to. He is <a href="https://www.youtube.com/watch?v=4jh94gowim0" style="color: #1155cc;">working on a new collections framework</a> built on simpler and more correctness-friendly foundations. </div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
It deserves mentioning that I, and <a href="https://groups.google.com/forum/#!topic/scala-user/ImqlClXTrS4%5B1-25-false%5D" style="color: #1155cc;">many others</a> who've worked with Scala for long, do not share the same frustration, and have found that the design works well enough in practice. YMMV.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<b>Clojure</b></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Clojure extends `map` to <b>work with arbitrary number of sequences</b>. How does it behave for two and more arguments? Simple – it <b>zips the given sequences and then applies the supplied function on the group</b>! </div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<div class="gmail_default">
Though Clojure is a dynamically typed language, it has <a href="http://typedclojure.org/" style="color: #1155cc;">an optional type system</a> available, which is what we are going to use for the purpose of this post. This is how the type of `map` looks like with Typed Clojure:</div>
<div class="gmail_default">
<br /></div>
<div class="gmail_default">
<pre class="" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.200000762939453px; margin-top: 0em;"><span class="">(<span class="">ann</span> <span class="">clojure</span>.<span class="">core</span>/<span class="">map</span><span class=""></span>
<span class="">(<span class="">All</span> <span class="">[c a b ...]</span><span class=""></span>
<span class="">(<span class="">Fn</span> <span class="">[<span class="">[a b ... b -> c]</span><span class=""> </span>
<span class="">(<span class="">NonEmptySeqable</span> a)</span> <span class="">(<span class="">NonEmptySeqable</span> b)</span> ... b -> <span class="">(<span class="">NonEmptyLazySeq</span> c)</span>]</span><span class=""></span>
<span class="">[<span class="">[a b ... b -> c]</span><span class=""> </span>
<span class="">(U <span class="" style="color: #003388; font-weight: bold;">nil</span> <span class="">(<span class="">Seqable</span> a)</span>)</span> <span class="">(U <span class="" style="color: #003388; font-weight: bold;">nil</span> <span class="">(<span class="">Seqable</span> b)</span>)</span> ... b -> <span class="">(<span class="">LazySeq</span> c)</span>]</span></span></span></span>))</pre>
</div>
<div class="gmail_default">
<br /></div>
<div>
<br /></div>
<div>
In Scala(-like) notation, that would roughly be:</div>
<div>
<br /></div>
<div>
<pre class="" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.200000762939453px; margin-top: 0em; white-space: pre-wrap; word-wrap: break-word;"><span class="" style="color: #008800; font-weight: bold;">def</span> <span class="" style="color: #880000;">map</span><span class="">[</span><span class="" style="color: #880000;">A</span>, <span class="" style="color: #880000;">B</span>, ..., <span class="" style="color: #880000;">C</span><span class="">]</span><span class="">(</span><span class="" style="color: #003377;">xs</span><span class="">:</span> <span class="" style="color: #880000;">NonEmptySeqable</span><span class="">[</span><span class="" style="color: #880000;">A</span><span class="">]</span>, <span class="" style="color: #003377;">ys</span><span class="">:</span> <span class="" style="color: #880000;">NonEmptySeqable</span><span class="">[</span><span class="" style="color: #880000;">B</span><span class="">]</span>, ..., <span class="" style="color: #003377;">f</span><span class="">:</span> <span class="">(</span><span class="" style="color: #880000;">A</span>, <span class="" style="color: #880000;">B</span>, ...<span class="">)</span> <span class="">=</span><span class="">></span> <span class="" style="color: #880000;">C</span><span class="">)</span><span class="">:</span> <span class="" style="color: #880000;">NonEmptyLazySeq</span><span class="">[</span><span class="" style="color: #880000;">C</span><span class="">]</span>
<span class="" style="color: #008800; font-weight: bold;">
</span></pre>
<pre class="" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.200000762939453px; margin-top: 0em; white-space: pre-wrap; word-wrap: break-word;"><span class="" style="color: #008800; font-weight: bold;">def</span> <span class="" style="color: #880000;">map</span><span class="">[</span><span class="" style="color: #880000;">A</span>, <span class="" style="color: #880000;">B</span>, ..., <span class="" style="color: #880000;">C</span><span class="">]</span><span class="">(</span><span class="" style="color: #003377;">xs</span><span class="">:</span> <span class="" style="color: #880000;">Null</span> <span class="">|</span> <span class="" style="color: #880000;">Seqable</span><span class="">[</span><span class="" style="color: #880000;">A</span><span class="">]</span>, <span class="" style="color: #003377;">ys</span><span class="">:</span> <span class="" style="color: #880000;">Null</span> <span class="">|</span> <span class="" style="color: #880000;">Seqable</span><span class="">[</span><span class="" style="color: #880000;">B</span><span class="">]</span>, ..., <span class="" style="color: #003377;">f</span><span class="">:</span> <span class="">(</span><span class="" style="color: #880000;">A</span>, <span class="" style="color: #880000;">B</span>, ...<span class="">)</span> <span class="">=</span><span class="">></span> <span class="" style="color: #880000;">C</span><span class="">)</span><span class="">:</span> <span class="" style="color: #880000;">LazySeq</span><span class="">[</span><span class="" style="color: #880000;">C</span><span class="">]</span></pre>
</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
(The above was taken from <a href="http://nathanic.org/posts/2013/typed-clojure-tour/" style="color: #1155cc;">this blog post</a>.)</div>
<div>
<br /></div>
<div>
This signature may look daunting, but being a Lisp and a dynamically typed language, variadic arity function application is a very natural operation in Clojure.</div>
</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Note that Typed Clojure type here has a more expressive specification of function's behavior, than the Scala and Haskell counterparts – such as how the function behaves differently for non-empty and empty sequences. <a href="https://twitter.com/ambrosebs/status/498026292147544064" style="color: #1155cc;">The essence of the function lies in the second signature</a>.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Also to be noted: This generalization isn't Clojure's innovation. Common Lisp's `mapcar` has the same behavior.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<b>Fairer comparison</b></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
As we saw, the three languages are trying to generalize `map` along very different dimensions. So a judgement like "this one's shorter, and therefore better" would be superficial and unfair. </div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
For fairness' sake, let's see how the other two languages fare in what the third tries to do.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Functor is easily expressible in Scala (and we did it above). Scalaz has it. Type-based dispatch and ergo functor is largely irrelevant in Clojure's case.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
CanBuildFrom, it turns out, is <a href="http://stackoverflow.com/questions/7705119/can-this-functionality-be-implemented-with-haskells-type-system" style="color: #1155cc;">exceedingly hard</a> in Haskell. Whether or not they think it's the right way to go is beside the point. This technique too is irrelevant in Clojure's case, for the same reason as before.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Clojure's variadic arity map that subsumes various `zipWith{N}` operations is hard to do in typed languages. Check out the <a href="http://community.haskell.org/~wren/wren-extras/dist/doc/html/wren-extras/Data-List-ZipWithN.html" style="color: #1155cc;">ZipWithN stuff here</a>. Typically one'd just <a href="http://www.mail-archive.com/haskell-cafe@haskell.org/msg28603.html" style="color: #1155cc;">use applicative</a> though, which can be thought of as a generalization of functor for variadic arity. The ZipWithN and applicative comment holds true for Scala as well.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<b>Conclusion</b></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
The picture I tweeted is supposed to be symbolic of different strides these languages are making in similar areas.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
I personally find all of the generalizations discussed to be positively interesting and useful.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
I hope this post paints a fairer picture than what I tweeted in the morning.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<b>Credits</b></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Thank you for your many inputs, Ambrose BS, Eyal Lotem, and Edward George. </div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-51266377366097797552014-08-09T14:37:00.000+05:302014-08-09T14:37:09.698+05:30Back from a break<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<b>Where have you been?</b></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
I was quite busy over past few months, and had taken a break from blogging.</div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
A lot of positive things happened.</div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
We (ThoughtWorks, Pune) organized the first ever annual Pune Scala Symposium. The event was very successful. I have written about it at length on <a href="http://www.thoughtworks.com/insights/blog/first-annual-pune-scala-symposium" style="color: #1155cc;">ThoughtWorks Insights</a>. You may want to check out my talk on <a href="http://www.thoughtworks.com/insights/blog/promise-better-future" style="color: #1155cc;">futures and promises</a> from the conference.</div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
I went to Istanbul in the month of May on another business trip. The first one happened in last December. The experience from both trips was surreal and exhilarating, and I am going to write a separate (and long!) post about it. One of the pictures from our wondrous trip:</div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK4Xricr9G6yxJUNC1h9eHh55zY0EnjAezTsgHlbEmFGzY02fLawWw7U_aCNcnYjUNMPVcV1zYEt87nVbJGl6NSCShJE_XHTDXwCLq66V1RzXF_tQpRJWN-3j7NmMN0gkQ6XzFc6IomUU/s1600/1921046_784158531594517_633455714_o.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK4Xricr9G6yxJUNC1h9eHh55zY0EnjAezTsgHlbEmFGzY02fLawWw7U_aCNcnYjUNMPVcV1zYEt87nVbJGl6NSCShJE_XHTDXwCLq66V1RzXF_tQpRJWN-3j7NmMN0gkQ6XzFc6IomUU/s1600/1921046_784158531594517_633455714_o.jpg" height="300" width="400" /></a></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
I am also involved in the organization of the first ever (again!) functional programming conference in India. It's to be held in coming October, and you can register for it <a href="http://functionalconf.com/">here</a>. There are some <a href="http://confengine.com/user/rahul-goma-phulore">talk proposals</a> from yours truly as well! Please vote if you like them.</div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
And now the biggest news in life! I triumphed over the deadly Hepatitis C virus. The treatment went on for a year, and was physically, mentally, and financially very taxing. It ending has been quite a relief. You can read more about it in my <a href="https://www.facebook.com/100000011310654/posts/858648287478874/" style="color: #1155cc;">Facebook life event</a>.</div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<b>What happens to the blog?</b></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
I am putting an end to the "<a href="http://missingfaktor.blogspot.in/search/label/this-week" style="color: #1155cc;">interesting things this week</a>" series. While useful for both readers (hopefully!) and myself, it required a significant investment of time and effort. I concluded the incentives were not commensurate, and hence the decision. Sorry if I have disappointed any of you.</div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
The social media obsessed creature that I am, I will still continue to share things that I find interesting. </div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
The blog posts will be more topical from now on. I have listed a few topics in my notebook that I want to blog about. I am going to try and write two posts every month, but I cannot make any promises.</div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
I tweet profusely. If the signal-to-noise ratio of my tweets is within your tolerance limits (and it will likely be, if you are interested in programming languages), you should <a href="http://twitter.com/missingfaktor" style="color: #1155cc;">follow me</a>! </div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
I plan to compile some curated lists on github (inspired by the recent <a href="https://github.com/t3chnoboy/awesome-awesome-awesome" style="color: #1155cc;">awesome</a> meme), for good resources on functional programming, types, and anything else I am into. That approach seems like it will work better.</div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
Until next time!</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-52556138936653513832014-03-29T19:49:00.000+05:302014-03-29T19:49:21.150+05:30Interesting things in past two weeks - viii (2014.03.29)<div dir="ltr" style="text-align: left;" trbidi="on">
<ol style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Wrapping an imperative API in a functional one</b> - <a href="http://www.slideshare.net/oxbow_lakes/fpx-talk-2014" style="color: #1155cc;" target="_blank">http://www.slideshare.net/<wbr></wbr>oxbow_lakes/fpx-talk-2014</a><br /><br />A talk from Chris Marshall, on wrapping an imperative Java API in a typed, algebraic, functional API, using Scalaz. It seems the video for the talk hasn't been uploaded yet.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Why OCaml? Why now?</b> - <a href="http://spyder.wordpress.com/2014/03/16/why-ocaml-why-now/" style="color: #1155cc;" target="_blank">http://spyder.wordpress.com/<wbr></wbr>2014/03/16/why-ocaml-why-now/</a><br /><br />Some more OCaml advocacy. An especially interesting bit from the post: "Facebook created a new language (Hack, a statically typed PHP variant) and wrote the compiler in OCaml. They then use js_of_ocaml to compile their entire type checker into JavaScript, as the basis of a web IDE along the lines of cloud9. Due to the use of OCaml for everything, this IDE has client-side code completion and error checking. It’s pretty amazing."<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>STM and persistent data structures performance on mutlicore architectures </b>- <a href="https://groups.google.com/forum/#!msg/clojure/q2dDWFHpdFk/FK_aqQViNKkJ" style="color: #1155cc;" target="_blank">https://groups.google.com/<wbr></wbr>forum/#!msg/clojure/<wbr></wbr>q2dDWFHpdFk/FK_aqQViNKkJ</a><br /><br />In January, Martin Thompson gave a talk on top 10 performance myths, where he spoke a bit about immutable/persistent data structures and STM. Here's a Clojure mailing list thread where he expands on his points, and answers some questions from the Clojure community.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>The J Programming Language</b> - <a href="http://www.infoq.com/presentations/j-language#_=_" style="color: #1155cc;" target="_blank">http://www.infoq.com/<wbr></wbr>presentations/j-language#_=_</a><br /><br />Tracy Harms' talk on the J language. I have only seen the slides, and the talk seems to have good, elaborate examples, which may help you understand the core J ideas and probably inspire you to look into array/tacit programming model deeper.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>An introduction to recursion schemes</b> - <a href="http://patrickthomson.ghost.io/an-introduction-to-recursion-schemes/" style="color: #1155cc;" target="_blank">http://patrickthomson.ghost.<wbr></wbr>io/an-introduction-to-<wbr></wbr>recursion-schemes/</a><br /><br />Patrick Thomson asserts that, "recursion schemes are just as essential to idiomatic functional programming as for and while are to idiomatic imperative programming." In this post, he demonstrates top-down and bottom-up traversals, which are simplest of recursion schemes. He will be writing about other recursion schemes in future posts in the series.<br /><br />I still haven't read "Bananas, Lenses, Envelopes, and Barbed Wire", the paper he alludes to in this post. Oh, I have so much to learn!<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Session</b> - <a href="https://medium.com/p/1a12997a5f70" style="color: #1155cc;" target="_blank">https://medium.com/p/<wbr></wbr>1a12997a5f70</a><br /><br />Session is a live-coding environment or a web REPL for Clojure, built atop Om and Datomic. It saves your REPL sessions in Datomic database, so that you can revisit them in future. It also has a "data-oriented" rendering model, where all graphic renderings have a backing EDN representation.<br /><br />It is a notebook environment like Mathematica or IPython, which could probably also be used as a teaching tool.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Macros vs Types</b> - <a href="https://thenewcircle.com/s/post/1582/macros_vs_types_eugene_burmako_lars_hupel_video" style="color: #1155cc;" target="_blank">https://thenewcircle.com/s/<wbr></wbr>post/1582/macros_vs_types_<wbr></wbr>eugene_burmako_lars_hupel_<wbr></wbr>video</a><br /><br />Eugene Burmako and Lars Hupel's NEScala talk is out. They go into pros and cons of both approaches, and how to combine the two together for fun and profit. They also talk about the latest "shadow embedding" and "yin yang" stuff, which I mentioned in the last post in the series.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Gorilla REPL </b>- <a href="http://gorilla-repl.org/" style="color: #1155cc;" target="_blank">gorilla-repl.org</a><br /><br />A project very similar to Session, but without all the database stuff. Gorilla worksheets are saved as simple Clojure files with all the text it between as comments.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Toward a better programming</b> - <a href="http://www.chris-granger.com/2014/03/27/toward-a-better-programming/" style="color: #1155cc;" target="_blank">http://www.chris-granger.<wbr></wbr>com/2014/03/27/toward-a-<wbr></wbr>better-programming/</a><br /><br />Chris Granger is working on a new programming environment called Aurora. Get details at the above link.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>How to name things</b> - <a href="http://www.slideshare.net/purewest/howto-namethings" style="color: #1155cc;" target="_blank">http://www.slideshare.net/<wbr></wbr>purewest/howto-namethings</a><br /><br />This presentation is not about naming in programming; sorry for the confusion. It is about some amazing web tools that will help you come up with awesome names for your blogs, events, sites.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Introductions to advanced Haskell topics</b> - <a href="http://www.haskellforall.com/2014/03/introductions-to-advanced-haskell-topics.html" style="color: #1155cc;" target="_blank">http://www.haskellforall.<wbr></wbr>com/2014/03/introductions-to-<wbr></wbr>advanced-haskell-topics.html</a><br /><br />It is difficult to find good resources on some of the advanced Haskell topics. Gabriel Gonzalez of haskellforall and pipes fame is here to help you with some pointers on monad transformers, parsers, Free, and such.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Squants </b>- <a href="http://www.squants.com/" style="color: #1155cc;" target="_blank">http://www.squants.com/</a><br /><br />A very impressive Scala library for quantities, units of measure, and dimensional analysis.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Programming with patterns </b>- <a href="http://bondi.it.uts.edu.au/defun.pdf" style="color: #1155cc;" target="_blank">http://bondi.it.uts.edu.au/<wbr></wbr>defun.pdf</a><br /><br />I was having a conversation with my colleague, Mushtaq, about pattern matching, where he pointed me to this interesting language called Bondi, which is based on pattern calculus, something the author claims is strictly more expressive than lambda calculus. I couldn't find any easy resources on the subject and haven't looked at it very deeply, but it sure sounds very interesting.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Running free with free monads </b>- <a href="http://www.slideshare.net/kenbot/running-free-with-the-monads">http://www.slideshare.net/kenbot/running-free-with-the-monads</a><br /><br />Ken Scambler's talk slides on free monads in Scala.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Using and abusing macros </b>- <a href="http://damienradtke.com/using-and-abusing-macros/">http://damienradtke.com/using-and-abusing-macros/</a><br /><br />Rust seems to have a very structured and powerful macro system. Here is an example of its (ab-)use for a card game called Dominion.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>ClojureWest 2014 videos</b> - <a href="https://www.youtube.com/user/ClojureTV">https://www.youtube.com/user/ClojureTV</a><br /><br />ClojureWest videos are out. I watched a few of them, a few are scheduled for next week. I quite liked David Nolen's talk on Om. Priyatam's talk on a "poet REPL" they built is also interesting. Zach Tellman's "predictably fast Clojure" was pretty amazing.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Functional programming is terrible </b>- <a href="https://thenewcircle.com/s/post/1584/functional_programming_is_terrible_runar_bjarnason_video">https://thenewcircle.com/s/post/1584/functional_programming_is_terrible_runar_bjarnason_video</a><br /><br />Runar Oli talks about how functional programming can be terrible "in Scala" due to a certain characteristics of JVM, Scala the language, and Scala's type system, and then concludes with why FP in Scala is awesome and beneficial nevertheless.<br /></span></li>
</ol>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<span style="color: black; font-family: arial, helvetica, sans-serif;">Until next time!</span></div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-29833610356926322212014-03-18T00:59:00.000+05:302014-03-18T00:59:58.487+05:30Interesting things in past two weeks - vii (2014.03.15)<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
I was busy last week with <a href="http://info.thoughtworks.com/geeknight-pune-march-12-registration.html" style="color: #1155cc;" target="_blank">GeekNight</a> and such, and was not able to write a post in this series. The conference went well. All talks were well received. (Including ours, I hope!)</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidYHUns_STaTHG2lMs1QmYhsAZZUcoPSuqHjPdfnBvb5YWAIaT0Cv5GnVWL7SSfLRsLg09lpBnWIzb0R-PvsWZWBrPilqiuwVr9wtSznfYEiekmMJrS-p0CxUQoipLJnGZ3c5-l2wXNSk/s1600/geeknight.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidYHUns_STaTHG2lMs1QmYhsAZZUcoPSuqHjPdfnBvb5YWAIaT0Cv5GnVWL7SSfLRsLg09lpBnWIzb0R-PvsWZWBrPilqiuwVr9wtSznfYEiekmMJrS-p0CxUQoipLJnGZ3c5-l2wXNSk/s1600/geeknight.jpg" height="180" width="320" /></a></div>
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
Anyway, here are some interesting links from past weeks:</div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<ol>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Grid style sheets</b> - <a href="http://gridstylesheets.org/" style="color: #1155cc;" target="_blank">http://gridstylesheets.org/</a><br /><br />This novel approach to style sheets lets you specify layout and positioning in terms of "constraints" and is way more expressive than CSS. This will help you build sophisticated UIs, with lesser effort, and more joy.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Why most unit testing is waste</b> - <a href="http://www.rbcs-us.com/documents/Why-Most-Unit-Testing-is-Waste.pdf" style="color: #1155cc;" target="_blank">http://www.rbcs-us.com/<wbr></wbr>documents/Why-Most-Unit-<wbr></wbr>Testing-is-Waste.pdf</a><br /><br />I haven't read this article yet, but it has spurred a great deal of discussion in many places, and may be worth a read.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Propositions as types</b> - <a href="http://homepages.inf.ed.ac.uk/wadler/papers/propositions-as-types/propositions-as-types.pdf" style="color: #1155cc;" target="_blank">http://homepages.inf.ed.ac.uk/<wbr></wbr>wadler/papers/propositions-as-<wbr></wbr>types/propositions-as-types.<wbr></wbr>pdf</a><br /><br />A very powerful piece from Phil Wadler, that talks about the isomoprhims between propositions and types, and between proofs and programs. It talks about how deep the implications of this isomorphism are, and how thus some aspects of programming are absolute.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>A brief introduction to Haskell, and why it matters</b> - <a href="https://github.com/pchiusano/fpinscala/wiki/A-brief-introduction-to-Haskell,-and-why-it-matters" style="color: #1155cc;" target="_blank">https://github.com/<wbr></wbr>pchiusano/fpinscala/wiki/A-<wbr></wbr>brief-introduction-to-Haskell,<wbr></wbr>-and-why-it-matters</a><br /><br />Good introduction. Though I'd have liked a small section on Haskell's philosophy/worldview in the beginning.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>ECMAScript 6 features overview</b> - <a href="https://github.com/lukehoban/es6features" style="color: #1155cc;" target="_blank">https://github.com/lukehoban/<wbr></wbr>es6features</a><br /><br />ECMAScript 6 is around the corner, and is bringing in a serious lot of features, which turn it into a new language altogether. Terse syntaxes for lambdas and class-based OO, destructuring, for-comprehensions, generators, modules are some of the highlights.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Effective ML</b> - <a href="http://vimeo.com/14313378" style="color: #1155cc;" target="_blank">http://vimeo.com/14313378</a><br /><br />I had been hearing about this Yaron Minsky lecture since long time. After all, it gave us type fanatics one of our favorite lines - "make illegal states unrepresentable". For whatever reasons, I had not watched the talk yet. But last week, I did. And boy, was it amazing! A lot of practical advice in this lecture, with some very good examples. The lecture is a bit ML-specific, but is still largely applicable to Scala, F#, and other languages in the philosophical vicinity.<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPmEHVrxxjzyk1drbBE-pt-_gnEPGnKUeXDyd_g7e72kpWnUsYUWYsXVh3m6TbWqNnlHViKNnG7__eqY7brR4H9JwVOJkoAzsL6WfMtojpk444DvWLWCj-r-CjML-yVL8hKYvo27wZMx0/s1600/Screen+Shot+2014-03-17+at+4.52.29+PM.png" imageanchor="1" style="font-family: arial; margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPmEHVrxxjzyk1drbBE-pt-_gnEPGnKUeXDyd_g7e72kpWnUsYUWYsXVh3m6TbWqNnlHViKNnG7__eqY7brR4H9JwVOJkoAzsL6WfMtojpk444DvWLWCj-r-CjML-yVL8hKYvo27wZMx0/s1600/Screen+Shot+2014-03-17+at+4.52.29+PM.png" height="200" width="320" /></a><br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>ScalaDays 2014 Schedule</b> - <a href="http://scaladays.org/">http://scaladays.org/</a><br /><br />Yes, it's been announced! A lot of amazing talks to look forward to. This year, topics around ScalaJS, Big data, streaming seem popular.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>OpenDylan </b>- <a href="https://github.com/dylan-lang/opendylan">https://github.com/dylan-lang/opendylan</a><br /><br />There's again been some buzz about this ancient language, Dylan. Manuel Simoni called it <a href="https://twitter.com/msimoni/status/439846878281498625" style="color: #1155cc;">the semi-functional OO language to rule them all</a>.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Macros vs types</b> - <a href="http://scalamacros.org/paperstalks/2014-03-01-MacrosVsTypes.pdf">http://scalamacros.org/paperstalks/2014-03-01-MacrosVsTypes.pdf</a><br /><br />These slides from Eugene Burmako and Lars Hupel are surprisingly good. Looking forward to the talk video being up on the internet.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>C++ vs Rust templates</b> - <a href="https://gist.github.com/bjz/9220415">https://gist.github.com/bjz/9220415</a><br /><br />Nice little comparison between C++ templates and Rust generics. TL;DR: If you are familiar with Haskell and OCaml type systems, that's the model Rust follows. Something C++ too will be moving towards, once the concepts feature is in.<br /><br /></span></li>
<li><b>A tale of two types</b> - <a href="http://chromaticleaves.com/posts/type-systems-fools-choice.html">http://chromaticleaves.com/posts/type-systems-fools-choice.html</a><br /><br />Short, little type systems advocacy. If you have a friend (which could be yourself) who judges type systems by his/her experience with Java or C# or similar, help them today by pointing them to this blog post!<br /><br /></li>
<li><b>Whirlwind tour of Haskell </b>- <a href="http://www.slideshare.net/wtaysom/haskell-tour-part-1-8133513">http://www.slideshare.net/wtaysom/haskell-tour-part-1-8133513</a><br /><br />Good slides. Has some very cool quotes. I liked this one the best - “Haskell has no preferred imperative semantics, and the monad just lets you swap out the semantics according to your needs.”<br /><br /></li>
<li><b>OCaml LWT</b> - <a href="http://ocsigen.org/lwt/">http://ocsigen.org/lwt/</a><br /><br />LWT is a co-operative concurrency library for OCaml. It also provides syntactic extensions similar to F#'s try!, for! etc for async, but specialized for the purpose.<br /><br /></li>
<li><b>Shadow embedding</b> - <a href="https://github.com/amirsh/master-thesis/blob/master/Thesis%20Presentation.pdf">https://github.com/amirsh/master-thesis/blob/master/Thesis%20Presentation.pdf</a><br /><br />This research from Amir Shaikh demonstrates a DSL technique called "shadow embedding", which allows you to create deeply integrated DSLs, which provide very strong compile time guarantees, and with sane error reporting.<br /><br /></li>
<li><b>JS6 generators </b>- <a href="http://wingolog.org/pub/jsromandie-02-2014-slides.pdf">http://wingolog.org/pub/jsromandie-02-2014-slides.pdf</a><br /><br />More on the new ECMAScript generators. Details about how they are to be used, and some implementation strategies for them.<br /><br /></li>
<li><b>Project Palladium</b> - <a href="http://scalamacros.org/news/2014/03/02/project-palladium.html">http://scalamacros.org/news/2014/03/02/project-palladium.html</a><br /><br />This project is aimed at reducing the complexity and verbosity of Scala macros, and make them more useful, enjoyable, and easier to reason about. The first public demo is scheduled for ScalaDays 2014. Looking forward to it.<br /><br /></li>
<li><b>Live coding ScalaJS</b> - <a href="http://vimeo.com/87845442">http://vimeo.com/87845442</a><br /><br />Haoyi Li demonstrating some ScalaJS goodness. Amazing demo.<br /><br /></li>
<li><b>EmbeddedDocument gem </b>- <a href="http://rubygems.org/gems/embedded_document">http://rubygems.org/gems/embedded_document</a><br /><br />Sumit Mahamuni has turned my "embedded document" stuff for Ruby into a gem. Now you can use it on your project! Feedback, pull requests very welcome.<br /><br /></li>
<li><b>Scala Quasiquotes </b>- <a href="http://den.sh/quasiquotes.html">http://den.sh/quasiquotes.html</a><br /><br />Scala macro quasiquotes tutorial. It's hard to imagine how people were managing code transformations before quasiquotes.<br /><br /></li>
<li><b>Mirage</b> - <a href="http://www.openmirage.org/wiki/overview-of-mirage">http://www.openmirage.org/wiki/overview-of-mirage</a><br /><br />From the site: "Mirage is a 'library operating system' for constructing secure, high-performance network applications across a variety of cloud computing and mobile platforms. It works by treating the Xen hypervisor as a stable hardware platform, allowing us to focus on high-performance protocol implementations without worrying about having to support the thousands of device drivers found in a traditional OS. Code can be developed in a high-level functional programming language (OCaml) on a desktop OS such as Linux or Mac OSX, and is then compiled into a fully-standalone, specialised unikernel."<br /><br /></li>
<li><b>Do-It-Yourself OS in Rust </b>- <a href="https://air.mozilla.org/rust-meetup-march-2014/">https://air.mozilla.org/rust-meetup-march-2014/</a><br /><br />A very enjoyable talk, if kernels and such are your thing.<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDgeq9Dpj5Hp1PVH3Uh7pGyl2_8ei0X4hJ6xnHwgYnsLYptwvR-1hXJROD4h2miWJUwpHUMZ-i-X58v6rj8sg6Cf3ErAsYMRzWFCRikszZHQPcay91HH5yLk6vKypFIipvQ07rrDJTPG8/s1600/Screen+Shot+2014-03-18+at+12.42.24+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDgeq9Dpj5Hp1PVH3Uh7pGyl2_8ei0X4hJ6xnHwgYnsLYptwvR-1hXJROD4h2miWJUwpHUMZ-i-X58v6rj8sg6Cf3ErAsYMRzWFCRikszZHQPcay91HH5yLk6vKypFIipvQ07rrDJTPG8/s1600/Screen+Shot+2014-03-18+at+12.42.24+AM.png" height="180" width="320" /></a><br /></li>
<li><b>Frege record accessors and mutators </b>- <a href="http://mmhelloworld.github.io/blog/2014/03/15/frege-record-accessors-and-mutators/">http://mmhelloworld.github.io/blog/2014/03/15/frege-record-accessors-and-mutators/</a><br /><br />Frege can be thought of as a Haskell implementation for JVM, but with some differences. One of those differences is how it does records: With each record definition, you get a set of accessor and mutator functions auto-generated, all in a record specific namespace. This is very handy. Here's an introduction to that feature from Marimuthu Madasammy, the person who wrote Frege's REPL.<br /><br /></li>
<li><b>Huge sci-fi collection </b>- <a href="http://www.astrosociety.org/education/astronomy-resource-guides/science-fiction-stories-with-good-astronomy-physics-a-topical-index/">http://www.astrosociety.org/education/astronomy-resource-guides/science-fiction-stories-with-good-astronomy-physics-a-topical-index/</a><br /><br />I was a huge fan of Jayant Narlikar, an astrophysicist who has written quite a bit of sci-fi in Marathi. He always had a two fold goal with his stories: to teach about some scientific concept, to entertain with a solid plot. The description at the top of this page reminded me of him. Glad to have stumbled upon a list of sci-fi literature/stories which do justice to science. </li>
</ol>
<div>
Until next time!</div>
</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-89222510143276962682014-03-17T04:44:00.000+05:302014-03-17T14:36:27.069+05:30Dead-simple threading with functions, in Clojure<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUlBswInFzr6v09HMoFpD0InibPei6oWs0iGYBSxrluup4KU5q0CsKVfHKbEotWIwer6EEZfH4l-Tw3A2icbRJncch-DB1ZC9lGitY04D2JlyikvQhnyJwOZ9BREizXulOCW5YaIDSI3s/s1600/the_pied_piper_of_hamelin_by_nacrym-d3ao6dj.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUlBswInFzr6v09HMoFpD0InibPei6oWs0iGYBSxrluup4KU5q0CsKVfHKbEotWIwer6EEZfH4l-Tw3A2icbRJncch-DB1ZC9lGitY04D2JlyikvQhnyJwOZ9BREizXulOCW5YaIDSI3s/s1600/the_pied_piper_of_hamelin_by_nacrym-d3ao6dj.jpg" height="281" width="400" /></a></div>
<br />
Clojure has a couple of macros for threading a value through a bunch of computations, `->` and `->>`. The syntactic benefit added by these macros can be seen in examples <a href="http://clojuredocs.org/clojure_core/clojure.core/-%3E" style="color: #1155cc;">here</a> and <a href="http://clojuredocs.org/clojure_core/clojure.core/-%3E%3E" style="color: #1155cc;">here</a>.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
These macros are definitely useful, but being macros, they deal with syntactic forms instead of functions, and thus make a bunch of things harder than they should be. Some such cases:</div>
<div class="gmail_default">
<ol style="background-color: white; color: #222222; font-family: arial;">
<li><span style="color: black; font-family: arial, helvetica, sans-serif;">Running a computation conditionally.</span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;">Nil-shortcutting. This is a special case of 1, where the condition is that the element isn't nil.</span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;">There are two macros for dealing with two common argument positions - first and last. What happens when the argument has to go anywhere else? Or what happens when in a single pipeline, you need to invoke two computations with two different argument positions?</span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;">Dropping in a real function value in pipeline.</span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;">Threading a value through a bunch of iteratively obtained computations.</span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;">Tap an immediate value, and pass it forward.</span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;">Handle to intermediate results.</span></li>
</ol>
<div style="background-color: white; color: #222222; font-family: arial;">
<span style="color: black; font-family: arial, helvetica, sans-serif;">These, and many such other problems, have spawned to a cottage industry of people developing macro extensions or macro alternatives to the two standard threading macros. Let's see how some of those solutions try to address the problems mentioned above:</span></div>
<div style="background-color: white;">
<ol>
<li style="color: #222222; font-family: arial;"><span style="color: black; font-family: arial, helvetica, sans-serif;">Prismatic developed penguin operators, `<a href="https://github.com/Prismatic/plumbing/blob/master/src/plumbing/core.clj" style="color: #1155cc;">?>` and `?>></a>`. Pellet came up with `<a href="https://github.com/pallet/thread-expr" style="color: #1155cc;">if->`, `when-></a>` etc. Chris Houser's Synthread has `<a href="https://github.com/LonoCloud/synthread" style="color: #1155cc;">when</a>`. Clojure core recently added `cond->` and `cond->>` to address the same problem. All of these are special purpose macros which transform the given expression in a form acceptable to `->` and `->>`.</span></li>
<li><span style="font-family: arial, helvetica, sans-serif;"><span style="color: #222222; font-family: arial;">Swiss Arrows has `</span><span style="color: #1155cc;"><u>some-<>` , `some-<>>`</u></span><span style="color: #222222; font-family: arial;">. A variation of the same has made it to the standard library, under name `some->`. (And its cousin `some->>`.)</span></span></li>
<li style="color: #222222; font-family: arial;">Swiss Arrows' `-<>` and `-<>>` (diamond wand and diamond spear respectively) allow you to explicitly specify the argument position. (I find this better.) Synthread's `as`, Pellet's `arg->`, and now core's `as->` allow you to name intermediate results, which can also help in marking the argument position.</li>
<li style="color: #222222; font-family: arial;">In the current implementation, people typically just put another set of parens around a function value. e.g. `(-> 5 ((fn [x] (- x 7))))`. (Yeah, hacky.) Prismatic's plumbing library has a `fn->` macro which makes this syntactically a bit nicer.</li>
<li style="color: #222222; font-family: arial;">Pellet's `for->`.</li>
<li style="color: #222222; font-family: arial;">Synthread's `aside`.</li>
<li style="color: #222222; font-family: arial;">See #3.</li>
</ol>
</div>
<div style="background-color: white; color: #222222; font-family: arial;">
<span style="color: black; font-family: arial, helvetica, sans-serif;">There is a common theme in all of the above solutions:</span></div>
<div style="background-color: white; color: #222222; font-family: arial;">
<ol>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;">They are all macros. These are typically developed in one of two ways: i) A whole new set of macros with additional semantics, like Swiss Arrows. ii) Macros that expand their input forms in a way acceptable to `->` and `->>`, and thus can be used with them. This doesn't strike me as very elegant.</span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;">Many of them come in two flavors - one that works with `->`, another that works with `->>`.</span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;">As evidenced by #1, macros are the primary way used for extension. It's hard to extend with functions in this framework.</span></li>
</ol>
</div>
<div style="background-color: white; color: #222222; font-family: arial;">
<span style="color: black; font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #222222; font-family: arial;">
<span style="color: black; font-family: arial, helvetica, sans-serif;">Here I am proposing a dead simple threading solution, purely based on functions/combinators.</span></div>
<div style="background-color: white; color: #222222; font-family: arial;">
<span style="color: black; font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #222222; font-family: arial;">
<pre class="" style="color: black; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.200000762939453px; margin-top: 0em;"><span class="">(<span class=""><span class="" style="color: #008800; font-weight: bold;">ns</span> <span class="" style="color: #880000;">piper.core)</span><span class=""></span>
<span class=""></span>
<span class="">(<span class=""><span class="" style="color: #008800; font-weight: bold;">defn</span> <span class="" style="color: #880000;">pipe</span> <span class="">[<span class="">value</span> & <span class="">fns</span>]</span><span class=""></span>
<span class="">(<span class="">reduce</span> <span class="">(<span class="">fn</span> <span class="">[<span class="">acc</span> <span class="">cur</span>]</span> <span class="">(<span class="">cur</span> <span class="">acc</span>)</span>)</span> <span class="">value</span> <span class="">fns</span>)</span></span>)<span class=""></span></span>
<span class=""></span>
<span class="">(<span class=""><span class="" style="color: #008800; font-weight: bold;">defn</span> <span class="" style="color: #880000;">given</span> <span class="">[<span class="">pred</span> f]</span><span class=""></span>
<span class="">(<span class="">fn</span> <span class="">[x]</span><span class=""></span>
<span class="">(<span class="">if</span> <span class="">(<span class="">pred</span> x)<span class=""></span></span>
<span class="">(f x)<span class=""></span></span>
x)</span>)</span></span>)<span class=""></span></span>
<span class=""></span>
<span class="">(<span class=""><span class="" style="color: #008800; font-weight: bold;">defn</span> <span class="" style="color: #880000;">unless-nil</span> <span class="">[f]</span><span class=""></span>
<span class="">(<span class="">fn</span> <span class="">[x]</span><span class=""></span>
<span class="">(<span class="">if</span> <span class="">(<span class="">nil</span>? x)<span class=""></span></span>
<span class="" style="color: #003388; font-weight: bold;">nil</span><span class=""></span>
<span class="">(f x)</span>)</span>)</span></span>)<span class=""></span></span>
<span class=""></span>
<span class="">(<span class=""><span class="" style="color: #008800; font-weight: bold;">defn</span> <span class="" style="color: #880000;">tap</span> <span class="">[<span class="">msg</span>]</span><span class=""></span>
<span class="">(<span class="">fn</span> <span class="">[x]</span><span class=""></span>
<span class="">(<span class="">do</span><span class=""></span>
<span class="">(<span class="">println</span> <span class="">(<span class="">str</span> <span class="">msg</span> <span class="" style="color: #dd2200;">": "</span> x)</span>)<span class=""></span></span>
x)</span>)</span></span>)<span class=""></span></span>
<span class=""></span>
<span class="">(<span class=""><span class="" style="color: #008800; font-weight: bold;">defn</span> <span class="" style="color: #880000;">times</span> <span class="">[n f]</span><span class=""></span>
<span class="">(<span class="">fn</span> <span class="">[x]</span><span class=""></span>
<span class="">(<span class="">loop</span> <span class="">[<span class="">value</span> x<span class=""></span>
<span class="">remaining</span>-<span class="">turns</span> n]</span><span class=""></span>
<span class="">(<span class="">if</span> <span class="">(<span class="">zero</span>? <span class="">remaining</span>-<span class="">turns</span>)<span class=""></span></span>
<span class="">value</span><span class=""></span>
<span class="">(<span class="">recur</span> <span class="">(f <span class="">value</span>)<span class=""></span></span>
<span class="">(<span class="">dec</span> <span class="">remaining</span>-<span class="">turns</span>)</span>)</span>)</span>)</span>)</span></span>)</span></span></span></pre>
</div>
<div style="background-color: white; color: #222222; font-family: arial;">
<span style="color: black; font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #222222; font-family: arial;">
<span style="color: black; font-family: arial, helvetica, sans-serif;">Pretty simple, isn't it? Here is some example use (from REPL):</span></div>
<div style="background-color: white; color: #222222; font-family: arial;">
<span style="color: black; font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #222222; font-family: arial;">
<pre class="" style="color: black; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.200000762939453px; margin-top: 0em;"><span class="">user</span>=> <span class="">(<span class="" style="color: #008800; font-weight: bold;">require</span> '<span class="">[<span class="">piper</span>.<span class="">core</span> <span class="" style="color: #003388; font-weight: bold;">:as</span> <span class="">pi</span>]</span>)<span class=""></span></span>
<span class="" style="color: #003388; font-weight: bold;">nil</span><span class=""></span>
<span class="">user</span>=><span class=""></span>
<span class=""></span>
<span class="">user</span>=> <span class="">(<span class="">pi</span>/<span class="">pipe</span> <span class="">{<span class="" style="color: #003388; font-weight: bold;">:a</span> <span class="" style="color: #0000dd; font-weight: bold;">3</span> <span class="" style="color: #003388; font-weight: bold;">:b</span> <span class="" style="color: #0000dd; font-weight: bold;">11</span>}</span><span class=""></span>
#_=> <span class="">(<span class="">pi</span>/<span class="">given</span> #<span class="">(> <span class="">(<span class="" style="color: #003388; font-weight: bold;">:a</span> %)</span> <span class="" style="color: #0000dd; font-weight: bold;">2</span>)<span class=""></span></span>
#_=> #<span class="">(<span class="">update</span>-<span class="">in</span> % <span class="">[<span class="" style="color: #003388; font-weight: bold;">:a</span>]</span> <span class="">inc</span>)</span>)<span class=""></span></span>
#_=> <span class="">(<span class="">pi</span>/<span class="">tap</span> <span class="" style="color: #dd2200;">"i"</span>)<span class=""></span></span>
#_=> <span class="">(<span class="">pi</span>/<span class="">unless</span>-<span class="" style="color: #003388; font-weight: bold;">nil</span> #<span class="">(<span class="">assoc</span> % <span class="" style="color: #003388; font-weight: bold;">:c</span> <span class="" style="color: #0000dd; font-weight: bold;">25</span>)</span>)<span class=""></span></span>
#_=> <span class="">(<span class="">pi</span>/<span class="">tap</span> <span class="" style="color: #dd2200;">"ii"</span>)<span class=""></span></span>
#_=> #<span class="">(<span class="">get</span> % <span class="" style="color: #003388; font-weight: bold;">:a</span>)<span class=""></span></span>
#_=> <span class="">(<span class="">pi</span>/<span class="">tap</span> <span class="" style="color: #dd2200;">"iii"</span>)<span class=""></span></span>
#_=> <span class="">(<span class="">pi</span>/<span class="">times</span> <span class="" style="color: #0000dd; font-weight: bold;">6</span> <span class="">inc</span>)<span class=""></span></span>
#_=> <span class="">(<span class="">pi</span>/<span class="">tap</span> <span class="" style="color: #dd2200;">"iv"</span>)</span>)<span class=""></span></span>
i: <span class="">{<span class="" style="color: #003388; font-weight: bold;">:a</span> <span class="" style="color: #0000dd; font-weight: bold;">4</span>, <span class="" style="color: #003388; font-weight: bold;">:b</span> <span class="" style="color: #0000dd; font-weight: bold;">11</span>}</span><span class=""></span>
<span class="">ii</span>: <span class="">{<span class="" style="color: #003388; font-weight: bold;">:c</span> <span class="" style="color: #0000dd; font-weight: bold;">25</span>, <span class="" style="color: #003388; font-weight: bold;">:a</span> <span class="" style="color: #0000dd; font-weight: bold;">4</span>, <span class="" style="color: #003388; font-weight: bold;">:b</span> <span class="" style="color: #0000dd; font-weight: bold;">11</span>}</span><span class=""></span>
<span class="">iii</span>: <span class="" style="color: #0000dd; font-weight: bold;">4</span><span class=""></span>
<span class="">iv</span>: <span class="" style="color: #0000dd; font-weight: bold;">10</span><span class=""></span>
<span class="" style="color: #0000dd; font-weight: bold;">10</span><span class=""></span>
<span class="">user</span>=></pre>
</div>
<div style="background-color: white; color: #222222; font-family: arial;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial;">
Some benefits of this approach:</div>
<div style="background-color: white; color: #222222; font-family: arial;">
<ol>
<li>It deals entirely with function values. The pipe combinator only cares that it's given a bunch of functions that can be called one after another. That's the only contract it has. It doesn't care how these function values came to life. </li>
<li>...which means it's quite easy to extend this system with new combinators. For an exercise, try writing a combinator that executes the given function and on exception defaults to a given fallback value.</li>
<li>You do not need to invent a new convention or new syntax for the argument positioning. The user can simply use `fn` form, or `#(` reader macro, or `partial`, or whatever strikes their fancy, and benefit from the already present syntax/functions.</li>
<li>Handle to an intermediate value can be done in a straightforward way with nested pipes. </li>
</ol>
</div>
<div style="background-color: white; color: #222222; font-family: arial;">
<span style="color: black; font-family: arial, helvetica, sans-serif;">It's not all good and shiny though. There are some major downsides too:</span></div>
<div style="background-color: white; color: #222222; font-family: arial;">
<ol>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;">The most common use cases of `->` and `->>` when translated to our approach would perhaps lead to noisier code, using either `#(` or `partial`.</span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;">The macro based approaches we talked about move around forms, insert arguments here and there, create intermediate let-bindings, and avoid generating function values as much as possible. This leads to better performance. </span></li>
</ol>
</div>
<div style="background-color: white; color: #222222; font-family: arial;">
This perhaps indicates that the function based approach may have occurred before to people, but they would have abandoned it for aforementioned reasons.</div>
<div style="background-color: white; color: #222222; font-family: arial;">
<br /></div>
<div style="background-color: white; color: #222222; font-family: arial;">
Nevertheless I may try using this on some project, just to see how much it scales, it terms of readability and performance.</div>
<div>
<br /></div>
</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com1tag:blogger.com,1999:blog-1586964767032798423.post-24145771127658778222014-03-04T02:44:00.000+05:302014-03-04T02:44:38.563+05:30Interesting things this week - vi (2014.03.01)<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="gmail_default" style="color: #222222; font-family: arial;">
<ol>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Google's Modular Phone, Ara</b> - <a href="http://techcrunch.com/2014/02/27/googles-project-ara-50-modular-smartphone-could-change-the-way-we-buy-phones-starting-next-year/?utm_campaign=fb&ncid=fb">http://techcrunch.com/2014/02/27/googles-project-ara-50-modular-smartphone-could-change-the-way-we-buy-phones-starting-next-year/?utm_campaign=fb&ncid=fb</a><br /><br />The <a href="http://phoneblocks.com/" style="color: #1155cc;">Phoneblocks idea</a> that came out last year is soon becoming a reality. This is going to be a game changer. Looking forward to Ara.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Atom, Github's hackable text editor for 21st century</b> - <a href="https://atom.io/">https://atom.io/</a><br /><br />From the project page: "Atom is composed of over 50 open-source packages that integrate around a minimal core. Our goal is a deeply extensible system that blurs the distinction between user and developer". This is a noble goal to have. Not sure how this editor compares to Sublime and Textmate. It will be nice to have a side-by-side comparison.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>C++17: I See a Monad in Your Future!</b> - <a href="http://bartoszmilewski.com/2014/02/26/c17-i-see-a-monad-in-your-future/">http://bartoszmilewski.com/2014/02/26/c17-i-see-a-monad-in-your-future/</a><br /><br />Bartosz Milewski mentions how the functor, applicative, monad, and monoid "patterns" appear in some C++ libraries. He also links to a "resumable functions" proposal for C++ (essentially async-await, but without a full-fledged support for continuations). There has been a clear, unmistakable trend towards more algebraic, data-driven, and functional style of programming, and C++ too hasn't been able to keep off it.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>John A De Goes' slides on First Class Patterns </b>- <a href="http://www.slideshare.net/jdegoes/firstclass-patterns">http://www.slideshare.net/jdegoes/firstclass-patterns</a><br /><br />I posted about Data.Pattern library in Haskell three weeks ago. In these slides, John presents some ideas from that library in Scala, simplified for pedagogical purposes.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Scala JS Fiddle</b> - <a href="http://www.scala-js-fiddle.com/">http://www.scala-js-fiddle.com/</a><br /><br />Scala JS is growing at an awesome pace. Now we even have a JS Fiddle like web app for Scala JS! Go try it out.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Scala.Rx</b> - <a href="https://github.com/lihaoyi/scala.rx">https://github.com/lihaoyi/scala.rx</a><br /><br />The awesome Haoyi Li has created a "change propagation" library for Scala and Scala JS. It's based on push-based FRP approach mentioned in "Deprecating the Observer Pattern" paper. The library looks straightforward enough to use. It would be nice to see UI, spreadsheet etc libraries built atop it.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Wolfram language</b> - <a href="http://www.youtube.com/watch?v=_P9HqHVPeik">http://www.youtube.com/watch?v=_P9HqHVPeik</a><br /><br />I mentioned Wolfram's "biggest technology project yet" blog some time in this series before. Here's the first public preview of it. Boy, this stuff is just rad! Wolfram has really created something unparalleled and deserves to be cheered for it.<br /><br /></span></li>
<li><b>Patterns in types</b> - <a href="http://mth.io/talks/patterns-in-types-ylj/#/">http://mth.io/talks/patterns-in-types-ylj/#/</a><br /><br />Excellent slides from Mark Hibberd, that show how types can drive you to more general, composable, and correct designs. The presentation also goes on to show how monad transformers can make use of several monads together convenient. He uses a great running example of an HTTP library, which helps understanding quite a lot. Highly recommended.<br /><br /></li>
<li><b>Koding</b> - <a href="https://koding.com/">https://koding.com/</a><br /><br />Koding provides a collaborative development environment that can be used for teaching, pairing, sharing, and for making real apps. Koding also has some social features that let you share your work, receive feedback, endorse etc.<br /></li>
</ol>
<div>
<br />Until next time!</div>
<div style="font-size: small;">
<br /></div>
</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-41719077296866587152014-03-04T00:32:00.000+05:302014-03-04T00:36:08.234+05:30Interesting things this week - v (2014.02.22)<div dir="ltr" style="text-align: left;" trbidi="on">
<ol style="background-color: white; color: #222222; font-family: arial;">
<li style="color: black; font-family: arial, helvetica, sans-serif;"><b>Common Lisp - The Untold Story</b> - <a href="http://www.nhplace.com/kent/Papers/cl-untold-story.html">http://www.nhplace.com/kent/Papers/cl-untold-story.html</a><br /><br />Kent Pitman talks about how he came to be involved with Common Lisp and the Common Lips standard, and the experiences and learnings he gained in the process. This description of his journey is very detailed, and will give you insights into the intricacies of human/social/economical factors involved in programming language design and standardization.<br /><br /></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Influx DB</b> - <a href="http://influxdb.org/docs/query_language/">http://influxdb.org/docs/query_language/</a></span><br />A new open-source distributed time series database with no external dependencies. This looks like it could be very useful for analyzing application history, logs, and such.<br /><br /></li>
<li><b>Dotty, open sourced</b> - <a href="https://groups.google.com/forum/#!msg/scala-internals/6HL6lVLI3bQ/IY4gEyOwFhoJ">https://groups.google.com/forum/#!msg/scala-internals/6HL6lVLI3bQ/IY4gEyOwFhoJ</a><br /><br />Dotty, the "Research platform for new language concepts and compiler technologies for Scala", has been open sourced! Odersky articulates very eloquently and succinctly in his announcement their motivations behind the project. So I wouldn't bother summarizing it here. Go take a look.<br /><br /></li>
<li><b>Haskell development on Emacs</b> - <a href="http://tim.dysinger.net/posts/2014-02-18-haskell-with-emacs.html">http://tim.dysinger.net/posts/2014-02-18-haskell-with-emacs.html</a><br /><br />Tim Dysinger shares details of his Haskell development environment and workflow. This should get you started with Emacs for Haskell.<br /><br /></li>
<li><b>The future of programming</b> - <a href="http://pchiusano.blogspot.in/2011/12/future-of-programming.html">http://pchiusano.blogspot.in/2011/12/future-of-programming.html</a><br /><br />This is kind of an ancient post, but while we are at it - the subject of development environment for Haskell - I thought I should mention this very relevant post. Among other things, this post from Paul Chiusano talks about the kind of potential the IDEs for awesomely-typed languages like Haskell could have. Very nice read.<br /><br /></li>
<li><b>FP Complete's FP Haskell Center</b> - <a href="https://www.fpcomplete.com/business/fp-haskell-center/">https://www.fpcomplete.com/business/fp-haskell-center/</a><br /><br />Again while we are on the topic, have you seen FP Complete's web-based IDE? It is relatively new, yet quite feature rich, and shows a good promise.<br /><br /></li>
<li><b>Monocle, a lens library for Scala</b> - <a href="https://github.com/julien-truffaut/Monocle">https://github.com/julien-truffaut/Monocle</a><br /><br />This is a port of Edward Kmett's famous <a href="https://github.com/ekmett/lens" style="color: #1155cc;">Control.Lens</a> library for Haskell. There is <a href="https://github.com/puffnfresh/scala-lenz" style="color: #1155cc;">one more port</a> out there by Brian McKenna. I haven't looked at these deeply to know what the differences etc are.<br /><br /></li>
<li><b>James Iry’s history of programming languages (illustrated with pictures and large fonts)</b> - <a href="http://thequickword.wordpress.com/2014/02/16/james-irys-history-of-programming-languages-illustrated-with-pictures-and-large-fonts/">http://thequickword.wordpress.com/2014/02/16/james-irys-history-of-programming-languages-illustrated-with-pictures-and-large-fonts/</a><br /><br />James Iry's <a href="http://james-iry.blogspot.in/2009/05/brief-incomplete-and-mostly-wrong.html" style="color: #1155cc;">A Brief, Incomplete, and Mostly Wrong History of Programming Languages</a> is one of the most humorous pieces I have ever read on the subject of programming languages. Here's a new version of it, embellished with some cool pictures from history.<br /><br /></li>
<li><b>Type programming: Shifting from values to types</b> - <a href="http://proseand.co.nz/2014/02/17/type-programming-shifting-from-values-to-types/">http://proseand.co.nz/2014/02/17/type-programming-shifting-from-values-to-types/</a><br /><br />Type level programming in Scala has very interesting parallels with term level (or value level) programming. Unfortunately most existing type level programming tutorials don't emphasize on this bit, and have a pace greater than what most people are comfortable with. This post takes a small subtopic - type level booleans, and explains the ideas involved, slowly and in detail. I am looking forward to the next post in the series.<br /><br /></li>
<li><b>Disallow shadowing</b> - <a href="http://lambda-the-ultimate.org/node/4885">http://lambda-the-ultimate.org/node/4885</a><br /><br />An LtU discussion on a seemingly mundane subject of shadowing, that goes all over the place, to things like "alternatives to functions", "control flow is paradigmatic flow". Interesting read.<br /><br /></li>
<li><b>Why Coursera loves Scala </b>- <a href="http://tech.coursera.org/blog/2014/02/18/why-we-love-scala-at-coursera/">http://tech.coursera.org/blog/2014/02/18/why-we-love-scala-at-coursera/</a><br /><br />Coursera team's field experiences in using Scala, and how they came to love it.<br /><br /></li>
<li><b>Probable C# syntax additions</b> - <a href="http://damieng.com/blog/2013/12/09/probable-c-6-0-features-illustrated">http://damieng.com/blog/2013/12/09/probable-c-6-0-features-illustrated</a><br /><br />You may be wondering how/why this made to my list. If you look closely, a lot of the syntax additions proposed are already present in some form in Scala and/or F#. I would just like those two to have a smug moment of "I told you so". B-)<br /><br /></li>
<li><b>Dart for the language enthusiast</b> - <a href="http://www.infoq.com/presentations/dart-introduction">http://www.infoq.com/presentations/dart-introduction</a><br /><br />Bob Nystorm, the lead developer of Dart and a well regarded PL guy, shows why Dart might not be so uninteresting for a language enthusiast after all. While I admire the newer languages appearing on the Alt-JS scene, I personally don't find Dart piquing my interests enough. I feel Clojurescript and ScalaJS might be better investments of time.<br /><br /></li>
<li><b>Are there benefits from Java's type erasure</b> - <a href="http://stackoverflow.com/questions/20918650/are-there-benefits-from-javas-type-erasure">http://stackoverflow.com/questions/20918650/are-there-benefits-from-javas-type-erasure</a><br /><br />I am not among those to reject outright the utility of persisting type information at runtime. Unlike the top voted answers in the thread. Interesting/informative posts nevertheless.<br /><br /></li>
<li><b>What is a type system for </b>- <a href="http://michaelrbernste.in/2014/02/17/what-is-a-type-system-for.html">http://michaelrbernste.in/2014/02/17/what-is-a-type-system-for.html</a><br /><br />Michael Bernstein has been reading TAPL and sharing his epiphanies along the way. This is a post where he shares his understandings of the purpose of a type system. The post reminds me of a quote from Yaron Minsky - "make illegal states unrepresentable." You can find that talk <a href="http://vimeo.com/14313378" style="color: #1155cc;">here</a>.<br /><br /></li>
<li><b>Scala, ugly duckling?</b> - <a href="http://blog.moonshothq.com/scala-ugly-duckling-programming-languages">http://blog.moonshothq.com/scala-ugly-duckling-programming-languages</a><br /><br />This post dispels some myths about Scala ecosystem and community, and concludes on a note that Scala brings an undeniable value to the scene, and that it has a bright future ahead.<br /><br /></li>
<li><b>Deconstructing FP</b> - <a href="http://www.infoq.com/presentations/functional-pros-cons">http://www.infoq.com/presentations/functional-pros-cons</a><br /><br />Gilad Bracha has a knack for ruffling feathers. While I don't agree at all with his views on type systems, and find his container metaphor for monads ludicrous, I think he makes a lot of good points in this talk, which makes it well worth a watch.<br /><br /></li>
<li><b>What's up with Paul Phillips?</b> - <a href="https://groups.google.com/forum/m/#!msg/scala-user/ImqlClXTrS4/P1wGjsQpVSMJ">https://groups.google.com/forum/m/#!msg/scala-user/ImqlClXTrS4/P1wGjsQpVSMJ</a><br /><br />A very intriguing thread on scala-user. It contains inquiry and introspection of Paul's critique, updates from Scala team about their efforts to address the issues he pointed out, and people throwing in more critique and feature requests.<br /><br /></li>
<li><b>Extensible records in Shapeless </b>- <a href="https://github.com/milessabin/shapeless/blob/dac2d60f1a60c16f93847eab2fa75fe20ea276cc/examples/src/main/scala/shapeless/examples/labelledgeneric.scala">https://github.com/milessabin/shapeless/blob/dac2d60f1a60c16f93847eab2fa75fe20ea276cc/examples/src/main/scala/shapeless/examples/labelledgeneric.scala</a><br /><br />Miles Sabin has been pushing the limits of Scala type system since past few years. IIRC he wrote the first implementation of extensible records for Scala a couple of years ago. Here is what seems like an improved (and probably revamped) version thereof.<br /><br /></li>
<li><b>Template Haskell quick tutorial</b> - <a href="http://www.slideshare.net/kizzx2/template-haskell-tutorial">http://www.slideshare.net/kizzx2/template-haskell-tutorial</a><br /><br />Template Haskell is a curious meta-linguistic abstraction system (macros) for Haskell. This quick tutorial will give you a gist of how this system works and is used.<br /><br /></li>
<li><b>Sweet JS</b> - <a href="http://sweetjs.org/">http://sweetjs.org/</a><br /><br />Now that we are talking about macros, I remain constantly surprised that not more Javascript developers have heard of Mozilla's Sweet JS. Try it, people! It's good stuff.<br /></li>
</ol>
<div>
<span style="color: #222222; font-family: arial;"><br />Until next time!</span></div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-21199164434940003722014-02-16T14:48:00.000+05:302014-02-16T14:50:28.961+05:30Interesting things this week - iv (2014.02.15)<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<ol style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<li><b>OCaml - what you gain</b> - <a href="http://roscidus.com/blog/blog/2014/02/13/ocaml-what-you-gain/" style="color: #1155cc;" target="_blank">http://roscidus.com/blog/blog/<wbr></wbr>2014/02/13/ocaml-what-you-<wbr></wbr>gain/</a><br /><br />Thomas Leonard was working on rewriting 0install with OCaml. He previously wrote about how going from Python to Ocaml, he lost surprisingly little. The port is now complete, and he is back to tell us what you <i>gain</i> from OCaml. Good read; might motivate you to give OCaml a shot.<br /><br />Among other things, he mentions OCaml's "polymorphic variants". It is a lovely feature, which once you look at, you may miss in every other language.<br /><br />Thomas' blog has many other gems - tips for OCaml, looking back at bugs he faced and whether they could have been prevented, overview of OCaml async libraries etc. Read it!<br /><br /></li>
<li><b>Marvel comics API</b> - <a href="http://developer.marvel.com/" style="color: #1155cc;" target="_blank">http://developer.marvel.com/</a><br /><br />Marvel comics has an API! It gives you access to "data about Marvel's vast library of comics — from what's coming up, to 70 years ago". Sounds exciting, right? Sign up, and play around.<br /><br /></li>
<li><b>Parametricity; Types Are Documentation</b> - <a href="http://dl.dropboxusercontent.com/u/7810909/media/doc/parametricity.pdf" style="color: #1155cc;" target="_blank">http://dl.<wbr></wbr>dropboxusercontent.com/u/<wbr></wbr>7810909/media/doc/<wbr></wbr>parametricity.pdf</a><br /><br />Chris Ford made <a href="https://twitter.com/ctford/status/432204554432958465" style="color: #1155cc;" target="_blank">an interesting statement on twitter</a> last week - "I now realise that Orwell's 'Ignorance is strength' becomes Philip Wadler's 'Theorems for free' when applied to types". It reminded me of these recent Tony Morris slides on the subject. The slides have many good examples that illustrate how parametricity can help you reason about code better.<br /><br /></li>
<li><b>Coursera's success story with Scala, Play, and Akka </b>- <a href="http://downloads.typesafe.com/website/casestudies/Coursera-Case-Study.pdf" style="color: #1155cc;" target="_blank">http://downloads.typesafe.<wbr></wbr>com/website/casestudies/<wbr></wbr>Coursera-Case-Study.pdf</a><br /><br />Coursera was built in PHP. As they reached a customer base of 6+ million and 500+ courses, they realized it wouldn't work for them any more. They evaluated Python and Scala for stacks to switch to, and decided to go with the latter. As per the report, the choices have worked out very well for them. They were able to leverage Play and Akka to handle a high amount of traffic that the site receives. They also seem happy with the IDE and build tool situation of Scala ecosystem.<br /><br /></li>
<li><b>Implementing, Abstracting and Benchmarking Lightweight Threads on the JVM</b> - <a href="http://blog.paralleluniverse.co/2014/02/06/fibers-threads-strands/" style="color: #1155cc;" target="_blank">http://blog.paralleluniverse.<wbr></wbr>co/2014/02/06/fibers-threads-<wbr></wbr>strands/</a>.<br /><br />Quasar implements light-weight threads on JVM, using bytecode instrumentation strategies, similar to what Kilim does. Scala Async and Clojure core.async provide a similar functionality. The article says, "Those employ a similar instrumentation scheme, but perform it at the language level, using macros, rather than at the JVM bytecode level like Quasar. While this allows Clojure to support core.async on non-JVM platforms (like JavaScript), the approach has two limitations: 1) it is only supported by a single language and can’t interoperate with other JVM languages, and 2) because it uses macros, the suspendable constructs are limited to the scope of a single code block, i.e. a function running in a suspendable block cannot call another blocking function; all blocking must be performed at the topmost function. It’s because of the second limitation that these constructs aren’t true lightweight threads, as threads must be able to block at a any call-stack depth."<br /><br /></li>
<li><b>Data.Pattern, first-class patterns in Haskell</b> - <a href="http://hackage.haskell.org/package/first-class-patterns">http://hackage.haskell.org/package/first-class-patterns</a>, <a href="http://hackage.haskell.org/package/first-class-patterns-0.3.2/docs/Data-Pattern.html">http://hackage.haskell.org/package/first-class-patterns-0.3.2/docs/Data-Pattern.html</a>.<br /><br />I absolutely love pattern matching. After using it for years, I still remain surprised by how easy it makes it to reason about code, how it aids readability, how concise it can make your code, and the way it can help you prevent subtle bugs.<br /><br />One thing that leaves much to be desired however is the way pattern matching is implemented in most languages. It's all at the language level. It doesn't blend too well with the world of functions. The extensibility is fairly limited, and often needs additional bells and whistles like Scala's "extractors" or Wadler's "views".<br /><br />All of these problems could be alleviated if "patterns" and "clauses" are made first-class values. (Yes, first-class all the things!) Reiner Pope and Brent Yorgey's `Data.Pattern` does exactly that. Take a look at `Data.Pattern.Base` and `Data.Pattern.Common` to see how beautifully it achieves this goal. IMO, after Control.Lens, this is the most amazing Haskell library ever.<br /><br /></li>
<li><b>First-class patterns in Newspeak</b> - <a href="http://www.hpi.uni-potsdam.de/hirschfeld/publications/media/GellerHirschfeldBracha_2010_PatternMatchingForAnObjectOrientedAndDynamicallyTypedProgrammingLanguage_HPI36.pdf">http://www.hpi.uni-potsdam.de/hirschfeld/publications/media/GellerHirschfeldBracha_2010_PatternMatchingForAnObjectOrientedAndDynamicallyTypedProgrammingLanguage_HPI36.pdf</a>.<br /><br />Newspeak is a dynamically typed, object oriented language, in tradition of Smalltalk. This very detailed paper presents first-class patterns for Newspeak. You'll notice that it features many things from the Haskell implementation, and then some. The two being very different languages however, the implementation strategies differ. Bindings, in particular, are done very differently.<br /><br /></li>
<li><b>SkillsMatter interviews Chris Marshall </b>- <a href="http://skillsmatterblog.wordpress.com/2014/02/12/while-its-compiling-skills-matter-interviews-chris-marshall/">http://skillsmatterblog.wordpress.com/2014/02/12/while-its-compiling-skills-matter-interviews-chris-marshall/</a>.<br /><br />Chris Marshall is a known name in Scala circles, largely due to his contribution on StackOverflow. Here's his recent interview with SkillsMatter.<br /><br />I love the advice he gives regarding the importance of logging. It resonates well with my own experiences and views on the subject.<br /><br /></li>
<li><b>Saying Goodbye to Python</b> - <a href="http://www.ianbicking.org/blog/2014/02/saying-goodbye-to-python.html">http://www.ianbicking.org/blog/2014/02/saying-goodbye-to-python.html</a>.<br /><br />Don't mistake the title! The post is not about some guy having found a new, better language, and leaving Python for it. It's about Ian Bicking's journey over past few years. He did a lot of great work in Python ecosystem (virtualenv and pip come to mind), and is now working with Javascript at Mozilla. Read his blog for more.<br /><br /></li>
<li><b>What is the type of derivative operator</b> - <a href="http://winterkoninkje.dreamwidth.org/91282.html">http://winterkoninkje.dreamwidth.org/91282.html</a>.<br /><br />This nice little post illustrates how typing discipline can be helpful in mathematics. I guess implementing a mathematics library in a dependently typed language may give a good taste of the kind of impact this may have.<br /><br /></li>
<li><b>Will a nicotine patch make you smarter</b> - <a href="http://www.scientificamerican.com/article/will-a-nicotine-patch-make-you-smarter-excerpt/">http://www.scientificamerican.com/article/will-a-nicotine-patch-make-you-smarter-excerpt/</a>.<br /><br />The summary is, there have been a number of studies showing nicotine patches are safe to consume and can enhance cognitive functions in many ways: alertness, attention, memory, psychomotor speed etc. For some godforsaken reason, however, most neuroscientists still wouldn't recommend its use. Probably they want more studies to assure its safety. But do you? ;-) And hey, you didn't hear it from me.<br /><br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhugX0cLgVZIGp79ExVOZ0ovCGJlVGIixym3LJZbAB1kUa_bR48MaI_Q5a9XO7PPMXOuBYQvgV_WMYt0GZbRnErp39YNsg2FCPkNikwf7tWnVIhhyphenhyphenWAsJfNyvxJ82TVnCYatwbz7NBf7Xs/s1600/nicotine.patches.png" imageanchor="1" style="font-family: Times; font-size: medium; margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhugX0cLgVZIGp79ExVOZ0ovCGJlVGIixym3LJZbAB1kUa_bR48MaI_Q5a9XO7PPMXOuBYQvgV_WMYt0GZbRnErp39YNsg2FCPkNikwf7tWnVIhhyphenhyphenWAsJfNyvxJ82TVnCYatwbz7NBf7Xs/s1600/nicotine.patches.png" height="225" width="400" /></a></li>
</ol>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<br />
Until next time!</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com3tag:blogger.com,1999:blog-1586964767032798423.post-53948019120237593242014-02-09T21:18:00.000+05:302014-02-10T00:12:36.067+05:30So how much of inheritance criticism is really valid?<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="gmail_default">
<div class="gmail_default">
<div class="gmail_default">
<div class="gmail_default">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;"><a href="http://www.scala-lang.org/docu/files/collections-api/collections-impl.html" style="color: #1155cc;">Scala collections library</a> has been receiving <a href="https://thenewcircle.com/s/post/1568/scala_collections_why_not_paul_phillips_video" style="color: #1155cc;">a lot of criticism</a> of late. One of the reasons, among many, is its use of inheritance as a primary means of code reuse. This has led to <a href="https://twitter.com/techtangents/status/429527937742688257" style="color: #1155cc;">some uproar</a> (a misguided one IMO).</span></div>
<div class="gmail_default">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;">There was <a href="https://groups.google.com/forum/#!topic/scala-internals/R4fTU_5XVZs" style="color: #1155cc;">a good discussion</a> recently on scala-internals mailing list about a new collection class called AnyRefMap. It brought out many good points. Rex Kerr remarks in one of his posts,</span></div>
<div class="gmail_default">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
</div>
<blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;">
<div class="gmail_default">
<div class="gmail_default">
<blockquote class="gmail_quote" style="border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; margin: 0px 0px 0px 0.8ex; padding-left: 1ex;">
<i><span style="font-family: Arial, Helvetica, sans-serif;">Any method where the call-chain isn't obvious is unsafe to override. For example, HashMap has -= overridden 7 times and += 8 times in the library scan I did. Update was overridden 0 times. put was overridden 0 times. Now, does += call update, or does update call +=, or neither call the other, or what? In AnyRefMap, += calls update, but put has its own implementation. In HashMap, update calls put, but += has its own implementation. </span></i> </blockquote>
</div>
</div>
</blockquote>
<blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;">
<div class="gmail_default">
<div class="gmail_default">
<blockquote class="gmail_quote" style="border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; margin: 0px 0px 0px 0.8ex; padding-left: 1ex;">
</blockquote>
</div>
</div>
</blockquote>
<blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;">
<div class="gmail_default">
<div class="gmail_default">
<blockquote class="gmail_quote" style="border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; margin: 0px 0px 0px 0.8ex; padding-left: 1ex;">
</blockquote>
</div>
</div>
</blockquote>
<blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;">
<div class="gmail_default">
<div class="gmail_default">
<blockquote class="gmail_quote" style="border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; margin: 0px 0px 0px 0.8ex; padding-left: 1ex;">
</blockquote>
</div>
</div>
</blockquote>
<blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;">
<div class="gmail_default">
<div class="gmail_default">
<blockquote class="gmail_quote" style="border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; margin: 0px 0px 0px 0.8ex; padding-left: 1ex;">
<i><span style="font-family: Arial, Helvetica, sans-serif;">How is anyone supposed to keep this straight? </span></i><i><span style="font-family: Arial, Helvetica, sans-serif;">So in the wild we have 8 implementations of maps that are probably inconsistent because people didn't override all the necessary methods (and how could they have known?).</span></i></blockquote>
</div>
</div>
</blockquote>
<div class="gmail_default">
<div class="gmail_default">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;">To which, Rüdiger Klaehn responds:</span></div>
<div class="gmail_default">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
</div>
<blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;">
<div class="gmail_default">
<blockquote class="gmail_quote" style="border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; margin: 0px 0px 0px 0.8ex; padding-left: 1ex;">
<i><span style="font-family: Arial, Helvetica, sans-serif;"><span style="color: black;">There are a lot of methods in scala collections, and it is easy to introduce inconsistencies by overriding some methods and not others. That is why advice to java programmers these days is "Design and document for inheritance or else prohibit it". (Joshua Bloch, Effective Java). This is basically gospel in java land these days. One of the few things that C# got right was to not make virtual the default for methods.</span> </span></i> </blockquote>
</div>
</blockquote>
<blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;">
<div class="gmail_default">
<blockquote class="gmail_quote" style="border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; margin: 0px 0px 0px 0.8ex; padding-left: 1ex;">
</blockquote>
</div>
</blockquote>
<blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;">
<div class="gmail_default">
<blockquote class="gmail_quote" style="border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; margin: 0px 0px 0px 0.8ex; padding-left: 1ex;">
</blockquote>
</div>
</blockquote>
<blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;">
<div class="gmail_default">
<blockquote class="gmail_quote" style="border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; margin: 0px 0px 0px 0.8ex; padding-left: 1ex;">
</blockquote>
</div>
</blockquote>
<blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;">
<div class="gmail_default">
<blockquote class="gmail_quote" style="border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; margin: 0px 0px 0px 0.8ex; padding-left: 1ex;">
</blockquote>
<blockquote class="gmail_quote" style="border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; margin: 0px 0px 0px 0.8ex; padding-left: 1ex;">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;"><i>But how would you design and document for inheritance with scala collections? You could make every method final that is difficult to override because it has to be consistent with other methods. That would be basically all of them except for default in case of AnyRefMap. And then you have to make sure to also do final overrides in case new methods are introduced in one of the traits you inherit from.</i></span></blockquote>
</div>
</blockquote>
<div class="gmail_default">
<div class="gmail_default">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;">(There were many other good points made during the course of the discussion. Read the thread if curious.)</span></div>
<div class="gmail_default">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default">
<span style="font-family: Arial, Helvetica, sans-serif;">The gist is that the selective overriding of methods in inheritance can cause a lot of trouble. I recalled Ionuț G Stan <a href="http://igstan.ro/posts/2011-09-09-how-inheritance-violates-encapsulation.html" style="color: #1155cc;">blogged about this problem</a> a couple years ago, with a very illustrative example. This set me thinking - Wouldn't type-classes suffer from the same problem, since they too allow selective overriding, and defining of type-class methods in terms of each other?</span></div>
<div class="gmail_default">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default">
<span style="font-family: Arial, Helvetica, sans-serif;">There was </span><a href="https://twitter.com/HaskellTips/status/430409144026152960" style="color: #1155cc; font-family: Arial, Helvetica, sans-serif;">a timely tweet from `@HaskellTips</a><span style="font-family: Arial, Helvetica, sans-serif;"> (hat tip!), which illustrated just the same point:</span></div>
</div>
<br />
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.200000762939453px; margin-top: 0em; text-align: left;"><span class="constant constant_other constant_other_haskell" style="color: #003388; font-weight: bold;">Prelude</span><span class="keyword keyword_operator keyword_operator_haskell">></span> <span class="keyword keyword_other keyword_other_haskell" style="color: #008800; font-weight: bold;">data</span> <span class="constant constant_other constant_other_haskell" style="color: #003388; font-weight: bold;">Foo</span> <span class="keyword keyword_operator keyword_operator_haskell">=</span> <span class="constant constant_other constant_other_haskell" style="color: #003388; font-weight: bold;">Foo</span>
<span class="constant constant_other constant_other_haskell" style="color: #003388; font-weight: bold;">Prelude</span><span class="keyword keyword_operator keyword_operator_haskell">></span> <span class="meta meta_declaration meta_declaration_instance meta_declaration_instance_haskell"><span class="keyword keyword_other keyword_other_haskell" style="color: #008800; font-weight: bold;">instance</span> <span class="storage storage_type storage_type_haskell" style="color: #008800; font-weight: bold;">Eq</span> <span class="storage storage_type storage_type_haskell" style="color: #008800; font-weight: bold;">Foo</span> </span>
<span class="constant constant_other constant_other_haskell" style="color: #003388; font-weight: bold;">Prelude</span><span class="keyword keyword_operator keyword_operator_haskell">></span> <span class="constant constant_other constant_other_haskell" style="color: #003388; font-weight: bold;">Foo</span> <span class="keyword keyword_operator keyword_operator_haskell">==</span> <span class="constant constant_other constant_other_haskell" style="color: #003388; font-weight: bold;">Foo</span> </pre>
<div style="text-align: left;">
<span style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.200000762939453px;">*** </span><span class="constant constant_other constant_other_haskell" style="color: #003388; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; font-weight: bold; line-height: 18.200000762939453px;">Exception</span><span class="keyword keyword_operator keyword_operator_haskell" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.200000762939453px;">:</span><span style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.200000762939453px;"> stack overflow</span> </div>
<div class="gmail_default">
<div class="gmail_default" style="background-color: white; color: #222222; text-align: left;">
<span style="color: black;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span></div>
<span style="background-color: white; font-family: Arial, Helvetica, sans-serif;">(Type-class Eq defines (==) and (/=) in terms of each other.)</span><br />
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="color: black;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="color: black;"><a href="https://twitter.com/extempore2" style="color: #1155cc;">Paul</a> pointed out that this problem has a name - <a href="http://en.wikipedia.org/wiki/Fragile_base_class" style="color: #1155cc;">fragile base class</a>. We concluded that the problems with selective overriding aren't unique to inheritance, and apply to type-classes too. Paul puts it much better than I could, so here are the original tweets:</span></span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="color: black;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span></div>
<blockquote class="twitter-tweet" lang="en">
<a href="https://twitter.com/missingfaktor">@missingfaktor</a> You’re right that the key dangerous feature is selective overriding, which needs not inheritance.<br />
— Paul Phillips (@extempore2) <a href="https://twitter.com/extempore2/statuses/430436640230604800">February 3, 2014</a></blockquote>
<script async="" charset="utf-8" src="//platform.twitter.com/widgets.js"></script>
<br />
<blockquote class="twitter-tweet" lang="en">
<a href="https://twitter.com/missingfaktor">@missingfaktor</a> The problem is one of preserving atomicity; people write code which implicitly assumes it, then it happens otherwise.<br />
— Paul Phillips (@extempore2) <a href="https://twitter.com/extempore2/statuses/430436877968375809">February 3, 2014</a></blockquote>
<script async="" charset="utf-8" src="//platform.twitter.com/widgets.js"></script>
<br />
<div class="gmail_default">
<br /></div>
</div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;">So what could we do about the problem of selective overriding? Here are some potential solutions:</span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<ol>
<li><span style="color: black; font-family: Arial, Helvetica, sans-serif;">As recommended in Effective Java, "design and document for inheritance or prohibit it". Guava's Forwarder classes take this approach.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Could we enhance the "document" part of above advice with <a href="https://twitter.com/missingfaktor/status/430441390753865728" style="color: #1155cc;">"enforced with types"</a>? Not sure how that could be done though. </span></li>
<li><span style="color: black; font-family: Arial, Helvetica, sans-serif;"><a href="https://twitter.com/extempore2/status/430437519226724352" style="color: #1155cc;">Disallow overridable methods from calling others on the same instance?</a> Umm... not sure about that.</span></li>
<li><span style="color: black; font-family: Arial, Helvetica, sans-serif;">The Wikipedia page on "fragile base class" suggests "defaulting method invocations on this to closed recursion (static dispatch, early binding) rather than open recursion (dynamic dispatch, late binding)". I don't know if any language implements this.</span></li>
</ol>
<div>
<span style="color: black; font-family: Arial, Helvetica, sans-serif;">This seems like a ripe area for research, and I hope to see some solutions coming up to address the problem being discussed.</span></div>
</div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="color: black;">If you're wondering why I am comparing with type-classes in particular, it's because many seem to think of type-classes as a perfect replacement for inheritance. I myself have been guilty of it. When I saw SPJ's <a href="http://channel9.msdn.com/posts/MDCC-TechTalk-Classes-Jim-but-not-as-we-know-them" style="color: #1155cc;">"</a></span><span style="color: black;"><a href="http://channel9.msdn.com/posts/MDCC-TechTalk-Classes-Jim-but-not-as-we-know-them" style="color: #1155cc;">Classes, Jim, but not as we know them"</a>, I was dazzled. I thought type-classes was the best thing since sliced bread. Paired with <a href="http://www.haskell.org/haskellwiki/Existential_type" style="color: #1155cc;">existentials</a>, <a href="http://stackoverflow.com/questions/7213676/forall-in-scala" style="color: #1155cc;">they can even do many of the things subtyping can</a>. However, as we just saw, they too suffer from the insidious problem of fragile base class.</span></span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="color: black;">SPJ's presentation poses an open question, "In a language with generics and constrained polymorphism, do you need subtyping too?". </span><span style="color: black;">I </span><a href="http://stackoverflow.com/questions/2707171/generics-and-constrained-polymorphism-versus-subtyping" style="color: #1155cc;">posted it to stackoverflow</a><span style="color: black;"> to get more views on the subject. I </span><a href="http://stackoverflow.com/questions/7266596/why-avoid-subtyping" style="color: #1155cc;">posted this another question to stackoverflow</a><span style="color: black;">, which received some satisfactory answers, but I am still not entirely convinced there are enough reasons to entirely avoid using subtyping. </span></span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="color: black;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="color: black;"><span style="font-family: Arial, Helvetica, sans-serif;">As <a href="https://twitter.com/stevedekorte" style="color: #1155cc;">Steve Dekorte</a> and <a href="https://twitter.com/msimoni" style="color: #1155cc;">Manuel Simoni</a> are fond of pointing out, there are some great examples of inheritance in wild, and there are ongoing advancements in the area, from the likes of <a href="http://newspeaklanguage.org/" style="color: #1155cc;">Gilad Bracha</a> and <a href="http://lampwww.epfl.ch/~amin/dot/fool_slides.pdf" style="color: #1155cc;">Martin Odersky</a>. People like <a href="http://www.infoq.com/presentations/post-functional-scala-clojure-haskell" style="color: #1155cc;">Daniel Spiewak</a> too seem to think there's a definite value in subtyping. If I am to borrow <a href="https://plus.google.com/109924404877416820675/posts/FP7kBboq2sJ" style="color: #1155cc;">Daniel Yokomizo's words</a>, I would put it this way: Subtyping, to me, gives an easy way of establishing morphisms, which I find hard to achieve with type-classes and such.</span></span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="color: black;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="color: black;"><span style="font-family: Arial, Helvetica, sans-serif;">I know there are other things on the horizon. Row polymorphism and extensible records in <a href="http://www.impredicative.com/ur/tutorial/intro.html" style="color: #1155cc;">Ur</a> show great promise. Multimethods or its subsuming but immature cousin Predicate Dispatch could be another answer. I do not have enough experience with any of these to have formed a well-informed view on them. </span></span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="font-family: Arial, Helvetica, sans-serif;">Given Paul's work and experience with Scala platform, it's safe to assume that his criticism of Scala collections is very much valid. But <a href="https://twitter.com/extempore2/status/424250929135616000" style="color: #1155cc;">he may not really be criticizing subtyping</a> in particular, as seemingly misinterpreted by many. </span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;">In conclusion, inheritance by itself may not be the culprit. The problem of "selective overriding" is not unique to inheritance. Inheritance has proven to be a useful technique in software development. We should give a careful consideration to the value it adds, the problems it brings, its net utility, and other factors on a case-to-case basis, without unnecessary generalizations. </span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default" style="background-color: white; color: #222222;">
<span style="color: black; font-family: Arial, Helvetica, sans-serif;">Criticism and contrarian opinions are always welcome, but they should be founded on objectivity, careful thought, and right information. Mere passive aggressiveness and loudness does not a valuable opinion make.</span></div>
</div>
</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com3tag:blogger.com,1999:blog-1586964767032798423.post-5690495860565317862014-02-09T03:06:00.000+05:302014-02-09T03:09:33.121+05:30Interesting things this week - iii (2014.02.08)<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
Plenty links this time. Mostly Clojure and Scala libraries, some papers, and some other cool stuff.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial; font-size: small;">
<ol>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Some Zach Tellman libraries</b> - <a href="https://twitter.com/ztellman/status/426165699384311808">https://twitter.com/ztellman/status/426165699384311808</a>.<br /><br />This humorous tweet from Zach Tellman lists a bunch of lovely libraries he has built for Clojure. I believe his tweet was what triggered the <a href="https://twitter.com/search?src=typd&q=%23upworthycs" style="color: #1155cc;">#upworthycs</a> meme, which was popular for a bit in a certain contingent of Twitter.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Om tutorial</b> - <a href="https://github.com/swannodette/om/wiki/Basic-Tutorial">https://github.com/swannodette/om/wiki/Basic-Tutorial</a>, <a href="https://github.com/swannodette/om/wiki/Intermediate-Tutorial">https://github.com/swannodette/om/wiki/Intermediate-Tutorial</a>.<br /><br />Om is the hottest thing in Clojure(script) world these days. It's a CLJS interface for <a href="http://facebook.github.io/react/" style="color: #1155cc;">Facebook's React</a>, which boasts of snapshotting and undoing capabilities, all powered by immutable data structures. Linked here is an in-progress tutorial for Om, written by <a href="http://twitter.com/swannodette" style="color: #1155cc;">David Nolen</a>.<br /><br />Need to play around with Om some time.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Reagent </b>- <a href="http://holmsand.github.io/reagent/">http://holmsand.github.io/reagent/</a>.<br /><br />Another CLJS binding for React. This one claims to be minimalistic.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Sneak peak at RedEyes</b> - <a href="https://gist.github.com/jdegoes/8808245">https://gist.github.com/jdegoes/8808245</a>.<br /><br />After the success of <a href="https://github.com/jdegoes/blueeyes" style="color: #1155cc;">BlueEyes</a>, a lightweight web framework for Scala, John A De Goes is now working on RedEyes. Inferring from the gist, it's going to be something to watch out for.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Composable validations for Play</b> - <a href="http://mandubian.com/2014/01/31/play-rules-shapeless/">http://mandubian.com/2014/01/31/play-rules-shapeless/</a>.<br /><br />Pascal Voitot is a creative fella. After JsZipper, he has been working on composable validations. Play 2.3 is shaping up to be awesome.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Newman</b> - <a href="https://blog.stackmob.com/2013/03/newman/">https://blog.stackmob.com/2013/03/newman/</a>.<br /><br />Stackmob has built a new HTTP client for Scala, based on Finagle's and Spray's implementations.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>µTest </b>- <a href="https://github.com/lihaoyi/utest">https://github.com/lihaoyi/utest</a>.<br /><br />A new macro-based Scala unit testing library. This was long due. Macros allow you to retain some important source/assertion information to produce useful test reports. clojure.test has some good examples. µTest brings that goodness to the Scala land.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Composing contracts, an adventure in finance engineering </b>- <a href="http://research.microsoft.com/en-us/um/people/simonpj/Papers/financial-contracts/contracts-icfp.htm">http://research.microsoft.com/en-us/um/people/simonpj/Papers/financial-contracts/contracts-icfp.htm</a>.<br /><br />In SPJ's own words, "Financial and insurance contracts do not sound like promising territory for functional programming and formal semantics, but in fact we have discovered that insights from programming languages bear directly on the complex subject of describing and valuing a large class of contracts." If not paper, do read the slides. They are compact and give you a taste of how powerful formal semantics can be.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Lua and mixins</b> - <a href="http://notmagi.me/the-power-of-lua-and-mixins/">http://notmagi.me/the-power-of-lua-and-mixins/</a>.<br /><br />All-hashtable languages (with simple enough structures) can be really powerful from extensibility point of view. Lua is one such language, and this article illustrates now.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Clojure ain't no Lisp?</b> - <a href="https://news.ycombinator.com/item?id=7171141">https://news.ycombinator.com/item?id=7171141</a>.<br /><br />A favorite rant of Common Lispers in recent years. Most such debates tend to generate more heat than light, and this one is no exception. But I find it worth sharing for whatever light content it may have.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Wadler's critique of use of Scheme in SICP </b>- <a href="http://www.cs.kent.ac.uk/people/staff/dat/miranda/wadler87.pdf">http://www.cs.kent.ac.uk/people/staff/dat/miranda/wadler87.pdf</a>.<br /><br />In the conclusion section of paper, Phil says, "I embarked upon teaching Lisp with the attitude that the differences from KRC and Miranda would be, at most, a small annoyance. The basic concepts were the same, and I did not feel that the syntax or idiosyncracies of Lisp would be a major barrier. Experience has convinced me otherwise. Although each difficulty by itself is minor, the cumulative effect is significant." I agree, and I think someone should totally write such textbook, using either Haskell or Idris.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Views, A way for pattern matching to cohabit with data abstraction </b>- <a href="http://dl.acm.org/citation.cfm?id=41653">http://dl.acm.org/citation.cfm?id=41653</a>.<br /><br />This is like Scala's extractors, but invented much earlier. Again, in Phil's own words, "(Views) address an important need reconciling pattern matching with data abstraction. In doing so, they also bring a new perspective. Instead of thinking of an abstract data type as hiding a representation, with views we can think of it as exporting as many representations as convenient."<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Why programming is difficult</b> - <a href="http://joearms.github.io/2014/02/07/why-programming-is-difficult.html">http://joearms.github.io/2014/02/07/why-programming-is-difficult.html</a>.<br /><br />A good piece from Joe Armstrong. Read it.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Wolfram's most important technology project yet </b>- <a href="http://blog.stephenwolfram.com/2013/11/something-very-big-is-coming-our-most-important-technology-project-yet/">http://blog.stephenwolfram.com/2013/11/something-very-big-is-coming-our-most-important-technology-project-yet/</a>.<br /><br />I share <a href="http://pchiusano.blogspot.in/2013/05/the-future-of-software-end-of-apps-and.html" style="color: #1155cc;">Paul Chiusano's</a> and <a href="https://groups.google.com/forum/#!msg/reactive-demand/gazxhLLXscQ/RFLHx45lvFQJ" style="color: #1155cc;">David Barbour's</a> dream of, for a lack of better term, different-kind-of-applications. Now I am not too good at Wolframese (a somewhat fluffy dialect of English), but the article seems to suggest that the upcoming Wolfram project is trying to fill a similar void.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Beginning Haskell </b>- <a href="http://www.amazon.com/exec/obidos/ASIN/1430262508/ref=nosim/apre-20">http://www.amazon.com/exec/obidos/ASIN/1430262508/ref=nosim/apre-20</a>.<br /><br />A new Haskell book is out. The content looks attractive, but it seems to do a lot more than just get you started with the language! The word on the street is the book also has a section on Idris. That sounds delicious!<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Microduino</b> - <a href="http://microduino.cc/">http://microduino.cc/</a>.<br /><br />An Arduino stackable that is open source. I imagine for those of you into hardware, this may be an exciting development.</span></li>
</ol>
<div>
<span style="color: black; font-family: arial, helvetica, sans-serif;">Now a couple of interesting not-so-tech links, both about maps. (Don't give me that look. <a href="http://www.youtube.com/user/crashcourse" style="color: #1155cc;">Some of the smartest people around</a> are cartographers!)</span></div>
<div>
<ol>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>A map of Indo-European migrations</b> - <a href="http://indo-european-migrations.scienceontheweb.net/map_of_indo_european_migrations.html">http://indo-european-migrations.scienceontheweb.net/map_of_indo_european_migrations.html</a>.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Maps as an instrument of propaganda</b> - <a href="http://www.geocurrents.info/geonotes/maps-as-an-instrument-of-propaganda-part-1">http://www.geocurrents.info/geonotes/maps-as-an-instrument-of-propaganda-part-1</a>.</span></li>
</ol>
<div>
<span style="color: black; font-family: arial, helvetica, sans-serif;">That's it for the week. See you next time!</span></div>
</div>
</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-78248550369082812782014-02-03T04:27:00.000+05:302014-02-04T13:54:16.530+05:30Interesting things this week - ii (2014.02.01)<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
I was down with severe cold and cough pretty much all of this week, and so have managed to accumulate a lot more goodie links this time. (Yay? Yay!) </div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default">
<ol style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>We are not even trying</b> - <a href="http://scattered-thoughts.net/blog/2014/01/27/were-not-even-trying">http://scattered-thoughts.net/blog/2014/01/27/were-not-even-trying</a><br /><br />This post talks about how "print" debugging is a sign of bygone age, and how we can do better with advanced languages and tools. According to author, "code as data" has a potential to be the biggest enabler of better debugging. And many other things. Look at the last paragraph of the post. It has pointers to so many gems of examples of the sort of things "code as data" can enable. In my opinion, the last paragraph weighs more than the rest of the post! Don't get me wrong. The post is great. It's just that the pointers in last paragraph are so, so exciting!<br /><br />By the way, wondering what those s-expressions are doing in the strings? You may find your answers <a href="https://twitter.com/msimoni/status/427829384888606720" style="color: #1155cc;">here</a>.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Lighttable plugin tutorial</b> - <a href="http://blog.jakubarnold.cz/light-table-plugin-tutorial">http://blog.jakubarnold.cz/light-table-plugin-tutorial</a><br /><br />I mentioned this in passing in my last post in the series. I went through it, but have no immediate willingness to cook up a Lighttable plugin, so didn't retain much in that reading. Based on a second hand account from <a href="https://twitter.com/sumek" style="color: #1155cc;">Aleks</a> though, the tutorial is good, but will leave you wanting for more. That's a good kind of thirst to have. Luckily for you, we can probably expect a wave of Lighttable plugin tutorials being published in near future.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Erik Palmgren's Course on type theory</b> - <a href="http://www.reddit.com/r/dependent_types/comments/1w9p4a/course_on_type_theory_124_pages_of_lecture_notes">http://www.reddit.com/r/dependent_types/comments/1w9p4a/course_on_type_theory_124_pages_of_lecture_notes</a><br /><br />Just had a cursory look. That too only at the lecture notes. Follow at your own peril. (Two kinds of perils here I am talking about: 1. I am no expert on the subject, and don't guarantee the quality of content. 2. The rabbit hole may take you so deep down that you might forgo everything else in your life.)<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Scala LMS</b> - <a href="http://infoscience.epfl.ch/record/150347/files/gpce63-rompf.pdf">http://infoscience.epfl.ch/record/150347/files/gpce63-rompf.pdf</a><br /><br />Compiler optimizations don't have to suck. Let the good folks at EPFL explain to you how! Lightweight modular staging is a novel approach to the problem of optimizations. This paper was first shown to me by <a href="http://mushtaq.github.io/" style="color: #1155cc;">Mushtaq</a>, and I was recently reminded of it thanks to some tweet. (Sorry Mr/Ms Tweeter! I have lost your reference.)<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Collection of Scala macro goodies</b> - <a href="https://github.com/ochafik/Scalaxy">https://github.com/ochafik/Scalaxy</a><br /><br />A collection of nifty macros. Optimized for-loops, nice-ified beans, JavaFX DSL, concise extension methods, and more.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Scala pretty-printing libraries</b> - <a href="https://code.google.com/p/kiama/wiki/PrettyPrinting">https://code.google.com/p/kiama/wiki/PrettyPrinting</a>, <a href="https://github.com/gnieh/gnieh-pp">https://github.com/gnieh/gnieh-pp</a> (via <a href="https://twitter.com/alexey_r/status/428082047056637952" style="color: #1155cc;">`@alexey_r</a>)<br /><br />Somehow pretty-printing doesn't seem to be all that popular in the static typing community. This surprises me. It's good to see some libraries coming up to address this need.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Monoids: Theme and Variations (Functional Pearl)</b> - <a href="http://www.cis.upenn.edu/~byorgey/pub/monoid-pearl.pdf">http://www.cis.upenn.edu/~byorgey/pub/monoid-pearl.pdf</a><br /><br />Fun read. Illustrates with lovely examples how types and algebras can drive your design. Joy, correctness, and a sense of accomplishment are things that you'll receive in the end.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Scala 2.11's name based extractors</b> - <a href="http://hseeberger.github.io/blog/2013/10/04/name-based-extractors-in-scala-2-dot-11/">http://hseeberger.github.io/blog/2013/10/04/name-based-extractors-in-scala-2-dot-11/</a><br /><br />An "extractor" is Scala's attempt at generalizing pattern matching to non-data-constructors. As of version 2.10, any object that defines one (or more) of the following can be used for extraction:<br /><br />def unapply(a: A): Boolean<br />def unapply(a: A): Option[B]<br />def unapplySeq(a: A): Option[Seq[B]]<br /><br />(Where do those A's and B's come from you ask? Well, it doesn't matter. No, really. Scala doesn't care about that and gives you a full liberty with regards to where you can get them from. You could use type parameters from any enclosing scope, type parameters on methods themselves, or even concrete types.)<br /><br />2.11's name based extractors is an attempt to generalize these signatures further. Heiko's article will help you understand how.<br /><br />The generalized form uses the kind of typing which is not quite typing - Desugar things as per rules and then see if the final form compiles. The for-comprehensions work the same way, and I am ambivalent about that.<br /><br />Anyway, this improvement is largely aimed towards performance. You can downright ignore it if you don't care about that.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Scala "corrections" library</b> - <a href="https://thenewcircle.com/s/post/1568/scala_collections_why_not_paul_phillips_video">https://thenewcircle.com/s/post/1568/scala_collections_why_not_paul_phillips_video</a><br /><br />Paul Philips, a valued member of the community, recently decided to walk out of Typesafe. And probably out of the whole Scala landscape. He said he made this decision because he "lost faith". This talk will give you more insight into that. It also has some fair criticism of Scala collections library. A must watch if you do Scala.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Erlang got maps</b> - <a href="http://joearms.github.io/2014/02/01/big-changes-to-erlang.html">http://joearms.github.io/2014/02/01/big-changes-to-erlang.html</a><br /><br />This threw me in utter shock. Your decades old language is getting maps *now*?!<br /><br /><a href="https://twitter.com/lambdadevfr" style="color: #1155cc;">A twitter acquaintance</a> told me Erlangers have been using association lists for the purpose. There also exists a map module, and that's used to. If that's the case, I think it's more fair to say that what Erlang got now is just a literal syntax for maps, with some nifty pattern matching support. That would be less of a shock. Also, the Clojure influences are evident. (To my eyes, at least.)<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>AnyRefMap discussion on Scala Internals mailing list</b> - <a href="https://groups.google.com/forum/#!msg/scala-internals/R4fTU_5XVZs/W47WsAE70LsJ">https://groups.google.com/forum/#!msg/scala-internals/R4fTU_5XVZs/W47WsAE70LsJ</a><br /><br />A very interesting discussion. The theme is use of inheritance in collections (or pretty much anywhere else), the perils of it, and the potential improvements. Also lurking in there somewhere are some best practices to follow when using inheritance.<br /><br />Some seem so pissed that <a href="https://twitter.com/techtangents/status/429527937742688257" style="color: #1155cc;">they're calling for its death</a>, while some think <a href="https://twitter.com/extempore2/status/424250929135616000" style="color: #1155cc;">it isn't really a culprit on its own</a>. My position? I find subtyping simple to conceptualize and build software around. I haven't run into any major problems with it. I'll throw my tantrums if/when I do.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Open Data protocol</b> - <a href="http://msopentech.com/odataorg/introduction">http://msopentech.com/odataorg/introduction</a><br /><br />In their own words (slightly paraphrased), "OData is about providing a uniform way to expose, structure, query and manipulate data using REST practices and JSON or ATOM syntax to describe the payload. It also provides a uniform way to represent metadata about the data, allowing computers to know more about the type system, relationships and structure of the data."<br /><br />What surprised me was that the protocol was first defined by Microsoft, the devil behind many common proprietary formats. Talk about irony. (Or hypocrisy?)<br /><br />The site is down half of the time. What a shame for something centered around HTTP and REST.</span></li>
</ol>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<span style="color: black; font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<span style="color: black; font-family: arial, helvetica, sans-serif;">This got a bit monotonous, right? Here're a couple links to lower the tech quotient and add a different flavor to the post.</span></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<span style="color: black; font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<ol>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>How to stop smoking </b>- <a href="http://existentialcomics.com/comic/13">http://existentialcomics.com/comic/13</a><br /><br />A philosophy comic. Delves into a complex muddle of will power, obedience, and pleasure. The reading will end in one of these: epiphany, annoyance, or mindfuck. (That's how they roll, these philosophy majors.)<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>An exploration into colour symbolism as used by different cultures and religions</b> - <a href="http://ncca.bournemouth.ac.uk/gallery/files/innovations/2006/Dilloway_Laura_16/LauraDillowayInnovations.pdf">http://ncca.bournemouth.ac.uk/gallery/files/innovations/2006/Dilloway_Laura_16/LauraDillowayInnovations.pdf</a><u><br /></u></span><span style="color: black; font-family: arial, helvetica, sans-serif;"><u><br /></u>Colors and symbolisms have fascinated me since childhood. This paper was an interesting read to me. </span></li>
</ol>
<div>
<span style="color: black; font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div>
<span style="color: black; font-family: arial, helvetica, sans-serif;">That's all. Yeah, that was a lot for one week!</span></div>
</div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<span style="color: black; font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<span style="color: black; font-family: arial, helvetica, sans-serif;">In other news, I finally got a hard copy of SICP as a gift. (Thank you, <a href="https://twitter.com/maheshmc2">Mahesh</a> and <a href="http://twitter.com/ivorykoder" style="color: #1155cc;">Bhushan</a>!) I am going to have to take great pains to not tsundoku this book (like many others). Wishing on a star the days would be longer and I would show more commitment.</span></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<span style="color: black; font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWO5H0vpfW9gfaWv4EAUMONvoyfYlwn9CN55CBSiOuM5ZYBrqpYukVnK9apMChztyVf3l_9XTPUGzv14QNzFzrRjUywFz3hcnUiZabQRrnACFHGzJ-mYE3zTx6M_F8ddm0QcxhVbByCH0/s1600/sicp-hb.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWO5H0vpfW9gfaWv4EAUMONvoyfYlwn9CN55CBSiOuM5ZYBrqpYukVnK9apMChztyVf3l_9XTPUGzv14QNzFzrRjUywFz3hcnUiZabQRrnACFHGzJ-mYE3zTx6M_F8ddm0QcxhVbByCH0/s1600/sicp-hb.jpg" /></a></div>
<div style="background-color: white; color: #222222; font-family: arial; font-size: small;">
<span style="color: black; font-family: arial, helvetica, sans-serif;"><br /></span></div>
</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-11605213412218677392014-01-27T01:42:00.003+05:302014-01-27T01:42:32.836+05:30Interesting things this week (2014.01.25)<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
Starting this week, I am going to try an experiment in blogging, where I would write about some of the interesting things I came across in previous week and my thoughts about those. I can't promise to be regular about this, but I am definitely going to try. :-)</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
I have been relatively offline for past some time, so there aren't many items on the list below, but I hope for this to change in near future.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial; font-size: small;">
<ol>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Typed tagless final interpreters</b> - <a href="http://okmij.org/ftp/tagless-final/course/lecture.pdf">http://okmij.org/ftp/tagless-final/course/lecture.pdf</a>. (via <a href="https://twitter.com/deech/status/424336024055971840" style="color: #1155cc;">`@deech</a>.)<br /><br />A typical approach to writing interpreters involves modelling an AST with algebraic data types, and then using pattern matching and combinators to process it. This is very convenient and powerful, but has flaws that we may have missed but which couldn't sweep past Oleg's eyes. :-) This paper discusses an alternate approach where AST nodes are modelled as abstract functions bundled in a module (in this case, a type-class). The paper goes on to show how this approach improves upon the ADT approach, in terms of extensibility, and for making a "computational context" explicit. The latter bit is especially interesting, and to understand it, you are going to have to read the paper.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Typechecking for JQuery</b> - <a href="http://blog.brownplt.org/2014/01/17/typechecking-jquery.html">http://blog.brownplt.org/2014/01/17/typechecking-jquery.html</a>.<br /><br />I have known <i>about</i> dependent types for fairly long now, but still haven't gotten around to exploring them. They are on my list, but they're likely going to have to wait a couple more years. (I am too busy now with err... other stuff.)<br /><br />Nevertheless the post was quite interesting to me. It's good to see the kind of things one can put types to use at.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>Robey Pointer on using Scala code as config</b> - <a href="http://robey.lag.net/2012/03/26/why-config.html">robey.lag.net/2012/03/26/why-config.html</a>.<br /><br />As application grows, configuration needs go on becoming more and more complex. Most configuration formats and libraries of the day show a surprising lack of many features you'd want in configurations. My colleague <a href="http://twitter.com/mushtaqA" style="color: #1155cc;">Mushtaq</a> pointed me to this post by Robey Pointer where he proposes using Scala code as configuration. I am not entirely convinced this is a great idea, but something worth considering surely.<br /><br />On a similar note, Clojure world has come up with <a href="https://github.com/edn-format/edn" style="color: #1155cc;">EDN</a> (extensible data notation). This pursues an opposite goal (kinda): Taking a "data" subset of your programming language (Clojure), and using it to represent configurations. The prime benefit here is syntactic and conceptual congruity between code and configurations.<br /><br /></span></li>
<li><span style="color: black; font-family: arial, helvetica, sans-serif;"><b>F# plugin for Lighttable</b> - <a href="https://github.com/enricosada/LightTable-FSharp/blob/master/src/lt/plugins/fsharp.cljs">https://github.com/enricosada/LightTable-FSharp/blob/master/src/lt/plugins/fsharp.cljs</a>.<br /><br /><a href="https://github.com/LightTable/LightTable" style="color: #1155cc;">Lighttable</a> is written in Clojurescript, and lives up to the Lisp spirit of using it to "create a language in which to write your program". Chris Granger first built a custom object system suitable for his goals (comprising of three main elements which he refers to as "objects", "behaviors", and "tags"), and then built rest of the application on top of it.<br /><br />Apparently this system makes writing plugins for this IDE very easy. There has been a wave of Lighttable plugins. This is one of those. You can find others, for OCaml, Haskell etc, by some googling and githubbing (I would be a teensy bit disappointed if latter isn't a thing yet).<br /><br />Should you feel tempted to write a plugin, here's a tutorial that may get you started - <a href="http://blog.jakubarnold.cz/light-table-plugin-tutorial">http://blog.jakubarnold.cz/light-table-plugin-tutorial</a>. (Warning: Haven't read it myself yet.)<br /></span></li>
</ol>
</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-4358532047982030062014-01-18T18:30:00.000+05:302014-01-18T18:30:31.785+05:30"Params" abstraction for HTTP query parameters <div dir="ltr" style="text-align: left;" trbidi="on">
<div style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px; margin-bottom: 15px;">
<a href="http://www.playframework.com/documentation/2.2.x/ScalaWS" rel="noreferrer" style="color: #4183c4; text-decoration: none;">The Play WS API</a> (like most other HTTP APIs) accepts the query parameters as Seq[(String, String)], a sequence of key-value tuples. This leaves the responsibilities like following to the caller:</div>
<ol style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px; margin: 15px 0px; padding-left: 30px;">
<li>If the parameter value is <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">Int</code>, convert it to a string, and add the parameter to query.</li>
<li>If the parameter value is <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">Option[_]</code>, check if the value is present, add if so, and not otherwise.</li>
<li>Similar for <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">Try[_]</code>. Add if <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">Success[_]</code>, not if <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">Failure[_]</code>.</li>
<li>If the parameter value is a <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">Seq[_]</code>, create a sequence with key paired with each value individually, and concatenate that to the parameters.</li>
</ol>
<div style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px; margin-bottom: 15px; margin-top: 15px;">
This leads to the following kind of code littered everywhere:</div>
<ul style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px; margin: 15px 0px; padding: 0px 0px 0px 30px;">
<li><code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">params ++ views.map("views" -> _) // views is Seq[String]</code></li>
<li><code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">params ++ limit.map(value => "limit" -> value.toString) // limit is Option[Int]</code></li>
<li><code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">params :+ ("locale" -> context.locale.code)</code></li>
</ul>
<div style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px; margin-bottom: 15px; margin-top: 15px;">
To address this problem, I created a data type called Params whose usage looks like follows:</div>
<div class="highlight highlight-scala" style="background-color: white; color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px;">
<pre style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;"><span class="k" style="font-weight: bold;">val</span> <span class="n">params</span> <span class="k" style="font-weight: bold;">=</span> <span class="nc" style="color: #445588; font-weight: bold;">Params</span><span class="o" style="font-weight: bold;">(</span><span class="s" style="color: #dd1144;">"views"</span> <span class="o" style="font-weight: bold;">-></span> <span class="n">views</span><span class="o" style="font-weight: bold;">,</span> <span class="s" style="color: #dd1144;">"limit"</span> <span class="o" style="font-weight: bold;">-></span> <span class="n">limit</span><span class="o" style="font-weight: bold;">,</span> <span class="s" style="color: #dd1144;">"locale"</span> <span class="o" style="font-weight: bold;">-></span> <span class="n">localeContext</span><span class="o" style="font-weight: bold;">)</span>
</pre>
</div>
<div style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px; margin-bottom: 15px; margin-top: 15px;">
which expands to:</div>
<div class="highlight highlight-scala" style="background-color: white; color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px;">
<pre style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;"><span class="k" style="font-weight: bold;">val</span> <span class="n">params</span> <span class="k" style="font-weight: bold;">=</span> <span class="nc" style="color: #445588; font-weight: bold;">Params</span><span class="o" style="font-weight: bold;">(</span>
<span class="nc" style="color: #445588; font-weight: bold;">Param</span><span class="o" style="font-weight: bold;">(</span><span class="s" style="color: #dd1144;">"views"</span><span class="o" style="font-weight: bold;">,</span> <span class="n">views</span><span class="o" style="font-weight: bold;">)(<</span><span class="n">evidence</span> <span class="n">that</span> <span class="nc" style="color: #445588; font-weight: bold;">Seq</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">]</span> <span class="n">can</span> <span class="n">be</span> <span class="n">a</span> <span class="n">parameter</span> <span class="n">value</span><span class="o" style="font-weight: bold;">>),</span>
<span class="nc" style="color: #445588; font-weight: bold;">Param</span><span class="o" style="font-weight: bold;">(</span><span class="s" style="color: #dd1144;">"limit"</span><span class="o" style="font-weight: bold;">,</span> <span class="n">limit</span><span class="o" style="font-weight: bold;">)(<</span><span class="n">evidence</span> <span class="n">that</span> <span class="nc" style="color: #445588; font-weight: bold;">Option</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">Int</span><span class="o" style="font-weight: bold;">]</span> <span class="n">can</span> <span class="n">be</span> <span class="n">a</span> <span class="n">parameter</span> <span class="n">value</span><span class="o" style="font-weight: bold;">>),</span>
<span class="nc" style="color: #445588; font-weight: bold;">Param</span><span class="o" style="font-weight: bold;">(</span><span class="s" style="color: #dd1144;">"locale"</span><span class="o" style="font-weight: bold;">,</span> <span class="n">localeContext</span><span class="o" style="font-weight: bold;">)(<</span><span class="n">evidence</span> <span class="n">that</span> <span class="nc" style="color: #445588; font-weight: bold;">LocaleContext</span> <span class="n">can</span> <span class="n">be</span> <span class="n">a</span> <span class="n">parameter</span> <span class="n">value</span><span class="o" style="font-weight: bold;">>)</span>
<span class="o" style="font-weight: bold;">)</span>
</pre>
</div>
<div style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px; margin-bottom: 15px; margin-top: 15px;">
<code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">Params("views" -> Seq("basic", "price"), "limit" -> Some(4), "q" -> None).value</code> evaluates to<code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">Seq("views" -> "basic", "views" -> "price", "limit" -> "4")</code>.</div>
<div style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px; margin-bottom: 15px; margin-top: 15px;">
The evidence parameters here, evidently, also encapsulate the details of how a value of some data type should be dealt with when being attached to query parameters.</div>
<div style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px; margin-bottom: 15px; margin-top: 15px;">
The benefits with this approach:</div>
<ol style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px; margin: 15px 0px; padding-left: 30px;">
<li>How various data types are dealt with when being translated to query parameters is now abstracted away. This leads to clearer separation of concerns, and DRY.</li>
<li>It is typesafe. <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">Param("q" -> SomeRandomObject)</code> for example will lead to a compiler error saying<code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">SomeRandomObject</code> cannot be used as a parameter value. (Unless you add a <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">CanBeParamValue[_]</code> instance for it.)</li>
</ol>
<div style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px; margin-bottom: 15px; margin-top: 15px;">
You can find the full implementation below:</div>
<div class="highlight highlight-scala" style="background-color: white; color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px;">
<pre style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;"><span class="k" style="font-weight: bold;">import</span> <span class="nn" style="color: #555555;">annotation.implicitNotFound</span>
<span class="k" style="font-weight: bold;">import</span> <span class="nn" style="color: #555555;">language.implicitConversions</span>
<span class="k" style="font-weight: bold;">import</span> <span class="nn" style="color: #555555;">scala.util.</span><span class="o" style="font-weight: bold;">{</span><span class="nc" style="color: #445588; font-weight: bold;">Failure</span><span class="o" style="font-weight: bold;">,</span> <span class="nc" style="color: #445588; font-weight: bold;">Success</span><span class="o" style="font-weight: bold;">,</span> <span class="nc" style="color: #445588; font-weight: bold;">Try</span><span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">case</span> <span class="k" style="font-weight: bold;">class</span> <span class="nc" style="color: #445588; font-weight: bold;">Params</span><span class="o" style="font-weight: bold;">(</span><span class="n">ps</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Param*</span><span class="o" style="font-weight: bold;">)</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">lazy</span> <span class="k" style="font-weight: bold;">val</span> <span class="n">value</span> <span class="k" style="font-weight: bold;">=</span> <span class="n">ps</span><span class="o" style="font-weight: bold;">.</span><span class="n">foldLeft</span><span class="o" style="font-weight: bold;">(</span><span class="nc" style="color: #445588; font-weight: bold;">Vector</span><span class="o" style="font-weight: bold;">.</span><span class="n">empty</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Seq</span><span class="o" style="font-weight: bold;">[(</span><span class="kt" style="color: #445588; font-weight: bold;">String</span>, <span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">)])</span> <span class="o" style="font-weight: bold;">{</span> <span class="o" style="font-weight: bold;">(</span><span class="n">r</span><span class="o" style="font-weight: bold;">,</span> <span class="n">c</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=></span> <span class="n">c</span><span class="o" style="font-weight: bold;">.</span><span class="n">attachTo</span><span class="o" style="font-weight: bold;">(</span><span class="n">r</span><span class="o" style="font-weight: bold;">)</span> <span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">override</span> <span class="k" style="font-weight: bold;">def</span> <span class="n">toString</span> <span class="k" style="font-weight: bold;">=</span> <span class="n">s</span><span class="s" style="color: #dd1144;">"Params(${ps.mkString("</span><span class="o" style="font-weight: bold;">,</span> <span class="s" style="color: #dd1144;">")})"</span>
<span class="k" style="font-weight: bold;">override</span> <span class="k" style="font-weight: bold;">def</span> <span class="n">equals</span><span class="o" style="font-weight: bold;">(</span><span class="n">that</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Any</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=</span> <span class="n">that</span> <span class="k" style="font-weight: bold;">match</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">case</span> <span class="n">that</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Params</span> <span class="o" style="font-weight: bold;">=></span> <span class="k" style="font-weight: bold;">this</span><span class="o" style="font-weight: bold;">.</span><span class="n">value</span> <span class="o" style="font-weight: bold;">==</span> <span class="n">that</span><span class="o" style="font-weight: bold;">.</span><span class="n">value</span>
<span class="k" style="font-weight: bold;">case</span> <span class="k" style="font-weight: bold;">_</span> <span class="k" style="font-weight: bold;">=></span> <span class="kc" style="font-weight: bold;">false</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">def</span> <span class="o" style="font-weight: bold;">++(</span><span class="n">that</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Params</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=</span> <span class="nc" style="color: #445588; font-weight: bold;">Params</span><span class="o" style="font-weight: bold;">((</span><span class="n">ps</span> <span class="o" style="font-weight: bold;">++</span> <span class="n">that</span><span class="o" style="font-weight: bold;">.</span><span class="n">ps</span><span class="o" style="font-weight: bold;">)</span><span class="k" style="font-weight: bold;">:</span> <span class="k" style="font-weight: bold;">_</span><span class="kt" style="color: #445588; font-weight: bold;">*</span><span class="o" style="font-weight: bold;">)</span>
<span class="k" style="font-weight: bold;">def</span> <span class="o" style="font-weight: bold;">:+(</span><span class="n">p</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Param</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=</span> <span class="nc" style="color: #445588; font-weight: bold;">Params</span><span class="o" style="font-weight: bold;">((</span><span class="n">ps</span> <span class="o" style="font-weight: bold;">:+</span> <span class="n">p</span><span class="o" style="font-weight: bold;">)</span><span class="k" style="font-weight: bold;">:</span> <span class="k" style="font-weight: bold;">_</span><span class="kt" style="color: #445588; font-weight: bold;">*</span><span class="o" style="font-weight: bold;">)</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">object</span> <span class="nc" style="color: #445588; font-weight: bold;">Params</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">val</span> <span class="n">empty</span> <span class="k" style="font-weight: bold;">=</span> <span class="nc" style="color: #445588; font-weight: bold;">Params</span><span class="o" style="font-weight: bold;">()</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">abstract</span> <span class="k" style="font-weight: bold;">class</span> <span class="nc" style="color: #445588; font-weight: bold;">Param</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">def</span> <span class="n">key</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">String</span>
<span class="k" style="font-weight: bold;">type</span> <span class="kt" style="color: #445588; font-weight: bold;">V</span>
<span class="k" style="font-weight: bold;">def</span> <span class="n">value</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">V</span>
<span class="k" style="font-weight: bold;">def</span> <span class="n">evidence</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">CanBeParamValue</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">]</span>
<span class="k" style="font-weight: bold;">def</span> <span class="n">attachTo</span><span class="o" style="font-weight: bold;">(</span><span class="n">ts</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Seq</span><span class="o" style="font-weight: bold;">[(</span><span class="kt" style="color: #445588; font-weight: bold;">String</span>, <span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">)])</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Seq</span><span class="o" style="font-weight: bold;">[(</span><span class="kt" style="color: #445588; font-weight: bold;">String</span>, <span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">)]</span> <span class="k" style="font-weight: bold;">=</span> <span class="o" style="font-weight: bold;">{</span>
<span class="n">evidence</span><span class="o" style="font-weight: bold;">.</span><span class="n">attach</span><span class="o" style="font-weight: bold;">(</span><span class="n">ts</span><span class="o" style="font-weight: bold;">,</span> <span class="n">key</span><span class="o" style="font-weight: bold;">,</span> <span class="n">value</span><span class="o" style="font-weight: bold;">)</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">override</span> <span class="k" style="font-weight: bold;">def</span> <span class="n">toString</span> <span class="k" style="font-weight: bold;">=</span> <span class="n">s</span><span class="s" style="color: #dd1144;">"$key -> $value"</span>
<span class="k" style="font-weight: bold;">override</span> <span class="k" style="font-weight: bold;">def</span> <span class="n">equals</span><span class="o" style="font-weight: bold;">(</span><span class="n">that</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Any</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=</span> <span class="n">that</span> <span class="k" style="font-weight: bold;">match</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">case</span> <span class="n">that</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Param</span> <span class="o" style="font-weight: bold;">=></span> <span class="k" style="font-weight: bold;">this</span><span class="o" style="font-weight: bold;">.</span><span class="n">key</span> <span class="o" style="font-weight: bold;">==</span> <span class="n">that</span><span class="o" style="font-weight: bold;">.</span><span class="n">key</span> <span class="o" style="font-weight: bold;">&&</span> <span class="k" style="font-weight: bold;">this</span><span class="o" style="font-weight: bold;">.</span><span class="n">value</span> <span class="o" style="font-weight: bold;">==</span> <span class="n">that</span><span class="o" style="font-weight: bold;">.</span><span class="n">value</span>
<span class="k" style="font-weight: bold;">case</span> <span class="k" style="font-weight: bold;">_</span> <span class="k" style="font-weight: bold;">=></span> <span class="kc" style="font-weight: bold;">false</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">object</span> <span class="nc" style="color: #445588; font-weight: bold;">Param</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">def</span> <span class="n">apply</span><span class="o" style="font-weight: bold;">[</span><span class="k" style="font-weight: bold;">_</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">](</span><span class="nc" style="color: #445588; font-weight: bold;">_key</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">,</span> <span class="nc" style="color: #445588; font-weight: bold;">_value</span><span class="k" style="font-weight: bold;">:</span> <span class="k" style="font-weight: bold;">_</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">)(</span><span class="k" style="font-weight: bold;">implicit</span> <span class="nc" style="color: #445588; font-weight: bold;">_evidence</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">CanBeParamValue</span><span class="o" style="font-weight: bold;">[</span><span class="k" style="font-weight: bold;">_</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">])</span> <span class="k" style="font-weight: bold;">=</span> <span class="k" style="font-weight: bold;">new</span> <span class="nc" style="color: #445588; font-weight: bold;">Param</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">def</span> <span class="n">key</span> <span class="k" style="font-weight: bold;">=</span> <span class="nc" style="color: #445588; font-weight: bold;">_key</span>
<span class="k" style="font-weight: bold;">type</span> <span class="kt" style="color: #445588; font-weight: bold;">V</span> <span class="o" style="font-weight: bold;">=</span> <span class="nc" style="color: #445588; font-weight: bold;">_V</span>
<span class="k" style="font-weight: bold;">def</span> <span class="n">value</span> <span class="k" style="font-weight: bold;">=</span> <span class="nc" style="color: #445588; font-weight: bold;">_value</span>
<span class="k" style="font-weight: bold;">def</span> <span class="n">evidence</span> <span class="k" style="font-weight: bold;">=</span> <span class="nc" style="color: #445588; font-weight: bold;">_evidence</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">implicit</span> <span class="k" style="font-weight: bold;">def</span> <span class="n">pairToParam</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">](</span><span class="n">pair</span><span class="k" style="font-weight: bold;">:</span> <span class="o" style="font-weight: bold;">(</span><span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">,</span> <span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">))(</span><span class="k" style="font-weight: bold;">implicit</span> <span class="n">evidence</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">CanBeParamValue</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">])</span> <span class="k" style="font-weight: bold;">=</span> <span class="o" style="font-weight: bold;">{</span>
<span class="n">pair</span> <span class="k" style="font-weight: bold;">match</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">case</span> <span class="o" style="font-weight: bold;">(</span><span class="n">key</span><span class="o" style="font-weight: bold;">,</span> <span class="n">value</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=></span> <span class="nc" style="color: #445588; font-weight: bold;">Param</span><span class="o" style="font-weight: bold;">(</span><span class="n">key</span><span class="o" style="font-weight: bold;">,</span> <span class="n">value</span><span class="o" style="font-weight: bold;">)</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="nd">@implicitNotFound</span><span class="o" style="font-weight: bold;">(</span><span class="s" style="color: #dd1144;">"An object of type ${V} cannot be used as a parameter value in a gateway call."</span><span class="o" style="font-weight: bold;">)</span>
<span class="k" style="font-weight: bold;">trait</span> <span class="nc" style="color: #445588; font-weight: bold;">CanBeParamValue</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">-V</span><span class="o" style="font-weight: bold;">]</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">def</span> <span class="n">attach</span><span class="o" style="font-weight: bold;">(</span><span class="n">ts</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Seq</span><span class="o" style="font-weight: bold;">[(</span><span class="kt" style="color: #445588; font-weight: bold;">String</span>, <span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">)],</span> <span class="n">key</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">,</span> <span class="n">value</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">)</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Seq</span><span class="o" style="font-weight: bold;">[(</span><span class="kt" style="color: #445588; font-weight: bold;">String</span>, <span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">)]</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">object</span> <span class="nc" style="color: #445588; font-weight: bold;">CanBeParamValue</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">def</span> <span class="n">instance</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">](</span><span class="nc" style="color: #445588; font-weight: bold;">_attach</span><span class="k" style="font-weight: bold;">:</span> <span class="o" style="font-weight: bold;">(</span><span class="kt" style="color: #445588; font-weight: bold;">Seq</span><span class="o" style="font-weight: bold;">[(</span><span class="kt" style="color: #445588; font-weight: bold;">String</span>, <span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">)],</span> <span class="nc" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">,</span> <span class="n">V</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=></span> <span class="nc" style="color: #445588; font-weight: bold;">Seq</span><span class="o" style="font-weight: bold;">[(</span><span class="kt" style="color: #445588; font-weight: bold;">String</span>, <span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">)])</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">CanBeParamValue</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">]</span> <span class="k" style="font-weight: bold;">=</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">new</span> <span class="nc" style="color: #445588; font-weight: bold;">CanBeParamValue</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">]</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">def</span> <span class="n">attach</span><span class="o" style="font-weight: bold;">(</span><span class="n">ts</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Seq</span><span class="o" style="font-weight: bold;">[(</span><span class="kt" style="color: #445588; font-weight: bold;">String</span>, <span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">)],</span> <span class="n">key</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">,</span> <span class="n">value</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">)</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">Seq</span><span class="o" style="font-weight: bold;">[(</span><span class="kt" style="color: #445588; font-weight: bold;">String</span>, <span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">)]</span> <span class="k" style="font-weight: bold;">=</span> <span class="o" style="font-weight: bold;">{</span>
<span class="nc" style="color: #445588; font-weight: bold;">_attach</span><span class="o" style="font-weight: bold;">(</span><span class="n">ts</span><span class="o" style="font-weight: bold;">,</span> <span class="n">key</span><span class="o" style="font-weight: bold;">,</span> <span class="n">value</span><span class="o" style="font-weight: bold;">)</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">implicit</span> <span class="k" style="font-weight: bold;">val</span> <span class="n">stringCanBeParamValue</span> <span class="k" style="font-weight: bold;">=</span> <span class="o" style="font-weight: bold;">{</span>
<span class="n">instance</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">]</span> <span class="o" style="font-weight: bold;">{</span> <span class="o" style="font-weight: bold;">(</span><span class="n">ts</span><span class="o" style="font-weight: bold;">,</span> <span class="n">key</span><span class="o" style="font-weight: bold;">,</span> <span class="n">value</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=></span>
<span class="n">ts</span> <span class="o" style="font-weight: bold;">:+</span> <span class="o" style="font-weight: bold;">(</span><span class="n">key</span> <span class="o" style="font-weight: bold;">-></span> <span class="n">value</span><span class="o" style="font-weight: bold;">)</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">implicit</span> <span class="k" style="font-weight: bold;">val</span> <span class="n">intCanBeParamValue</span> <span class="k" style="font-weight: bold;">=</span> <span class="o" style="font-weight: bold;">{</span>
<span class="n">instance</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">Int</span><span class="o" style="font-weight: bold;">]</span> <span class="o" style="font-weight: bold;">{</span> <span class="o" style="font-weight: bold;">(</span><span class="n">ts</span><span class="o" style="font-weight: bold;">,</span> <span class="n">key</span><span class="o" style="font-weight: bold;">,</span> <span class="n">value</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=></span>
<span class="n">ts</span> <span class="o" style="font-weight: bold;">:+</span> <span class="o" style="font-weight: bold;">(</span><span class="n">key</span> <span class="o" style="font-weight: bold;">-></span> <span class="n">value</span><span class="o" style="font-weight: bold;">.</span><span class="n">toString</span><span class="o" style="font-weight: bold;">)</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">implicit</span> <span class="k" style="font-weight: bold;">val</span> <span class="n">stringSeqCanBeParamValue</span> <span class="k" style="font-weight: bold;">=</span> <span class="o" style="font-weight: bold;">{</span>
<span class="n">instance</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">Seq</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">String</span><span class="o" style="font-weight: bold;">]]</span> <span class="o" style="font-weight: bold;">{</span> <span class="o" style="font-weight: bold;">(</span><span class="n">ts</span><span class="o" style="font-weight: bold;">,</span> <span class="n">key</span><span class="o" style="font-weight: bold;">,</span> <span class="n">values</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=></span>
<span class="n">ts</span> <span class="o" style="font-weight: bold;">++</span> <span class="n">values</span><span class="o" style="font-weight: bold;">.</span><span class="n">map</span><span class="o" style="font-weight: bold;">(</span><span class="n">key</span> <span class="o" style="font-weight: bold;">-></span> <span class="k" style="font-weight: bold;">_</span><span class="o" style="font-weight: bold;">)</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">implicit</span> <span class="k" style="font-weight: bold;">def</span> <span class="n">optionCanBeParamValue</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">](</span><span class="k" style="font-weight: bold;">implicit</span> <span class="n">evidence</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">CanBeParamValue</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">])</span> <span class="k" style="font-weight: bold;">=</span> <span class="o" style="font-weight: bold;">{</span>
<span class="n">instance</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">Option</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">]]</span> <span class="o" style="font-weight: bold;">{</span> <span class="o" style="font-weight: bold;">(</span><span class="n">ts</span><span class="o" style="font-weight: bold;">,</span> <span class="n">key</span><span class="o" style="font-weight: bold;">,</span> <span class="n">maybeValue</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=></span>
<span class="n">maybeValue</span> <span class="k" style="font-weight: bold;">match</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">case</span> <span class="nc" style="color: #445588; font-weight: bold;">Some</span><span class="o" style="font-weight: bold;">(</span><span class="n">value</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=></span> <span class="n">evidence</span><span class="o" style="font-weight: bold;">.</span><span class="n">attach</span><span class="o" style="font-weight: bold;">(</span><span class="n">ts</span><span class="o" style="font-weight: bold;">,</span> <span class="n">key</span><span class="o" style="font-weight: bold;">,</span> <span class="n">value</span><span class="o" style="font-weight: bold;">)</span>
<span class="k" style="font-weight: bold;">case</span> <span class="nc" style="color: #445588; font-weight: bold;">None</span> <span class="k" style="font-weight: bold;">=></span> <span class="n">ts</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="k" style="font-weight: bold;">implicit</span> <span class="k" style="font-weight: bold;">def</span> <span class="n">tryCanBeParamValue</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">](</span><span class="k" style="font-weight: bold;">implicit</span> <span class="n">evidence</span><span class="k" style="font-weight: bold;">:</span> <span class="kt" style="color: #445588; font-weight: bold;">CanBeParamValue</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">])</span> <span class="k" style="font-weight: bold;">=</span> <span class="o" style="font-weight: bold;">{</span>
<span class="n">instance</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">Try</span><span class="o" style="font-weight: bold;">[</span><span class="kt" style="color: #445588; font-weight: bold;">V</span><span class="o" style="font-weight: bold;">]]</span> <span class="o" style="font-weight: bold;">{</span> <span class="o" style="font-weight: bold;">(</span><span class="n">ts</span><span class="o" style="font-weight: bold;">,</span> <span class="n">key</span><span class="o" style="font-weight: bold;">,</span> <span class="n">tryValue</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=></span>
<span class="n">tryValue</span> <span class="k" style="font-weight: bold;">match</span> <span class="o" style="font-weight: bold;">{</span>
<span class="k" style="font-weight: bold;">case</span> <span class="nc" style="color: #445588; font-weight: bold;">Success</span><span class="o" style="font-weight: bold;">(</span><span class="n">value</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=></span> <span class="n">evidence</span><span class="o" style="font-weight: bold;">.</span><span class="n">attach</span><span class="o" style="font-weight: bold;">(</span><span class="n">ts</span><span class="o" style="font-weight: bold;">,</span> <span class="n">key</span><span class="o" style="font-weight: bold;">,</span> <span class="n">value</span><span class="o" style="font-weight: bold;">)</span>
<span class="k" style="font-weight: bold;">case</span> <span class="nc" style="color: #445588; font-weight: bold;">Failure</span><span class="o" style="font-weight: bold;">(</span><span class="k" style="font-weight: bold;">_</span><span class="o" style="font-weight: bold;">)</span> <span class="k" style="font-weight: bold;">=></span> <span class="n">ts</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="o" style="font-weight: bold;">}</span>
<span class="o" style="font-weight: bold;">}</span>
</pre>
</div>
<div style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 22.100000381469727px; margin-top: 15px;">
Cheers!</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-4307996884349509902014-01-02T23:40:00.000+05:302014-01-02T23:40:54.674+05:30Partial functions for Clojure<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25px; margin-bottom: 15px;">
I happen to be one of the people who think Scala's <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: normal; margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">PartialFunction</code> is pretty cool. I was missing it in Clojure, so I went ahead, and created this project - <a href="https://github.com/missingfaktor/partial-fn" rel="noreferrer" style="color: #4183c4; text-decoration: none;">https://github.com/missingfaktor/partial-fn</a>. The README describes the motivation for the project, currently implemented functionality, and possible future directions. I have tried to keep the document as descriptive and as understandable as possible.</div>
<div style="font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25px; margin-bottom: 15px; margin-top: 15px;">
The current implementation is fairly straightforward. It essentially performs the following transformations:</div>
<div class="highlight" style="background-color: white; border: 0px; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25px; padding: 0px;">
<pre style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 13px; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;"><span class="p">(</span><span class="nf" style="color: #990000; font-weight: bold;">partial-fn</span> <span class="p">[</span><span class="nv" style="color: teal;">x</span> <span class="nv" style="color: teal;">y</span> <span class="nv" style="color: teal;">z</span><span class="p">]</span>
<span class="p">[</span><span class="mi" style="color: #009999;">4</span> <span class="mi" style="color: #009999;">5</span> <span class="nv" style="color: teal;">_</span><span class="p">]</span> <span class="mi" style="color: #009999;">4</span>
<span class="p">[</span><span class="mi" style="color: #009999;">1</span> <span class="mi" style="color: #009999;">2</span> <span class="ss" style="color: #990073;">:a</span><span class="p">]</span> <span class="mi" style="color: #009999;">9</span><span class="p">)</span>
<span class="c1" style="color: #999988; font-style: italic;">; becomes</span>
<span class="p">(</span><span class="k" style="font-weight: bold;">fn </span><span class="p">[</span><span class="nv" style="color: teal;">x</span> <span class="nv" style="color: teal;">y</span> <span class="nv" style="color: teal;">z</span><span class="p">]</span>
<span class="p">(</span><span class="nf" style="color: #990000; font-weight: bold;">match</span> <span class="p">[</span><span class="nv" style="color: teal;">x</span> <span class="nv" style="color: teal;">y</span> <span class="nv" style="color: teal;">z</span><span class="p">]</span>
<span class="p">[</span><span class="mi" style="color: #009999;">4</span> <span class="mi" style="color: #009999;">5</span> <span class="nv" style="color: teal;">_</span><span class="p">]</span> <span class="mi" style="color: #009999;">4</span>
<span class="p">[</span><span class="mi" style="color: #009999;">1</span> <span class="mi" style="color: #009999;">2</span> <span class="ss" style="color: #990073;">:a</span><span class="p">]</span> <span class="mi" style="color: #009999;">9</span><span class="p">))</span>
<span class="c1" style="color: #999988; font-style: italic;">; becomes</span>
<span class="p">{</span><span class="ss" style="color: #990073;">:fun</span> <span class="p">(</span><span class="k" style="font-weight: bold;">fn </span><span class="p">[</span><span class="nv" style="color: teal;">x</span> <span class="nv" style="color: teal;">y</span> <span class="nv" style="color: teal;">z</span><span class="p">]</span>
<span class="p">(</span><span class="nf" style="color: #990000; font-weight: bold;">match</span> <span class="p">[</span><span class="nv" style="color: teal;">x</span> <span class="nv" style="color: teal;">y</span> <span class="nv" style="color: teal;">z</span><span class="p">]</span>
<span class="p">[</span><span class="mi" style="color: #009999;">4</span> <span class="mi" style="color: #009999;">5</span> <span class="nv" style="color: teal;">_</span><span class="p">]</span> <span class="mi" style="color: #009999;">4</span>
<span class="p">[</span><span class="mi" style="color: #009999;">1</span> <span class="mi" style="color: #009999;">2</span> <span class="ss" style="color: #990073;">:a</span><span class="p">]</span> <span class="mi" style="color: #009999;">9</span><span class="p">))</span>
<span class="ss" style="color: #990073;">:in-domain?</span> <span class="p">(</span><span class="k" style="font-weight: bold;">fn </span><span class="p">[</span><span class="nv" style="color: teal;">x</span> <span class="nv" style="color: teal;">y</span> <span class="nv" style="color: teal;">z</span><span class="p">]</span>
<span class="p">(</span><span class="nf" style="color: #990000; font-weight: bold;">match</span> <span class="p">[</span><span class="nv" style="color: teal;">x</span> <span class="nv" style="color: teal;">y</span> <span class="nv" style="color: teal;">z</span><span class="p">]</span>
<span class="p">[</span><span class="mi" style="color: #009999;">4</span> <span class="mi" style="color: #009999;">5</span> <span class="nv" style="color: teal;">_</span><span class="p">]</span> <span class="nv" style="color: teal;">true</span>
<span class="p">[</span><span class="mi" style="color: #009999;">1</span> <span class="mi" style="color: #009999;">2</span> <span class="ss" style="color: #990073;">:a</span><span class="p">]</span> <span class="nv" style="color: teal;">true</span>
<span class="ss" style="color: #990073;">:else</span> <span class="nv" style="color: teal;">false</span><span class="p">))}</span>
</pre>
</div>
<div style="font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25px; margin-bottom: 15px; margin-top: 15px;">
Of course there is a bit more involved, but this is the crux of it.</div>
<div style="font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25px; margin-bottom: 15px; margin-top: 15px;">
It only took a few hours to implement this, but a type system and a greater prowess with Lisp macros would have helped me get there even faster.</div>
<div style="font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25px; margin-bottom: 15px; margin-top: 15px;">
Fork away!</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-69027251657454503372013-12-01T17:20:00.001+05:302013-12-01T17:21:49.905+05:30Optional-implicit trick in Scala<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
Scala's implicit parameters are an extremely powerful beast. They encode Haskell's type-classes and instances, and by the virtue of being first-class values, enable some really cool tricks. We will see one such trick today. </div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
Failure in implicit resolution is a compile time failure. Once in a while, you may encounter a use case, where you might want to say, "If the implicit is available, do X. Else do Y." </div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
We can do this with following little data type and implicit provider:</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
<pre class="" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span class="" style="color: #008800; font-weight: bold;">case</span> <span class="" style="color: #008800; font-weight: bold;">class</span> <span class="">Perhaps</span><span class="">[</span><span class="">E</span><span class="">]</span><span class="">(</span><span class="">value</span><span class="">:</span> <span class="">Option</span><span class="">[</span><span class="">E</span><span class="">]</span><span class="">)</span> <span class="">{</span>
<span class="" style="color: #008800; font-weight: bold;">def</span> <span class="">fold</span><span class="">[</span><span class="">F</span><span class="">]</span><span class="">(</span><span class="">ifAbsent</span><span class="">:</span> <span class="">=</span><span class="">></span> <span class="">F</span><span class="">)</span><span class="">(</span><span class="">ifPresent</span><span class="">:</span> <span class="">E</span> <span class="">=</span><span class="">></span> <span class="">F</span><span class="">)</span><span class="">:</span> <span class="">F</span> <span class="">=</span> <span class="">{</span>
value.fold<span class="">(</span>ifAbsent<span class="">)</span><span class="">(</span>ifPresent<span class="">)</span>
<span class="">}</span>
<span class="">}</span>
<span class="">implicit</span> <span class="" style="color: #008800; font-weight: bold;">def</span> <span class="">perhaps</span><span class="">[</span><span class="">E</span><span class="">]</span><span class="">(</span><span class="">implicit</span> <span class="">ev</span><span class="">:</span> <span class="">E</span> <span class="">=</span> <span class="" style="color: #003388; font-weight: bold;">null</span><span class="">)</span><span class="">:</span> <span class="">Perhaps</span><span class="">[</span><span class="">E</span><span class="">]</span> <span class="">=</span> <span class="">{</span>
<span class="">Perhaps</span><span class="">(</span><span class="">Option</span><span class="">(</span>ev<span class="">)</span><span class="">)</span>
<span class="">}</span></pre>
</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
'Perhaps' is fully isomorphic to 'Option'. Then why bother creating a new type at all? It's because we do not want to introduce into scope implicit instances of a very commonly used type such as 'Option'. </div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
The implicit provider defined combines Scala's implicits and default arguments in a creative way to meet our end.</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
Sample use:</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif; font-size: small;">
<pre class="" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span class="" style="color: #008800; font-weight: bold;">def</span> <span class="">convertToJson</span><span class="">[</span><span class="">A</span><span class="">]</span><span class="">(</span><span class="">a</span><span class="">:</span> <span class="">A</span><span class="">)</span><span class="">(</span><span class="">implicit</span> <span class="">pf</span><span class="">:</span> <span class="">Perhaps</span><span class="">[</span><span class="">Format</span><span class="">[</span><span class="">A</span><span class="">]</span><span class="">]</span><span class="">)</span><span class="">:</span> <span class="">JsValue</span> <span class="">=</span> <span class="">{</span>
pf.fold<span class="">[</span><span class="">JsValue</span><span class="">]</span> <span class="">{</span>
println<span class="">(</span><span class="" style="color: #dd2200;">"oops"</span><span class="">)</span>
<span class="">JsNull</span>
<span class="">}</span> <span class="">{</span> <span class="">implicit</span> ev <span class="">=</span><span class="">></span>
<span class="">Json</span>.toJson<span class="">(</span>a<span class="">)</span>
<span class="">}</span>
<span class="">}</span><span style="font-family: arial, helvetica, sans-serif; line-height: normal;"></span></pre>
</div>
<div style="color: #222222; font-family: arial; font-size: small;">
<div class="gmail_default" style="color: black; font-family: arial, helvetica, sans-serif;">
<i><br /></i></div>
<div class="gmail_default" style="color: black; font-family: arial, helvetica, sans-serif;">
<i>(I originally posted this to <a href="http://stackoverflow.com/a/20016152/192247" style="color: #1155cc;">this thread on stackoverflow</a>. Copying it here because I find it worthy of sharing more.)</i></div>
<div>
<i><br /></i></div>
</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-78868747881417574722013-10-02T15:22:00.000+05:302013-10-02T15:35:00.793+05:30Understanding monads<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
(<i>On September 23rd, 2013, <a href="http://twitter.com/sumek" style="color: #1155cc;" target="_blank">Aleksander Sumowski</a> and I gave a talk on monads at Developer Meetup, ThoughtWorks, Pune. This post is a transcript of that talk.)</i></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<i><br /></i></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
I have come across many people who are somewhat familiar with functional programming but have had a hard time understanding the idea of "monads". I believe monads is a simple concept and the intent of this talk is to provide an intuition for this concept. (Don't worry if you haven't heard of monads before. You might still learn something from this talk.)</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
I will try to motivate the case for monads with some day to day code examples. The language used for examples is Scala.</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b>Example 1: Presence or absence of a value</b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b><br /></b></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">You are given a string. You have to look up this string in a map named </span><span style="font-family: courier new, monospace;">foo</span><span style="font-family: arial, helvetica, sans-serif;">. The length of the value obtained is to be used as a key in another map, named </span><span style="font-family: courier new, monospace;">bar</span><span style="font-family: arial, helvetica, sans-serif;">, to get the final value. </span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
This is how you might do it:</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 1.1</span>
<span style="color: #008800; font-weight: bold;">import</span> java.{util <span style="color: #008800; font-weight: bold;">=></span> ju}</pre>
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #008800; font-weight: bold;">import</span> scala.collection.<wbr></wbr>JavaConverters._</pre>
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"></pre>
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #008800; font-weight: bold;">val</span> fooJ: ju.Map[<span style="color: #008800; font-weight: bold;">String</span>, <span style="color: #008800; font-weight: bold;">String</span>] = Map(<span style="color: #dd2200;">"a"</span> -> <span style="color: #dd2200;">"xoxox"</span>, <span style="color: #dd2200;">"b"</span> -> <span style="color: #dd2200;">"xoxo"</span>).asJava
<span style="color: #008800; font-weight: bold;">val</span> barJ: ju.Map[<span style="color: #008800; font-weight: bold;">Int</span>, <span style="color: #008800; font-weight: bold;">String</span>] = Map(<span style="color: #0000dd; font-weight: bold;">4</span> -> <span style="color: #dd2200;">"P"</span>, <span style="color: #0000dd; font-weight: bold;">5</span> -> <span style="color: #dd2200;">"Q"</span>).asJava
<span style="color: #008800; font-weight: bold;">def</span> calc(s: <span style="color: #008800; font-weight: bold;">String</span>): <span style="color: #008800; font-weight: bold;">String</span> = {
<span style="color: #008800; font-weight: bold;">val</span> x = fooJ.get(s)
<span style="color: #008800; font-weight: bold;">val</span> y = barJ.get(x.length)
y
}</pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">But wait! This code is incorrect. What if the key is missing in the first map itself? In that case, the map will return </span><span style="font-family: courier new, monospace;">null</span><span style="font-family: arial, helvetica, sans-serif;">, leading to a </span><span style="font-family: courier new, monospace;">NullPointerException</span><span style="font-family: arial, helvetica, sans-serif;"> on next operation. </span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">Clearly we need something that guards us against </span><span style="font-family: courier new, monospace;">null</span><span style="font-family: arial, helvetica, sans-serif;">. So we add an </span><span style="font-family: courier new, monospace;">if</span><span style="font-family: arial, helvetica, sans-serif;">-check. </span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 1.2</span>
<span style="color: #008800; font-weight: bold;">def</span> calc(s: <span style="color: #008800; font-weight: bold;">String</span>): <span style="color: #008800; font-weight: bold;">String</span> = {
<span style="color: #008800; font-weight: bold;">val</span> x = fooJ.get(s)
<span style="color: #008800; font-weight: bold;">val</span> y = <span style="color: #008800; font-weight: bold;">if</span> (x != <span style="color: #003388; font-weight: bold;">null</span>) {
barJ.get(x.length)
} <span style="color: #008800; font-weight: bold;">else</span> {
<span style="color: #003388; font-weight: bold;">null</span>
}
y
}</pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
What was wrong with the snippet 1.1 was that the two operations were <b><i>"sequenced"</i></b> wrongly i.e. There were some <b><i>"additional effects"</i></b> necessary in between, which were missing.</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
Wouldn't it be cool if we could write code whose <b><i>"shape"</i></b> is like that of snippet 1.1 but which behaves like code in snippet 1.2? </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b>Example 2: Exceptions</b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b><br /></b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
You have to look up a couple of keys in a JSON object and then concatenate the obtained values with a space in between. Again, either or both keys might be absent, thus leading to an exception. In such an event, the exception should bubble up to the caller. </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
This is how you might do it:</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default">
<pre style="margin-top: 0em;"><pre style="color: #222222; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 2.1</span>
<span style="color: #008800; font-weight: bold;">import</span> play.api.libs.json._
<span style="color: #008800; font-weight: bold;">def</span> calc(json: JsObject): <span style="color: #008800; font-weight: bold;">String</span> = {
<span style="color: #008800; font-weight: bold;">val</span> name = (json \ <span style="color: #dd2200;">"name"</span>).as[<span style="color: #008800; font-weight: bold;">String</span>]
<span style="color: #008800; font-weight: bold;">val</span> address = (json \ <span style="color: #dd2200;">"address"</span>).as[<span style="color: #008800; font-weight: bold;">String</span>]
name + <span style="color: #dd2200;">" "</span> + address
}</pre>
</pre>
<pre style="margin-top: 0em;"></pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
This code works as expected. The necessary "sequencing" or "effects" here are provided by a first-class language feature called exceptions. Imagine a language without exceptions.
<br />
<br />
What might you do in such a language? Perhaps send a tuple of error code and result. Or some equivalent structure.<br />
<br />
Is it possible to write code whose "shape" and behavior is like that of snippet 2.1, but which doesn't use first-class exceptions?</div>
<br />
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b>Example 3: Futures and promises</b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b><br /></b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
A future is an abstraction of a value which will be available at some point in time. This is a concurrency abstraction invented in late 70s but popularized by Java and Javascript. Scala's variation is a tad better. </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
Consider a simple, non realistic task. We need to make two web service calls. There's something that mandates that the second call must be made after the first one is over (I told you it's a non-realistic example). Then after you obtain both results, you sum the lengths of the response bodies. </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
In a good old, serial, blocking, non-futurey API, this might look like below:</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 3.1</span>
<span style="color: #008800; font-weight: bold;">def</span> calc(s: <span style="color: #008800; font-weight: bold;">String</span>): <span style="color: #008800; font-weight: bold;">Int</span> = {
<span style="color: #008800; font-weight: bold;">val</span> googleResponse = makeWebServiceCall(<span style="color: #dd2200;">"<a href="https://www.google.com/#q=" style="color: #1155cc;" target="_blank">https://<wbr></wbr>www.google.com/#q=</a>"</span> + s)
<span style="color: #008800; font-weight: bold;">val</span> bingRespone = makeWebServiceCall(<span style="color: #dd2200;">"<a href="http://www.bing.com/search?q=" style="color: #1155cc;" target="_blank">http://<wbr></wbr>www.bing.com/search?q=</a>"</span> + s)
googleResponse.body.length + bingResponse.body.length
}</pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
Now let's rewrite this with an API that uses futures. How are we going to sequence operations in such an API? The popular solution seems to be callbacks. With such an approach the code might look like below:</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 3.2</span>
<span style="color: #008800; font-weight: bold;">import</span> concurrent.{Promise, Future}
<span style="color: #008800; font-weight: bold;">import</span> play.api.libs.ws.WS
<span style="color: #008800; font-weight: bold;">def</span> calc(s: <span style="color: #008800; font-weight: bold;">String</span>): Future[<span style="color: #008800; font-weight: bold;">Int</span>] = {
<span style="color: #008800; font-weight: bold;">val</span> promise = Promise[<span style="color: #008800; font-weight: bold;">Int</span>]()
<span style="color: #008800; font-weight: bold;">val</span> googleResponse = WS.url(<span style="color: #dd2200;">"<a href="https://www.google.com/#q=" style="color: #1155cc;" target="_blank">https://www.google.<wbr></wbr>com/#q=</a>"</span> + s).get()
googleResponse onSuccess { <span style="color: #008800; font-weight: bold;">case</span> res1 =>
<span style="color: #008800; font-weight: bold;">val</span> bingResponse = WS.url(<span style="color: #dd2200;">"<a href="http://www.bing.com/search?q=" style="color: #1155cc;" target="_blank">http://www.bing.com/<wbr></wbr>search?q=</a>"</span> + s).get()
bingResponse onSuccess { <span style="color: #008800; font-weight: bold;">case</span> res2 =>
promise.success(res1.body.<wbr></wbr>length + res2.body.length)
}
}
promise.future
}</pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
The onSuccess here provides necessary "effects" in between the operations.</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
This code is fairly straightforward, but has the following problems:</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
i. It exposes "promise", an implementation detail of futures.</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
ii. The onSuccess+promise pattern gets repetitive fast, and soon becomes an eyesore.</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
Wouldn't it rock if we could write code whose "shape" is like that of our serial code but which has future-y semantics? </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b>Enter "Type Driven Development"!</b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b><br /></b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
Let me introduce you to a style of programming popular in statically typed functional languages - Type Driven Development! (Henceforth referred to as TyDD.) </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
In TyDD, you encode as much semantic information as possible in your types (and values). (Of course there is a lot more to TyDD but it isn't the subject of this talk.)</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
Let us revisit our examples, and try applying TyDD to them.</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b>Revisiting example 1:</b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b><br /></b></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">Scala has a data type named "</span><span style="font-family: courier new, monospace;">Option</span><span style="font-family: arial, helvetica, sans-serif;">", which is a sum type, that encodes the presence/absence semantics. (Languages with different type systems might use different encodings.) It's roughly defined as:</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 1.3</span>
sealed abstract <span style="color: #008800; font-weight: bold;">class</span> Option[+A]
<span style="color: #008800; font-weight: bold;">case</span> <span style="color: #008800; font-weight: bold;">class</span> Some[+A](value: A) <span style="color: #008800; font-weight: bold;">extends</span> <span style="color: #003366; font-weight: bold;">Option</span>[A]
<span style="color: #008800; font-weight: bold;">case</span> <span style="color: #008800; font-weight: bold;">object</span> None <span style="color: #008800; font-weight: bold;">extends</span> <span style="color: #003366; font-weight: bold;">Option</span>[Nothing]</pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
As you'd expect, calling <span style="font-family: courier new, monospace;">get</span><span style="font-family: arial, helvetica, sans-serif;"> on Scala's map returns an </span><span style="font-family: courier new, monospace;">Option</span><span style="font-family: arial, helvetica, sans-serif;"> value. With use of Scala maps, our code might look like:</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 1.4</span>
<span style="color: #008800; font-weight: bold;">val</span> fooS: Map[<span style="color: #008800; font-weight: bold;">String</span>, <span style="color: #008800; font-weight: bold;">String</span>] = Map(<span style="color: #dd2200;">"a"</span> -> <span style="color: #dd2200;">"xoxox"</span>, <span style="color: #dd2200;">"b"</span> -> <span style="color: #dd2200;">"xoxo"</span>)
<span style="color: #008800; font-weight: bold;">val</span> barS: Map[<span style="color: #008800; font-weight: bold;">Int</span>, <span style="color: #008800; font-weight: bold;">String</span>] = Map(<span style="color: #0000dd; font-weight: bold;">4</span> -> <span style="color: #dd2200;">"P"</span>, <span style="color: #0000dd; font-weight: bold;">5</span> -> <span style="color: #dd2200;">"Q"</span>)
<span style="color: #008800; font-weight: bold;">def</span> calc(s: <span style="color: #008800; font-weight: bold;">String</span>): Option[<span style="color: #008800; font-weight: bold;">String</span>] = {
fooS.get(s) <span style="color: #008800; font-weight: bold;">match</span> {
<span style="color: #008800; font-weight: bold;">case</span> Some(x) => barS.get(x.length)
<span style="color: #008800; font-weight: bold;">case</span> <span style="color: #003388; font-weight: bold;">None</span> => <span style="color: #003388; font-weight: bold;">None</span>
}
}</pre>
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"></pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
One advantage of the TyDD approach should be immediately clear by now: Compiler won't allow you to treat <span style="font-family: courier new, monospace;">Option[A]</span><span style="font-family: arial, helvetica, sans-serif;"> as </span><span style="font-family: courier new, monospace;">A</span><span style="font-family: arial, helvetica, sans-serif;">, and hence you cannot inadvertently write incorrect code like in snippet 1.1. You are forced to deal with optionality of value. </span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
But all that sequencing with pattern matching looks yucky, and will get yuckier with every operation. <b>Wouldn't it be nice if the data type in question could take care of this sequencing? </b>You know, "Tell, Don't Ask" and all that? </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">As it happens, </span><span style="font-family: courier new, monospace;">Option</span><span style="font-family: arial, helvetica, sans-serif;"> does have a method that takes care of this sequencing! The method is called </span><span style="font-family: courier new, monospace;">flatMap</span><span style="font-family: arial, helvetica, sans-serif;">, and on using it, the code looks like shown below:</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 1.5</span>
<span style="color: #008800; font-weight: bold;">def</span> calc(s: <span style="color: #008800; font-weight: bold;">String</span>): Option[<span style="color: #008800; font-weight: bold;">String</span>] = {
fooS.get(s) flatMap { x =>
barS.get(x.length) flatMap { y =>
Some(y)
}
}
}</pre>
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"></pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
In the innermost block, you need to put the value in <span style="font-family: courier new, monospace;">Option</span><span style="font-family: arial, helvetica, sans-serif;">. </span><span style="font-family: courier new, monospace;">Some</span><span style="font-family: arial, helvetica, sans-serif;"> is the data constructor we use for the purpose.</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
If you compare this code to snippet 1.1, you'll notice that their shape is similar. (Okay, the code is <i>somewhat</i> inverted along vertical axis, but as you'll soon see, there is a fix for that.)</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b>Revisiting example 2:</b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">Scala has a data type named "</span><span style="font-family: courier new, monospace;">Try</span><span style="font-family: arial, helvetica, sans-serif;">" which encodes success/failure semantics. It's roughly defined as:</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 1.3em; margin-top: 0em;"><span style="color: #888888;">// snippet 2.2</span>
sealed abstract <span style="color: #008800; font-weight: bold;">class</span> Try[+A]
<span style="color: #008800; font-weight: bold;">case</span> <span style="color: #008800; font-weight: bold;">class</span> Success[+A](value: A) <span style="color: #008800; font-weight: bold;">extends</span> <span style="color: #003366; font-weight: bold;">Try</span>[A]
<span style="color: #008800; font-weight: bold;">case</span> <span style="color: #008800; font-weight: bold;">class</span> Failure(throwable: Throwable) <span style="color: #008800; font-weight: bold;">extends</span> <span style="color: #003366; font-weight: bold;">Try</span>[Nothing]
</pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
Let's imagine <span style="font-family: courier new, monospace;">JsObject</span><span style="font-family: arial, helvetica, sans-serif;"> has a method named </span><span style="font-family: courier new, monospace;">asTry[A]</span><span style="font-family: arial, helvetica, sans-serif;"> that returns </span><span style="font-family: courier new, monospace;">Try[A]</span><span style="font-family: arial, helvetica, sans-serif;">. With its use, code will look like:</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 2.3</span>
<span style="color: #008800; font-weight: bold;">import</span> play.api.libs.json._
<span style="color: #008800; font-weight: bold;">import</span> util.{Try, Success, Failure}
<span style="color: #008800; font-weight: bold;">def</span> calc(json: JsObject): Try[<span style="color: #008800; font-weight: bold;">String</span>] = {
(json \ <span style="color: #dd2200;">"name"</span>).asTry[<span style="color: #008800; font-weight: bold;">String</span>] <span style="color: #008800; font-weight: bold;">match</span> {
<span style="color: #008800; font-weight: bold;">case</span> Success(name) =>
(json \ <span style="color: #dd2200;">"address"</span>).asTry[<span style="color: #008800; font-weight: bold;">String</span>] <span style="color: #008800; font-weight: bold;">match</span> {
<span style="color: #008800; font-weight: bold;">case</span> Success(address) => Success(name + <span style="color: #dd2200;">" "</span> + address)
<span style="color: #008800; font-weight: bold;">case</span> Failure(ex) => Failure(ex)
}
<span style="color: #008800; font-weight: bold;">case</span> Failure(ex) => Failure(ex)
}
}</pre>
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"></pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
Boy, look at all that boilerplate! </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">As you might probably expect at this point, </span><span style="font-family: courier new, monospace;">Try </span><span style="font-family: arial, helvetica, sans-serif;">has a method named "</span><span style="font-family: courier new, monospace;">flatMap</span><span style="font-family: arial, helvetica, sans-serif;">" that helps you do away with this boilerplate. This is how the code will look like with </span><span style="font-family: courier new, monospace;">flatMap</span><span style="font-family: arial, helvetica, sans-serif;">:</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 2.4</span>
<span style="color: #008800; font-weight: bold;">import</span> play.api.libs.json._
<span style="color: #008800; font-weight: bold;">import</span> util.{Try, Success, Failure}
<span style="color: #008800; font-weight: bold;">def</span> calc(json: JsObject): Try[<span style="color: #008800; font-weight: bold;">String</span>] = {
(json \ <span style="color: #dd2200;">"name"</span>).asTry[<span style="color: #008800; font-weight: bold;">String</span>] flatMap { name =>
(json \ <span style="color: #dd2200;">"address"</span>).asTry[<span style="color: #008800; font-weight: bold;">String</span>] flatMap { address =>
Success(name + <span style="color: #dd2200;">" "</span> + address)
}
}
}</pre>
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"></pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
In the innermost block, you need to put the value in <span style="font-family: courier new, monospace;">Try</span><span style="font-family: arial, helvetica, sans-serif;">, and we use </span><span style="font-family: courier new, monospace;">Success </span><span style="font-family: arial, helvetica, sans-serif;">data constructor for that.</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
This code is very similar in shape to code in snippet 2.1.</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b>Revisiting example 3:</b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b><br /></b></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">Our results are already wrapped in </span><span style="font-family: courier new, monospace;">Future</span><span style="font-family: arial, helvetica, sans-serif;">, so we are already using a distinct type to encode the semantics.</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b><br /></b></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">Now </span><span style="font-family: courier new, monospace;">Future</span><span style="font-family: arial, helvetica, sans-serif;"> also happens to have a "</span><span style="font-family: courier new, monospace;">flatMap</span><span style="font-family: arial, helvetica, sans-serif;">" method. Let's rewrite the code in snippet 3.2 with it.</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 3.3</span>
<span style="color: #008800; font-weight: bold;">import</span> concurrent.{Promise, Future}
<span style="color: #008800; font-weight: bold;">import</span> play.api.libs.ws.WS
<span style="color: #008800; font-weight: bold;">def</span> calc(s: <span style="color: #008800; font-weight: bold;">String</span>): Future[<span style="color: #008800; font-weight: bold;">Int</span>] = {
WS.url(<span style="color: #dd2200;">"<a href="https://www.google.com/#q=" style="color: #1155cc;" target="_blank">https://www.google.<wbr></wbr>com/#q=</a>"</span> + s).get() flatMap { googleResponse =>
WS.url(<span style="color: #dd2200;">"<a href="http://www.bing.com/search?q=" style="color: #1155cc;" target="_blank">http://www.bing.com/<wbr></wbr>search?q=</a>"</span> + s).get() flatMap { bingResponse =>
Future.successful(googleRespon<wbr></wbr>se.body.length + bingResponse.body.length)
}
}
}</pre>
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"></pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
In the innermost block, we create a future with an already completed promise with our value.</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
Again, similar in shape to code in snippet 3.1.</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b>Monad comprehensions:</b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b><br /></b></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">As we have seen "</span><span style="font-family: courier new, monospace;">flatMap</span><span style="font-family: arial, helvetica, sans-serif;">" allows our code to have a simple shape, with details of sequencing of operations abstracted away. Now monads are so common in functional programming that functional languages often provide a syntactic sugar on top of them, which makes the "inversion along vertical axis" go away. This sugar is called "monad comprehensions". Scala calls them "for comprehensions". (Similarity with for-loops is superficial and should be ignored.) Here's how our code snippets might look once we start using this notation:</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 1.6</span>
<span style="color: #008800; font-weight: bold;">def</span> calc(s: <span style="color: #008800; font-weight: bold;">String</span>): Option[<span style="color: #008800; font-weight: bold;">String</span>] = {
<span style="color: #008800; font-weight: bold;">for</span> {
x <- fooS.get(s)
y <- barS.get(x.length)
} <span style="color: #008800; font-weight: bold;">yield</span> y
}
<span style="color: #888888;">// snippet 2.5</span>
<span style="color: #008800; font-weight: bold;">import</span> play.api.libs.json._
<span style="color: #008800; font-weight: bold;">import</span> util.{Try, Success, Failure}
<span style="color: #008800; font-weight: bold;">def</span> calc(json: JsObject): Try[<span style="color: #008800; font-weight: bold;">String</span>] = {
<span style="color: #008800; font-weight: bold;">for</span> {
name <- (json \ <span style="color: #dd2200;">"name"</span>).asTry[<span style="color: #008800; font-weight: bold;">String</span>]
address <- (json \ <span style="color: #dd2200;">"address"</span>).asTry[<span style="color: #008800; font-weight: bold;">String</span>]
} <span style="color: #008800; font-weight: bold;">yield</span> name + <span style="color: #dd2200;">" "</span> + address
}
<span style="color: #888888;">// snippet 3.4</span>
<span style="color: #008800; font-weight: bold;">import</span> concurrent.{Promise, Future}
<span style="color: #008800; font-weight: bold;">import</span> play.api.libs.ws.WS
<span style="color: #008800; font-weight: bold;">def</span> calc(s: <span style="color: #008800; font-weight: bold;">String</span>): Future[<span style="color: #008800; font-weight: bold;">Int</span>] = {
<span style="color: #008800; font-weight: bold;">for</span> {
googleResponse <- WS.url(<span style="color: #dd2200;">"<a href="https://www.google.com/#q=" style="color: #1155cc;" target="_blank">https://www.google.<wbr></wbr>com/#q=</a>"</span> + s).get()
bingResponse <- WS.url(<span style="color: #dd2200;">"<a href="http://www.bing.com/search?q=" style="color: #1155cc;" target="_blank">http://www.bing.com/<wbr></wbr>search?q=</a>"</span> + s).get()
} <span style="color: #008800; font-weight: bold;">yield</span> googleResponse.body.length + bingResponse.body.length
}</pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
These are even closer in appearance to snippets 1.1, 2.1, and 3.1 respectively. </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">Note that this is just a sugar and compiles down <i>roughly</i> to the code we wrote before with </span><span style="font-family: courier new, monospace;">flatMap</span><span style="font-family: arial, helvetica, sans-serif;">.</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b>So what is a monad?</b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b><br /></b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
A monad is essentially a two method interface, which can be defined as below:</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 4.1</span></pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #008800; font-weight: bold;">trait</span> Monad[M[_]] {
<span style="color: #008800; font-weight: bold;">def</span> flatMap[A, B](x: M[A], f: A => M[B]): M[B]
<span style="color: #008800; font-weight: bold;">def</span> point[A](x: A): M[A]
<span style="color: #008800; font-weight: bold;">def</span> map[A, B](x: M[A], f: A => B): M[B] = flatMap(x, a => point(f(a)))
}</pre>
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"></pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
I am using the word "interface" here in its generic sense, not in the OO sense. A more specific term for this abstraction mechanism would be "type-class", and you can learn more about it <a href="http://danielwestheide.com/blog/2013/02/06/the-neophytes-guide-to-scala-part-12-type-classes.html" style="color: #1155cc;" target="_blank">here</a>. </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
About the methods:</div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<ul>
<li><span style="font-family: courier new, monospace;">flatMap</span><span style="font-family: arial, helvetica, sans-serif;">: We already talked about it.</span></li>
<li><span style="font-family: courier new, monospace;">point</span><span style="font-family: arial, helvetica, sans-serif;">: It's basically a method that allows you to put a value in monad's context in the innermost block. </span></li>
<li><span style="font-family: courier new, monospace;">map</span><span style="font-family: arial, helvetica, sans-serif;">: It's a method by default defined in terms of </span><span style="font-family: courier new, monospace;">flatMap</span><span style="font-family: arial, helvetica, sans-serif;"> and </span><span style="font-family: courier new, monospace;">point</span><span style="font-family: arial, helvetica, sans-serif;">, and you can override it in case a more performant implementation specific to the data type is possible.</span></li>
</ul>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">As an example here's a monad implementation for </span><span style="font-family: courier new, monospace;">Option</span><span style="font-family: arial, helvetica, sans-serif;">:</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 4.2</span>
implicit <span style="color: #008800; font-weight: bold;">object</span> OptionMonad <span style="color: #008800; font-weight: bold;">extends</span> <span style="color: #003366; font-weight: bold;">Monad</span>[Option] {
<span style="color: #008800; font-weight: bold;">def</span> flatMap[A, B](x: Option[A], f: A => Option[B]): Option[B] = x <span style="color: #008800; font-weight: bold;">match</span> {
<span style="color: #008800; font-weight: bold;">case</span> Some(a) => f(a)
<span style="color: #008800; font-weight: bold;">case</span> <span style="color: #003388; font-weight: bold;">None</span> => <span style="color: #003388; font-weight: bold;">None</span>
}
<span style="color: #008800; font-weight: bold;">def</span> point[A](x: A): Option[A] = Some(x)
override <span style="color: #008800; font-weight: bold;">def</span> map[A, B](x: Option[A], f: A => B): Option[B] = x <span style="color: #008800; font-weight: bold;">match</span> {
<span style="color: #008800; font-weight: bold;">case</span> Some(a) = Some(f(a))
<span style="color: #008800; font-weight: bold;">case</span> <span style="color: #003388; font-weight: bold;">None</span> => <span style="color: #003388; font-weight: bold;">None</span>
}
}</pre>
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"></pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
The implementation of Monad type-class also needs to obey some laws which we won't go into here. </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b>Intuition for monads:</b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b><br /></b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
You use the monad abstraction when: </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
i. You need a "customized sequencing" for operations i.e. You need "additional effects" in between computations, and you want them abstracted away.</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
ii. You need to abstract <i>over </i>the sequencing details. i.e. Write code that is parametrized over M (some monad), and plug specific monad instance as necessary. <a href="http://www.precog.com/blog/Precog-Copointed-The-Abstract-Future/" style="color: #1155cc;" target="_blank">This technique is used in Precog code</a> to a good effect (pun unintended! ;).</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
One gentleman once cleverly described monads as something that lets you "overload semicolon". (Since Scala doesn't use semicolons at the end of statements/expressions, this perhaps isn't as helpful/funny, but you get the idea (I hope).)</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b>Other monads:</b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b><br /></b></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">We have covered only three monads here - </span><span style="font-family: courier new, monospace;">Option</span><span style="font-family: arial, helvetica, sans-serif;">, </span><span style="font-family: courier new, monospace;">Try</span><span style="font-family: arial, helvetica, sans-serif;">, and </span><span style="font-family: courier new, monospace;">Future</span><span style="font-family: arial, helvetica, sans-serif;"> - there are many more out there. Here're some more interesting and common ones:</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">i. </span><span style="font-family: courier new, monospace;">Seq</span><span style="font-family: arial, helvetica, sans-serif;"> - Non-determinism.</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">ii. </span><span style="font-family: courier new, monospace;">Either</span><span style="font-family: arial, helvetica, sans-serif;"> - Binary type disjunction. Often used for error handling.</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">iii. </span><span style="font-family: courier new, monospace;">Reader</span><span style="font-family: arial, helvetica, sans-serif;"> - An "implicit" context passed around from which values can be read.</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">iv. </span><span style="font-family: courier new, monospace;">Writer</span><span style="font-family: arial, helvetica, sans-serif;"> - Logging.</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">v. </span><span style="font-family: courier new, monospace;">State</span><span style="font-family: arial, helvetica, sans-serif;"> - What the name says.</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">vi. </span><span style="font-family: courier new, monospace;">ST</span><span style="font-family: arial, helvetica, sans-serif;"> - Localized mutation. </span></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">vii. </span><span style="font-family: courier new, monospace;">Undo</span><span style="font-family: arial, helvetica, sans-serif;"> - Ability to undo (and redo) operations.</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<b>Kleisli composition:</b></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default">
<span style="font-family: arial, helvetica, sans-serif;">Given two functions </span><span style="font-family: courier new, monospace;">f: A => B</span><span style="font-family: arial, helvetica, sans-serif;"> and </span><span style="font-family: courier new, monospace;">g: B => C</span><span style="font-family: arial, helvetica, sans-serif;">, it's fairly trivial to compose them together. Here's how you can write a function to compose them:</span></div>
<div class="gmail_default">
<span style="font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 5.1</span>
<span style="color: #008800; font-weight: bold;">def</span> compose[A, B, C](f: A => B, g: B => C): A => C =
a => g(f(a))</pre>
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"></pre>
</div>
<div class="gmail_default">
<span style="font-family: arial, helvetica, sans-serif;">Now what happens when I have two "effectful" functions instead, say </span><span style="font-family: courier new, monospace;">f: A => M[B]</span><span style="font-family: arial, helvetica, sans-serif;"> and </span><span style="font-family: courier new, monospace;">g: B => M[C]? </span><span style="font-family: arial, helvetica, sans-serif;">Composing these isn't trivial since the output type of f and input type of g don't match. We need a new composition function with signature like:</span></div>
<div class="gmail_default">
<span style="font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 5.2</span>
<span style="color: #008800; font-weight: bold;">def</span> mcompose[A, B, C, M[_]](f: A => M[B], g: B => M[C]): A => M[C] =
???</pre>
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"></pre>
</div>
<div>
<span style="font-family: arial, helvetica, sans-serif;">It's not possible to write this generically. How the operations would be composed will depend on the structure of </span><span style="font-family: courier new, monospace;">M</span><span style="font-family: arial, helvetica, sans-serif;">. Hmm, why don't we then have </span><span style="font-family: courier new, monospace;">M</span><span style="font-family: arial, helvetica, sans-serif;"> tell us how to wire this operations up? We can. Monads to the rescue!</span></div>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><span style="color: #888888;">// snippet 5.3</span>
<span style="color: #008800; font-weight: bold;">def</span> mcompose[A, B, C, M[_]](f: A => M[B], g: B => M[C])(implicit e: Monad[M]): A => M[C] =
a => {
<span style="color: #008800; font-weight: bold;">val</span> mb = f(a)
e.flatMap(mb, { b =>
<span style="color: #008800; font-weight: bold;">val</span> mc = g(b)
e.flatMap(mc, { c =>
m.point(c)
})
})
}</pre>
<pre style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"></pre>
</div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">This kind of composition is called "Kleisli composition" and is often denoted with symbol </span><span style="font-family: courier new, monospace;">>=></span><span style="font-family: arial, helvetica, sans-serif;">.</span></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b>Monads are not alone!</b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b><br /></b></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
I hope this talk helped you gain some intuition for what a monad is and when to use this abstraction. </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
As it happens, monads are not alone. There is a whole slew of such type-classes that let you abstract over computational patterns. Some key examples might be: Functor, Applicative, MonadPlus, Arrow, Alternative etc. If you find monads interesting/useful, I strongly recommend exploring the rest of the brethren as well. The best medium to do that is probably Haskell, and <a href="http://learnyouahaskell.com/" style="color: #1155cc;" target="_blank">here</a> is a good book to learn this beautiful language. </div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: arial, helvetica, sans-serif;">
<b>Some more notes:</b></div>
<div class="gmail_default" style="color: #222222; font-family: arial;">
<ol>
<li><span style="font-family: arial, helvetica, sans-serif;">Note that the names </span><span style="font-family: courier new, monospace;">flatMap</span><span style="font-family: arial, helvetica, sans-serif;"> and </span><span style="font-family: courier new, monospace;">point</span><span style="font-family: arial, helvetica, sans-serif;"> are not standard and different languages refer to them with different names. Various other names of </span><span style="font-family: courier new, monospace;">flatMap: >>=, bind, m-bind, SelectMany</span><span style="font-family: arial, helvetica, sans-serif;">. Various other names of </span><span style="font-family: courier new, monospace;">point: pure, return</span><span style="font-family: arial, helvetica, sans-serif;">.)</span></li>
<li><span style="font-family: arial, helvetica, sans-serif;">Scala's </span><span style="font-family: courier new, monospace;">Try</span><span style="font-family: arial, helvetica, sans-serif;"> violates certain monad laws and is therefore not quite a monad. However those details are irrelevant considering the basic nature of this talk. I could have used </span><span style="font-family: courier new, monospace;">Either</span><span style="font-family: arial, helvetica, sans-serif;">, but its implementation would require me to touch upon many tangential ideas and that would be a distraction.</span></li>
<li><span style="font-family: arial, helvetica, sans-serif;">A question is often asked, given that monads are so centered around types, are they possible/useful in dynamic languages? Yes, they are possible in dynamic languages. But much of their utility is lost. Also they require a somewhat different encoding. (I intend to blog about this point separately.)</span></li>
<li><span style="font-family: arial, helvetica, sans-serif;">Scala standard library does not have a Monad type-class. How do its for-comprehensions work then? The answer is Scala compiler blindly translates them to </span><span style="font-family: courier new, monospace;">flatMap</span><span style="font-family: arial, helvetica, sans-serif;"> and </span><span style="font-family: courier new, monospace;">map</span><span style="font-family: arial, helvetica, sans-serif;"> method calls <i>on</i> that data type (Yes, </span><span style="font-family: courier new, monospace;">map</span><span style="font-family: arial, helvetica, sans-serif;">, not </span><span style="font-family: courier new, monospace;">point</span><span style="font-family: arial, helvetica, sans-serif;">). This approach has its pros and cons. Nevertheless, a </span><span style="font-family: courier new, monospace;">Monad</span><span style="font-family: arial, helvetica, sans-serif;"> type-class can be useful in many cases, and there're <a href="https://github.com/scalaz/scalaz" style="color: #1155cc;" target="_blank">libraries</a> that will provide it for you.</span></li>
<li><span style="font-family: arial, helvetica, sans-serif;">If you want to really really understand monads in all their glory, <a href="http://mvanier.livejournal.com/3917.html" style="color: #1155cc;" target="_blank">here</a>'s a brilliant tutorial. Mind you it's rather long, but from my experiences I can tell, it's totally worth it.</span></li>
<li><span style="font-family: arial, helvetica, sans-serif;">Monad comprehensions sugar is pretty neat, but it still leaves much to be desired. People have taken the idea further in many different directions and come up with better syntaxes, such as <a href="https://github.com/aztek/scala-workflow/" style="color: #1155cc;" target="_blank">this one</a>. </span></li>
</ol>
</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com1tag:blogger.com,1999:blog-1586964767032798423.post-42872269256237952622013-09-15T03:07:00.001+05:302013-09-15T23:04:11.375+05:30Not-so-embedded documents with Clojure<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="color: #222222; font-family: arial;"><a href="http://www.blogger.com/"><span id="goog_1469188307"></span>In my previous blog post<span id="goog_1469188308"></span></a>, I talked about embedded document pattern, and how a combination of combinators and some metaprogramming can abstract away its recurring bits. When I wrote that post, I wondered how I might deal with this problem in Clojure, a language that lacks OO, in traditional sense. I fiddled with it a bit and ended up with what I find to be a reasonably elegant solution. This blog post talks about that.</span><br />
<span style="color: #222222; font-family: arial;"><br /></span>
<span style="color: #222222; font-family: arial;">In Clojure, we like to keep our data structures "naked". We don't wrap them in classes unless there is a good reason to do so. This has a huge advantage that all the functions and utilities available for maps, sets, sequences still work with your data. </span><br />
<span style="color: #222222; font-family: arial;"><br /></span>
<span style="color: #222222; font-family: arial;">Our initial approach to the problem might look like:</span><br />
<span style="color: #222222; font-family: arial;"><br /></span>
<br />
<pre class="textmate-source" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 1.3em; margin-top: 0em;"><pre class="sunburst" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 1.3em; margin-top: 0em;"><span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_definition meta_definition_global meta_definition_global_clojure"><span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_global entity_global_clojure">data</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_map meta_map_clojure">{<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:id</span> <span class="string string_quoted string_quoted_double string_quoted_double_clojure" style="color: #dd2200;">"product1234"</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:name</span> <span class="string string_quoted string_quoted_double string_quoted_double_clojure" style="color: #dd2200;">"Nex-5R"</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:href</span> <span class="string string_quoted string_quoted_double string_quoted_double_clojure" style="color: #dd2200;">"totoro.com"</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:links</span> <span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_map meta_map_clojure">{<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:id</span> <span class="string string_quoted string_quoted_double string_quoted_double_clojure" style="color: #dd2200;">"link1"</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:url</span> <span class="string string_quoted string_quoted_double string_quoted_double_clojure" style="color: #dd2200;">"kokoro.com"</span>}</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_map meta_map_clojure">{<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:id</span> <span class="string string_quoted string_quoted_double string_quoted_double_clojure" style="color: #dd2200;">"link2"</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:url</span> <span class="string string_quoted string_quoted_double string_quoted_double_clojure" style="color: #dd2200;">"boboro.com"</span>}</span>]</span>}</span></span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"> </span>
<span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_definition meta_definition_global meta_definition_global_clojure"><span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defn</span> <span class="entity entity_global entity_global_clojure">product-master-id</span><span class="invalid invalid_trailing-whitespace"> </span>
<span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_symbol meta_symbol_clojure">product</span>]</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:name</span> <span class="meta meta_symbol meta_symbol_clojure">product</span>)</span></span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"> </span>
<span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_definition meta_definition_global meta_definition_global_clojure"><span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defn</span> <span class="entity entity_global entity_global_clojure">link-master-id</span><span class="invalid invalid_trailing-whitespace"> </span>
<span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_symbol meta_symbol_clojure">link</span>]</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:id</span> <span class="meta meta_symbol meta_symbol_clojure">link</span>)</span></span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"> </span>
<span class="comment comment_line comment_line_semicolon comment_line_semicolon_clojure" style="color: #888888;">; Collect product master ID and master IDs for all its links</span>
<span class="invalid invalid_trailing-whitespace"> </span>
<span class="meta meta_map meta_map_clojure">{<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:product-master-id</span> <span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_symbol meta_symbol_clojure">product</span>-<span class="meta meta_symbol meta_symbol_clojure">master</span>-<span class="meta meta_symbol meta_symbol_clojure">id</span> <span class="meta meta_symbol meta_symbol_clojure">data</span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:links-master-ids</span> <span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_symbol meta_symbol_clojure">map</span> <span class="meta meta_symbol meta_symbol_clojure">link</span>-<span class="meta meta_symbol meta_symbol_clojure">master</span>-<span class="meta meta_symbol meta_symbol_clojure">id</span> <span class="meta meta_expression meta_expression_clojure">(<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:links</span> <span class="meta meta_symbol meta_symbol_clojure">data</span>)</span>)</span>}</span></pre>
</pre>
<span style="color: #222222; font-family: arial;">Pretty simple. Just data and functions.</span><br />
<span style="color: #222222; font-family: arial;"><br /></span>
<span style="color: #222222; font-family: arial;">However there is a disadvantage with this approach: The caller always has to know the type of the input data. (link, product etc.) In a system involving complex data, comprising of dozens of models, this would become very tedious. This is not ideal.</span><br />
<span style="color: #222222; font-family: arial;"><br /></span>
<span style="color: #222222; font-family: arial;">Wouldn't it be nice if we could have our data respond to function calls <i>polymorphically</i>, without having to wrap it in some types or having to otherwise pollute the data? The good news is that there are a couple of Clojure features that make this possible:</span><br />
<ol style="text-align: left;">
<li><span style="color: #222222; font-family: arial;"><span style="color: #222222; font-family: arial;">Metadata: Most Clojure data structures implement protocol </span><span style="color: #222222; font-family: Courier New, Courier, monospace;">clojure.lang.IObj</span><span style="color: #222222; font-family: arial;"> that provides an ability to decorate references with metadata, without actually affecting the data. We can store "type tags" for our data in this metadata!</span></span></li>
<li><span style="color: #222222; font-family: arial;">Multimethods: These let you dispatch on arbitrary function. In our case, we could use a dispatching function that looks up the type tag we embedded in the metadata.</span></li>
</ol>
<span style="color: #222222; font-family: arial;">With that our design might look like:</span><br />
<span style="color: #222222; font-family: arial;"><br /></span>
<br />
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_definition meta_definition_global meta_definition_global_clojure"><span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defn</span> <span class="entity entity_global entity_global_clojure">with-type-tag</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_symbol meta_symbol_clojure">data</span> <span class="meta meta_symbol meta_symbol_clojure">type</span>-<span class="meta meta_symbol meta_symbol_clojure">tag</span>]</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_symbol meta_symbol_clojure">with</span>-<span class="meta meta_symbol meta_symbol_clojure">meta</span> <span class="meta meta_symbol meta_symbol_clojure">data</span> <span class="meta meta_map meta_map_clojure">{<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:type-tag</span> <span class="meta meta_symbol meta_symbol_clojure">type</span>-<span class="meta meta_symbol meta_symbol_clojure">tag</span>}</span>)</span></span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_definition meta_definition_global meta_definition_global_clojure"><span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defn</span> <span class="entity entity_global entity_global_clojure">type-tag</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_symbol meta_symbol_clojure">data</span>]</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:type-tag</span> <span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_symbol meta_symbol_clojure">meta</span> <span class="meta meta_symbol meta_symbol_clojure">data</span>)</span>)</span></span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_definition meta_definition_global meta_definition_global_clojure"><span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defn</span> <span class="entity entity_global entity_global_clojure">tag-as</span><span class="invalid invalid_trailing-whitespace"> </span>
<span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_symbol meta_symbol_clojure">tag</span>]</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="storage storage_control storage_control_clojure">fn</span> <span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_symbol meta_symbol_clojure">data</span>]</span> <span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_symbol meta_symbol_clojure">with</span>-<span class="meta meta_symbol meta_symbol_clojure">type</span>-<span class="meta meta_symbol meta_symbol_clojure">tag</span> <span class="meta meta_symbol meta_symbol_clojure">data</span> <span class="meta meta_symbol meta_symbol_clojure">tag</span>)</span>)</span></span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defmulti</span> <span class="meta meta_symbol meta_symbol_clojure">master</span>-<span class="meta meta_symbol meta_symbol_clojure">id</span> <span class="meta meta_symbol meta_symbol_clojure">type</span>-<span class="meta meta_symbol meta_symbol_clojure">tag</span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defmethod</span> <span class="meta meta_symbol meta_symbol_clojure">master</span>-<span class="meta meta_symbol meta_symbol_clojure">id</span> <span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">::Product</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_symbol meta_symbol_clojure">this</span>]</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:name</span> <span class="meta meta_symbol meta_symbol_clojure">this</span>)</span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defmethod</span> <span class="meta meta_symbol meta_symbol_clojure">master</span>-<span class="meta meta_symbol meta_symbol_clojure">id</span> <span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">::Link</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_symbol meta_symbol_clojure">this</span>]</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:id</span> <span class="meta meta_symbol meta_symbol_clojure">this</span>)</span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defmulti</span> <span class="meta meta_symbol meta_symbol_clojure">links</span> <span class="meta meta_symbol meta_symbol_clojure">type</span>-<span class="meta meta_symbol meta_symbol_clojure">tag</span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defmethod</span> <span class="meta meta_symbol meta_symbol_clojure">links</span> <span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">::Product</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_symbol meta_symbol_clojure">this</span>]</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(->> <span class="meta meta_symbol meta_symbol_clojure">this</span> <span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:links</span> <span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_symbol meta_symbol_clojure">map</span> <span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_symbol meta_symbol_clojure">tag</span>-<span class="meta meta_symbol meta_symbol_clojure">as</span> <span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">::Link</span>)</span>)</span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"></span>
<span class="comment comment_line comment_line_semicolon comment_line_semicolon_clojure" style="color: #888888;">; Collect product master ID and master IDs for all its links</span>
<span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_map meta_map_clojure">{<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:product-master-id</span> <span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_symbol meta_symbol_clojure">master</span>-<span class="meta meta_symbol meta_symbol_clojure">id</span> <span class="meta meta_symbol meta_symbol_clojure">data</span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:links-master-ids</span> <span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_symbol meta_symbol_clojure">map</span> <span class="meta meta_symbol meta_symbol_clojure">master</span>-<span class="meta meta_symbol meta_symbol_clojure">id</span> <span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_symbol meta_symbol_clojure">links</span> <span class="meta meta_symbol meta_symbol_clojure">data</span>)</span>)</span>}</span></span></pre>
<span style="color: #222222; font-family: arial;"><br /></span>
<span style="color: #222222; font-family: arial;">Great, we got a custom tagging and dispatching system working with a tiny bit of code!</span><br />
<span style="color: #222222; font-family: arial;"><br /></span>
<span style="color: #222222; font-family: arial;">Since we are always dispatching on a type-tag, we could spin up a small macro that avoids some of this duplication for us.</span><br />
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_expression meta_expression_clojure">
</span></pre>
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_definition meta_definition_global meta_definition_global_clojure"><span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defmacro</span> <span class="entity entity_global entity_global_clojure">defmessage</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_symbol meta_symbol_clojure">name</span>' <span class="meta meta_symbol meta_symbol_clojure">tag</span> & <span class="meta meta_symbol meta_symbol_clojure">forms</span>]</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_qouted-expression meta_qouted-expression_clojure">`(<span class="storage storage_control storage_control_clojure">do</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defmulti</span> ~<span class="meta meta_symbol meta_symbol_clojure">name</span>' <span class="meta meta_symbol meta_symbol_clojure">type</span>-<span class="meta meta_symbol meta_symbol_clojure">tag</span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defmethod</span> ~<span class="meta meta_symbol meta_symbol_clojure">name</span>' ~<span class="meta meta_symbol meta_symbol_clojure">tag</span><span class="invalid invalid_trailing-whitespace"></span>
~@<span class="meta meta_symbol meta_symbol_clojure">forms</span>)</span>)</span></span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"></span>
<span class="comment comment_line comment_line_semicolon comment_line_semicolon_clojure" style="color: #888888;">; Here's how relevant part of previous snippet will look like after we start </span>
<span class="comment comment_line comment_line_semicolon comment_line_semicolon_clojure" style="color: #888888;">; using this macro</span>
<span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defmessage</span> <span class="meta meta_symbol meta_symbol_clojure">master</span>-<span class="meta meta_symbol meta_symbol_clojure">id</span> <span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">::Product</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_symbol meta_symbol_clojure">this</span>]</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:name</span> <span class="meta meta_symbol meta_symbol_clojure">this</span>)</span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defmessage</span> <span class="meta meta_symbol meta_symbol_clojure">master</span>-<span class="meta meta_symbol meta_symbol_clojure">id</span> <span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">::Link</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_symbol meta_symbol_clojure">this</span>]</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:id</span> <span class="meta meta_symbol meta_symbol_clojure">this</span>)</span>)<span class="meta meta_after-expression meta_after-expression_clojure"></span></span>
<span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(<span class="keyword keyword_control keyword_control_clojure" style="color: #008800; font-weight: bold;">defmessage</span> <span class="meta meta_symbol meta_symbol_clojure">links</span> <span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">::Product</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_vector meta_vector_clojure">[<span class="meta meta_symbol meta_symbol_clojure">this</span>]</span><span class="invalid invalid_trailing-whitespace"></span>
<span class="meta meta_expression meta_expression_clojure">(->> <span class="meta meta_symbol meta_symbol_clojure">this</span> <span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">:links</span> <span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_symbol meta_symbol_clojure">map</span> <span class="meta meta_expression meta_expression_clojure">(<span class="meta meta_symbol meta_symbol_clojure">tag</span>-<span class="meta meta_symbol meta_symbol_clojure">as</span> <span class="constant constant_keyword constant_keyword_clojure" style="color: #003388; font-weight: bold;">::Link</span>)</span>)</span>)</span></span></pre>
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_expression meta_expression_clojure"><span class="meta meta_expression meta_expression_clojure">
</span></span></pre>
<span style="color: #222222; font-family: arial;">Cool, with just a few more lines, we also have a custom syntax for our new system!</span><br />
<span style="color: #222222; font-family: arial;"><br /></span>
<span style="color: #222222; font-family: arial;">What you see here is not a novel idea, but something very routinely used in Lisps. (Some refer to it as "custom type system", though I personally am not a fan of that term, as the term "type" means something entirely different to me.)</span><br />
<span style="color: #222222; font-family: arial;"><br /></span>
<span style="color: #222222; font-family: arial;">We have done a pretty fine job here, but there is a lot of room for improvement: </span><br />
<ol style="text-align: left;">
<li style="font-family: arial;"><span style="color: #222222;">There could be messages (tag dispatched polymorphic functions) with arity greater than one. The dispatch function should handle that.</span></li>
<li><span style="color: #222222;"><span style="font-family: arial;">We could define a variation of </span><span style="font-family: Courier New, Courier, monospace;">defmessage</span><span style="font-family: arial;"> which takes a function value. This would be useful for 3.</span></span></li>
<li style="font-family: arial;"><span style="color: #222222;">Combinators for common cases, such as "sequence of $type-tag".</span></li>
<li style="font-family: arial;"><span style="color: #222222;">Some sugar that lets one define messages for a model together in one place. Note that this will syntactially be somewhat like OO classes, but won't limit the extensibility, because what we are essentially writing are multimethods.</span></li>
<li style="font-family: arial;"><span style="color: #222222;">You could extend this further to include things like validations. A macro for model could generate a "tagger" that will run these validations before tagging given data.</span></li>
</ol>
<span style="color: #222222; font-family: arial;">All of the above left as exercise for curious/adventurous readers. ;-)</span><br />
<span style="color: #222222; font-family: arial;"><br /></span>
<span style="color: #222222; font-family: arial;">If you found this post interesting, here are some more links/resources that might strike your fancy:</span><br />
<ol style="text-align: left;">
<li><span style="color: #222222; font-family: arial;"><a href="http://www.youtube.com/watch?v=V1Eu9vZaDYw">Chris Granger on the design of LightTable</a></span></li>
<li><span style="color: #222222; font-family: arial;"><a href="http://www.infoq.com/presentations/We-Really-Dont-Know-How-To-Compute">"We really don't know how to compute!" by Gerald Sussman</a></span></li>
<li><span style="color: #222222; font-family: arial;"><a href="http://www.amazon.com/The-Metaobject-Protocol-Gregor-Kiczales/dp/0262610744">The Art of MetaObject Protocol</a></span></li>
</ol>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-15475430570671933652013-07-22T01:19:00.001+05:302013-07-22T01:58:13.615+05:30Easing the use of Embedded Document pattern<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="font-family: arial; font-size: small;">
<div>
Martin Fowler recently <a href="http://martinfowler.com/bliki/EmbeddedDocument.html" target="_blank">blogged about "Embedded Document" pattern</a>. It's a very convenient way of dealing with JSON documents in web apps and we are using it for our models in the app we are currently working on.<br />
<br />
In this post, we will see how we can abstract away the smaller patterns that occur when using Embedded Document pattern. Here is the code snippet we will be working with (based on code from Fowler's post):<br />
<br />
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; line-height: 18.1875px; margin-top: 0em;"><pre class="sunburst" style="font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; margin-top: 0em;"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;">Delivery</span></span>
<span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">initialize</span>(<span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">data</span>)</span>
<span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby" style="color: #3333bb;">@data</span> <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> data
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">customer</span></span>
<span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby" style="color: #3333bb;">@data</span>[<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'customer'</span>]
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">ship_date</span></span>
<span class="support support_class support_class_ruby" style="color: #003366; font-weight: bold;">Date</span>.parse(<span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby" style="color: #3333bb;">@data</span>[<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'shipDate'</span>])
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;">Order</span></span>
<span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">initialize</span>(<span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">data</span>)</span>
<span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby" style="color: #3333bb;">@data</span> <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> data
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">deliveries</span></span>
<span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby" style="color: #3333bb;">@data</span>[<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'deliveries'</span>].map{<span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"> </span>|<span class="variable variable_other variable_other_block variable_other_block_ruby">d</span>| <span class="support support_class support_class_ruby" style="color: #003366; font-weight: bold;">Delivery</span>.<span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby" style="color: #008800; font-weight: bold;">new</span>(d) }
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">quantity_for</span>(<span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">a_product</span>)</span>
item <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby" style="color: #3333bb;">@data</span>[<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'items'</span>].detect{|<span class="variable variable_other variable_other_block variable_other_block_ruby">i</span>| a_product <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby">==</span> i[<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'product'</span>]}
item <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby">?</span> item[<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'quantity'</span>] : <span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;">0</span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
order_hash <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="support support_class support_class_ruby" style="color: #003366; font-weight: bold;">JSON</span>.parse(
<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'{ "id": 1234,
"customer": "martin",
"items": [
{"product": "talisker", "quantity": 500},
{"product": "macallan", "quantity": 800},
{"product": "ledaig", "quantity": 1100}
],
"deliveries": [
{ "id": 7722,
"shipDate": "2013-04-19",
"items": [
{"product": "talisker", "quantity": 300},
{"product": "ledaig", "quantity": 500}
]
},
{ "id": 6533,
"shipDate": "2013-04-18",
"items": [
{"product": "talisker", "quantity": 200},
{"product": "ledaig", "quantity": 300},
{"product": "macallan", "quantity": 300}
]
}
]
}'</span>
)
order <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="support support_class support_class_ruby" style="color: #003366; font-weight: bold;">Order</span>.<span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby" style="color: #008800; font-weight: bold;">new</span>(order_hash)
p order.deliveries
p order.quantity_for(<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'talisker'</span>)</pre>
</pre>
</div>
<div>
We can observe following recurring patterns in above code:<br />
<ol>
<li>All of these classes need to have a constructor that takes in a data object and stores it in a field.</li>
<li>Many attributes require only a simple look-up in the wrapped hash. (e.g. Delivery#customer)</li>
<li>Some attributes need a look-up in hash followed by application of some transformation. (e.g. Delivery#ship_date)</li>
<li>In some cases, the nested hashes further need to be wrapped in some objects. These nested objects can appear in sequence too. (e.g. Order#deliveries)</li>
<li>Some attributes/methods involve complex operations and are too specific to derive any generalizations from them. (e.g. Order#quantity_for)</li>
</ol>
<br />
Let's start by defining a class called EmbeddedDocument which provides the base for such classes.<br />
<br />
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;">EmbeddedDocument<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby" style="color: #003366;"> < Struct.new</span></span></span>(<span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600;">:data</span>)
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span></pre>
<br />
This will provide the necessary constructor to a subclass of EmbeddedDocument, thus taking care of #1.<br />
<br />
Before we move further, let us conjure up an abstraction named "embedder". <b>An embedder is nothing but an object with a method named 'call' that takes one of the possible types in JSON document (a number, a string, an array, a hash, or nil) and returns a more useful representation thereof (potentially wrapping it in some subclass of EmbeddedDocument).</b><br />
<br />
Now we can define an identity embedder (something that returns a value as-is, without any transformations) which we will be using for scalar values such as numbers, strings, and nil.<br />
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">
</span></span></pre>
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">scalar</span></span>
lambda {<span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"> </span>|<span class="variable variable_other variable_other_block variable_other_block_ruby">x</span>| x }
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span></pre>
<br />
This takes care of #2.<br />
<br />
We can define some common transformations in a similar way, and take care of #3. We will define one for date to serve as an example.<br />
<br />
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">date</span></span>
lambda {<span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"> </span>|<span class="variable variable_other variable_other_block variable_other_block_ruby">x</span>| <span class="support support_class support_class_ruby" style="color: #003366; font-weight: bold;">Date</span>.parse(x) }
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span></pre>
<br />
We will deal with #4 in two steps.<br />
<br />
Step 1: We will make Class object associated with every EmbeddedDocument an embedder too. i.e. it will have a 'call' method that takes in parsed data and returns an instance wrapping it.<br />
<br />
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;">EmbeddedDocument<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby" style="color: #003366;"> < Struct.new</span></span></span>(<span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600;">:data</span>)
<span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">self.call</span>(<span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">value</span>)</span>
<span class="variable variable_language variable_language_ruby" style="color: #003388; font-weight: bold;">self</span>.<span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby" style="color: #008800; font-weight: bold;">new</span>(value)
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span></pre>
<br />
Step 2: We will now define a couple of functions that take one embedder and return another one. This is a very powerful technique from functional programming called "combinatory design". What we are defining below can be referred to as "embedder combinators".<br />
<br />
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">sequence_of</span>(<span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">e</span>)</span>
lambda {<span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"> </span>|<span class="variable variable_other variable_other_block variable_other_block_ruby">array</span>|
array.map {|<span class="variable variable_other variable_other_block variable_other_block_ruby">x</span>| e.call(x)}
}
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">defaulted</span>(<span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">e, default</span>)</span>
lambda {<span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"> </span>|<span class="variable variable_other variable_other_block variable_other_block_ruby">value</span>|
value.nil? <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby">?</span> default : e.call(value)
}
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span></pre>
<br />
Let's define a method 'key' which will allow us to specify a key name and embedder to be used.<br />
<br />
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;">EmbeddedDocument<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby" style="color: #003366;"> < Struct.new</span></span></span>(<span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600;">:data</span>)
<span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">self.key</span>(<span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">name, embedder</span>)</span>
embedder.call(<span class="variable variable_language variable_language_ruby" style="color: #003388; font-weight: bold;">self</span>.data[name])
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">self.call</span>(<span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">value</span>)</span>
<span class="variable variable_language variable_language_ruby" style="color: #003388; font-weight: bold;">self</span>.<span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby" style="color: #008800; font-weight: bold;">new</span>(value)
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span></pre>
<br />
We have all the machinery ready! This is how our original classes will look like with the new utility:<br />
<br />
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;">Delivery<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby" style="color: #003366;"> < EmbeddedDocument</span></span></span>
<span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">customer</span></span>
key(<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'customer'</span>, scalar)
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">ship_date</span></span>
key(<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'shipDate'</span>, date)
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;">Item<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby" style="color: #003366;"> < EmbeddedDocument</span></span></span>
<span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">product</span></span>
key(<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'product'</span>, scalar)
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">quantity</span></span>
key(<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'quantity'</span>, scalar)
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;">Order<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby" style="color: #003366;"> < EmbeddedDocument</span></span></span>
<span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">deliveries</span></span>
key(<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'deliveries'</span>, sequence_of(<span class="variable variable_other variable_other_constant variable_other_constant_ruby" style="color: #003366; font-weight: bold;">Delivery</span>))
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">items</span></span>
key(<span class="string string_quoted string_quoted_single string_quoted_single_ruby" style="color: #dd2200;">'items'</span>, sequence_of(<span class="variable variable_other variable_other_constant variable_other_constant_ruby" style="color: #003366; font-weight: bold;">Item</span>))
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">quantity_for</span>(<span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">a_product</span>)</span>
item <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> items.detect{|<span class="variable variable_other variable_other_block variable_other_block_ruby">i</span>| a_product <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby">==</span> i.product}
item <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby">?</span> item.quantity : <span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;">0</span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span></pre>
<br />
Beautiful, isn't it? :-)<br />
<br />
But this is Ruby. We can do even better! Here are a couple of ways we can improve upon the above solution:<br />
<ol>
<li>Define a method on EmbeddedDocument's Class that will take only absolute essentials, and define a JSON accessor method for us.</li>
<li>We have many cases above wherein a field access is a simple look-up in the wrapped hash and nothing more. Why not put method_missing to a good use here?</li>
</ol>
Here's what our EmbeddedDocument class looks like after above improvements:<br />
<br />
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;">EmbeddedDocument<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby" style="color: #003366;"> < Struct.new</span></span></span>(<span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600;">:data</span>)
<span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">self.key</span>(<span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">name, embedder, accessor_name <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="constant constant_language constant_language_ruby" style="color: #003388; font-weight: bold;">nil</span></span>)</span>
name <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> name.to_s
accessor_name <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby">||=</span> name
define_method(accessor_name) <span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby" style="color: #008800; font-weight: bold;">do</span>
embedder.call(<span class="variable variable_language variable_language_ruby" style="color: #003388; font-weight: bold;">self</span>.data[name])
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">self.call</span>(<span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">value</span>)</span>
<span class="variable variable_language variable_language_ruby" style="color: #003388; font-weight: bold;">self</span>.<span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby" style="color: #008800; font-weight: bold;">new</span>(value)
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">method_missing</span>(<span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">sym</span>)</span>
<span class="variable variable_language variable_language_ruby" style="color: #003388; font-weight: bold;">self</span>.data[sym.to_s]
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span></pre>
<br />
Use:<br />
<br />
<pre class="sunburst" style="background-color: white; font-family: Inconsolata, Inconsolata, Monaco, Consolas, 'Courier New', monospace; font-size: 14px; line-height: 18.1875px; margin-top: 0em;"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;">Item<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby" style="color: #003366;"> < EmbeddedDocument</span></span></span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;">Delivery<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby" style="color: #003366;"> < EmbeddedDocument</span></span></span>
key <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600;">:shipDate</span>, date, <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600;">:ship_date</span>
key <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600;">:items</span>, sequence_of(<span class="variable variable_other variable_other_constant variable_other_constant_ruby" style="color: #003366; font-weight: bold;">Item</span>)
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby" style="color: #008800; font-weight: bold;">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby" style="color: #bb0066; font-weight: bold;">Order<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby" style="color: #003366;"> < EmbeddedDocument</span></span></span>
key <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600;">:deliveries</span>, sequence_of(<span class="variable variable_other variable_other_constant variable_other_constant_ruby" style="color: #003366; font-weight: bold;">Delivery</span>)
key <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby" style="color: #aa6600;">:items</span>, sequence_of(<span class="variable variable_other variable_other_constant variable_other_constant_ruby" style="color: #003366; font-weight: bold;">Item</span>)
<span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby" style="color: #008800; font-weight: bold;">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby" style="color: #0066bb; font-weight: bold;">quantity_for</span>(<span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">a_product</span>)</span>
item <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> items.detect{|<span class="variable variable_other variable_other_block variable_other_block_ruby">i</span>| a_product <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby">==</span> i.product}
item <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby">?</span> item.quantity : <span class="constant constant_numeric constant_numeric_ruby" style="color: #0000dd; font-weight: bold;">0</span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span>
<span class="keyword keyword_control keyword_control_ruby" style="color: #008800; font-weight: bold;">end</span></pre>
<br />
This is even more concise and beautiful I am sure you would agree. :-)<br />
<br />
You might wonder what use is 'scalar' embedder now that we have played the 'method_missing' card. The answer is that it's still useful, not by itself, but in conjunction with combinators. e.g. defaulted(scalar, 0)<br />
<br />
You can find the full code <a href="https://gist.github.com/missingfaktor/6018320" target="_blank">here</a>.<br />
<br />
Well that's it. I hope you find the post interesting and useful. I am quite new to Ruby (as I am sure reflects from my code), so any suggestions, criticism, and other sort of feedback is most welcome.<br />
<br />
<b>Note:</b> The app I talked about before is in Scala, not Ruby. I developed this utility first in Scala and then ported it to Ruby. Of course the semantics and abstractions provided by the two languages are quite different, and thus the two implementations have some key differences. You can find my Scala implementation <a href="https://gist.github.com/missingfaktor/6018346" target="_blank">here</a>.<br />
<br />
<br /></div>
</div>
</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-23113246816149506432013-04-13T03:28:00.001+05:302013-04-13T03:29:11.606+05:30OpenStruct, a dynamic object utility for Scala<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Ruby standard library has a nice little utility named <a href="http://ruby-doc.org/stdlib-2.0/libdoc/ostruct/rdoc/OpenStruct.html" style="color: #1155cc;">OpenStruct</a> which gives you objects on which you can dynamically add and remove fields. .NET framework added a similar class named <a href="http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx" style="color: #1155cc;">ExpandoObject</a> in its version 4.5. </div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
With version 2.10, Scala has the necessary machinery required to support this kind of utility, so I went ahead and wrote it!</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">This utility supports the standard features supported by Ruby's </span><span style="font-family: courier new, monospace;">OpenStruct</span><span style="font-family: arial, helvetica, sans-serif;"> and .NET's </span><span style="font-family: courier new, monospace;">ExpandoObject</span><span style="font-family: arial, helvetica, sans-serif;">, but also supports </span><span style="font-family: arial, helvetica, sans-serif;">a couple more features in addition:</span></div>
<div class="gmail_default" style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">1. You can define an </span><span style="font-family: courier new, monospace;">OpenStruct</span><span style="font-family: arial, helvetica, sans-serif;"> with an underlying object. All field accesses and method invocations are first delegated to this object. If the field/method is not found in the underlying object, the map backing this </span><span style="font-family: courier new, monospace;">OpenStruct</span><span style="font-family: arial, helvetica, sans-serif;"> will be consulted.</span></div>
<div class="gmail_default" style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">2. You can optionally have the results of field updates and method invocations wrapped in an </span><span style="font-family: courier new, monospace;">OpenStruct</span><span style="font-family: arial, helvetica, sans-serif;">. This lets you chain dynamic field accesses and method calls nicely. This however is not set as default due to some issues.</span></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
<br /></div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
Lessons learned in this project:</div>
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
1. TDD is pretty awesome. It gives you a clear idea of what you're building and dictates your design choices in such a way that they result in looser coupling and better testability. The extra time spent writing test specifications, at least in this project, paid off well.</div>
<div class="gmail_default" style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">2. I can't get myself to like the Scala reflection library. It's tedious, unintuitive, verbose, bug-ridden, and thread-unsafe. The last bit caused several surprises during test execution, which went away when I added a </span><span style="font-family: courier new, monospace;">sequential</span><span style="font-family: arial, helvetica, sans-serif;"> flag in my Specs2 specifications. I think it's a wonder that I was able to get Scala reflection work for me at all.</span></div>
<div class="gmail_default" style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">3. Scala's local </span><span style="font-family: courier new, monospace;">return</span><span style="font-family: arial, helvetica, sans-serif;"> and </span><span style="font-family: courier new, monospace;">break</span><span style="font-family: arial, helvetica, sans-serif;"> are implemented using exceptions. This can lead to strange surprises when using them in blocks that catch exceptions. Watch out for such situations.</span></div>
<div class="gmail_default" style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">4. </span><span style="font-family: courier new, monospace;">trait</span><span style="font-family: arial, helvetica, sans-serif;">s with smart constructors (read: factories in companion objects) are in general preferable to </span><span style="font-family: courier new, monospace;">class</span><span style="font-family: arial, helvetica, sans-serif;">es.</span></div>
<div class="gmail_default" style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default" style="font-family: arial;">
<div class="gmail_default" style="font-family: arial, helvetica, sans-serif;">
The project is hosted here - <a href="https://github.com/missingfaktor/OpenStruct">https://github.com/missingfaktor/OpenStruct</a>. Any kind of feedback and contributions are welcome.</div>
<div>
<br /></div>
</div>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com0tag:blogger.com,1999:blog-1586964767032798423.post-41542750601730959382012-11-04T18:02:00.001+05:302012-11-04T22:15:44.436+05:30Something to be said for dynamic typing<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="color: black;"><span style="font-family: inherit;">I recently answered a question on Quora, titled "What is something possible in duck type programming, which is not possible in Scala?". (Note: The title was later edited by the OP.) I took time to provide what I think is a good response. I am embedding it here so that more people benefit from it.</span></span><br />
<div>
<div>
<span style="font-family: inherit;"><br />
By the way, if this topic interests you, then you might also want to read Chris Smith's <a href="http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html">"What to know before debating type systems"</a>. (If you haven't already read it, that is.)</span><br />
<div style="font-family: arial;">
<span style="font-size: x-small;"><br /></span></div>
</div>
</div>
</div>
<span class="quora-content-embed" data-name="Programming-Languages/What-is-something-possible-in-dynamic-type-programming-which-is-not-possible-in-Scala/answer/Rahul-Goma-Phulore/quote/108440"><span style="font-size: x-small;">Read <a class="quora-content-link" data-embed="6bRzKZ2" data-height="1469" data-id="108440" data-key="1b45be599382dda355c2e0193db4ca37" data-type="quote" data-width="575" href="http://www.quora.com/Programming-Languages/What-is-something-possible-in-dynamic-type-programming-which-is-not-possible-in-Scala/answer/Rahul-Goma-Phulore/quote/108440">Quote of Rahul Goma Phulore's answer to Programming Languages: What is something possible in dynamic type programming, which is not possible in Scala?</a> on <a href="http://www.quora.com/">Quora</a></span><script src="http://www.quora.com/widgets/content" type="text/javascript"></script></span>
</div>
Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com2tag:blogger.com,1999:blog-1586964767032798423.post-72015475654818989322012-07-23T04:48:00.000+05:302012-07-23T12:00:02.950+05:30Stacking up Factor against Lisp bullet list<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<div style="font-family: arial; font-size: small; text-align: -webkit-auto;">
Out of a whim, I retook <a href="http://factorcode.org/">Factor</a> yesterday. By some coincidence, <a href="https://twitter.com/old_sound">Alvaro Videla</a> also happened to retake it at about the same time. In a twitter conversation on the topic, he asked a couple of interesting questions. Since twitter is not a suitable medium for elaborate discussions, I am posting my responses here.</div>
<div style="font-family: arial; font-size: small; text-align: -webkit-auto;">
<br />
Note that I am only a beginner in Factor, and I am trying to answer the questions on the basis of whatever little I know. If there are any errors in this post, please feel free to correct.<br />
<br />
<b><a href="https://twitter.com/old_sound/status/227124152442687488">Q: What's your take on Factor macros vs Lisp ones?</a></b><br />
<br />
<b>A:</b> <a href="http://docs.factorcode.org/content/article-macros.html">Factor macros</a> have considerably simpler semantics. Thanks to "<a href="http://concatenative.org/wiki/view/Concatenative%20language">concatenativity</a>", macro expansion simply involves splicing a sequence. Nothing more. Thanks to the same property, Factor macros, unlike their Lisp counterparts, compose.<br />
<br />
One downside I can think of is that Factor macros provide no mechanism for maintaining hygiene. You are on your own. Probably because relying on named cells isn't in the vein of the language. Or probably it was just an oversight. I don't know. (Perhaps I should pop the question to the wizards at #concatenative.)<br />
<br />
Note that macros aren't used very often in Factor. Factor uses <a href="http://docs.factorcode.org/content/article-parsing-words.html">parsing words</a> for most things that Lisps use macros for. (Parsing words are kind of like reader macros.) Compare <a href="http://docs.factorcode.org/content/word-TUPLE__colon__,roles.html">TUPLE:</a> vs <a href="http://clojuredocs.org/clojure_core/clojure.core/defrecord">defrecord</a>, <a href="http://docs.factorcode.org/content/word-GENERIC__colon__%2Cmulti-methods.html">GENERIC:</a> vs <a href="http://clojuredocs.org/clojure_core/clojure.core/defmulti">defmulti</a>, <a href="http://docs.factorcode.org/content/word-USING__colon__,syntax.html">USING:</a> vs <a href="http://clojuredocs.org/clojure_core/clojure.core/use">use</a> etc.<br />
<br />
<b><a href="https://twitter.com/old_sound/status/227124251185016832">Q: If you compare Lisp vs Factor in the Paul Graham sense, what do you think?</a></b><br />
<br />
<b>A:</b> Comparing against <a href="http://paulgraham.com/diff.html">this list</a>:<br />
<ol>
<li><b>Conditionals:</b> Check.</li>
<li><b>Function types:</b> Check. In Factor parlance, functions are called words. Words are simply named quotations; quotations are sequences; sequences are data. So even function "contents" are first class values. Ergo, in this respect, it goes even further than Lisp. This enables crazy things like <a href="http://docs.factorcode.org/content/article-inverse,intro.html">invertible quotations</a>. </li>
<li><b>Recursion:</b> Check. <a href="http://docs.factorcode.org/content/article-tail-call-opt.html">With full TCO</a>. Note that in Factor you rarely use recursion directly in your code. Sequence combinators can usually achieve the same ends in a more elegant manner.</li>
<li><b>Variables 2.0:</b> Check.</li>
<li><b>GC:</b> Check.</li>
<li><b>Programs composed of expressions:</b> Check. </li>
<li><b>Symbols:</b> Check. </li>
<li><b>A notation for code using tree of symbols:</b> Irrelevant.</li>
<li><b>The whole language always available:</b> Check.</li>
</ol>
Factor meets all key stated goals of Lisp. There are many similarities between the two. You can see a clear Lisp influence in many aspects of Factor. Even so, it is not a Lisp. </div>
<div style="font-family: arial; font-size: small; text-align: -webkit-auto;">
<br /></div>
<div style="font-family: arial; font-size: small; text-align: -webkit-auto;">
The stack model is quite different from Lisp's inside-out model. It necessitates things like <a href="http://docs.factorcode.org/content/vocab-make.html">make</a> and <a href="http://docs.factorcode.org/content/vocab-fry.html">fry</a>, not required in Lisp. <a href="http://concatenative.org/wiki/view/Concatenative%20language/Rest%20parameters">Rest parameters</a> have no meaning in a stack language context, and so it's a common idiom to define words specialized for arities upto a certain value (usually 3) and a general word that operates on a sequence. <a href="http://concatenative.org/wiki/view/Concatenative%20language/Keyword%20parameters">Keyword arguments don't exist either.</a> (On the other hand, there are plentiful advantages to the stack model as listed on concatenative.org.)</div>
<div style="font-family: arial; font-size: small; text-align: -webkit-auto;">
<br />
More importantly, Factor is concatenative whereas Lisp is applicative. What this means is that Factor doesn't have lambdas as part of the language. Nor let bindings. (There exists a <a href="http://docs.factorcode.org/content/vocab-locals.html">library support for both</a> but they desugar to <a href="http://en.wikipedia.org/wiki/Tacit_programming">tacit expressions</a>.) So, no connection with lambda calculus. Factor is more in line with Backus' <a href="http://www.cs.cmu.edu/~crary/819-f09/Backus78.pdf">function-level programming</a> than with lambda calculus, although the official Factor site and blog do not appear to touch upon these topics.</div>
<div style="font-family: arial; font-size: small; text-align: -webkit-auto;">
<br /></div>
<div style="font-family: arial; font-size: small; text-align: -webkit-auto;">
For what it's worth, on my personal awesomeness scale, Factor lies way above Lisp. </div>
<div style="font-family: arial; font-size: small; text-align: -webkit-auto;">
<br /></div>
<div style="font-family: arial; font-size: small; text-align: -webkit-auto;">
<b>Recommended reading:</b></div>
<div style="font-family: arial; text-align: -webkit-auto;">
<ul style="font-size: small;">
<li><a href="http://jedahu.blogspot.in/2010/08/why-i-like-factor.html">Why I like Factor</a></li>
</ul>
<div style="font-size: small;">
<span style="color: #333333; font-family: arial, helvetica, sans-serif; line-height: 18px;">- γ</span></div>
</div>
</div>Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com5tag:blogger.com,1999:blog-1586964767032798423.post-42946990325274708922012-07-11T15:14:00.000+05:302012-07-12T01:39:01.716+05:30A tour through the Land of Lisp<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<div style="font-size: small; text-align: -webkit-auto;">
<div class="separator" style="clear: both; font-family: arial; text-align: center;">
<a href="http://upload.wikimedia.org/wikipedia/commons/6/64/Lisplogo_alien_256.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://upload.wikimedia.org/wikipedia/commons/6/64/Lisplogo_alien_256.png" /></a></div>
<div style="font-family: arial;">
<span style="border-collapse: separate; border-spacing: 0px;"><span style="font-family: arial, helvetica, sans-serif;"><br /></span></span></div>
<div style="font-family: arial;">
<span style="border-collapse: separate; border-spacing: 0px;"><span style="font-family: arial, helvetica, sans-serif;"><br /></span></span></div>
<div style="font-family: arial;">
<span style="border-collapse: separate; border-spacing: 0px;"><span style="font-family: arial, helvetica, sans-serif;">In this blog entry, I am only going to describe one of my learning experiences from past few weeks. No programming pearl today.</span></span></div>
<div style="font-family: arial;">
<span style="border-collapse: separate; border-spacing: 0px;"><span style="font-family: arial, helvetica, sans-serif;"><br /></span></span></div>
<div style="font-family: arial;">
<span style="border-collapse: separate; border-spacing: 0px;"><span style="font-family: arial, helvetica, sans-serif;">About a year ago or so, I learnt about this book named <a href="http://landoflisp.com/" target="_blank">Land of Lisp</a>. The website is just amazing, and I was mighty impressed after going through the video and the comics on the front page. I decided to get the book. Here are some reasons for why I made that decision:</span></span></div>
<div style="font-family: arial;">
<ol>
<li><span style="font-family: arial, helvetica, sans-serif;">I am a big fan of Head First series from O'Reilly, and this book follows a similar <i>hat ke</i> style.</span></li>
<li><span style="font-family: arial, helvetica, sans-serif;">I worked through some Clojure books two years ago, and a lot of things in Clojure come from Common Lisp. Learning their historic roots often helps me understand concepts much better.</span></li>
<li><span style="font-family: arial, helvetica, sans-serif;">I wanted to learn about reader macros, CLOS, and condition system - three things not present in Clojure. (Well, the condition system <a href="http://richhickey.github.com/clojure-contrib/condition-api.html" target="_blank">is available as an external library</a>, but I came to know that only recently.)</span></li>
<li><span style="font-family: arial, helvetica, sans-serif;">I wanted to learn about continuations. I know that it's a Scheme thing, but the site makes a mention of it (see the "guilds" at bottom), and so I presumed the book covers that.</span></li>
</ol>
</div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">I got the book, and started working through it a couple of weeks ago. I decided to port the examples to Clojure as I read. </span></div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">The first six chapters are introductory level, and quite slow-paced. Head First series books are similarly slow-placed, but at the time when I read them, I was just getting started with the whole programming thing, and so the pace suited me, but it doesn't any more. </span></div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: arial, helvetica, sans-serif;">In seventh chapter, we create a small graph-util library that draws graphs from the given information using <a href="http://www.graphviz.org/" target="_blank">graphviz</a>. (Sidenote: I have ported it to Clojure, and put it up <a href="https://github.com/missingfaktor/loclj-graph-util" target="_blank">on github</a> for your reading and forking pleasure.) This chapter is where my gripes about the language start. To represent the nodes, author uses a list of lists. Each nested item represents a node, with the items in cells corresponding the attributes of a node. Edges are represented in a bit more complicated manner - with a list of lists, which again contain some more lists. The problem gets worse during processing where some of the functions use </span><span style="font-family: 'courier new', monospace;">maplist</span><span style="font-family: arial, helvetica, sans-serif;"> on edges' list and therefore have to deal with a nested structure of depth 4. No attributes are named (i.e. records, maps aren't used), and so processing code is littered with calls to </span><span style="font-family: 'Courier New', Courier, monospace;">cdar, caadr, cadar</span><span style="font-family: arial, helvetica, sans-serif;"> etc. It took me over a day to understand one of the functions from the undirected graphs section. I don't know about you, but I really really dislike this kind of code.</span></div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">In eighth chapter, we create a game named Grand Theft Wumpus. I flipped through the chapter to take a look at the code, and my fear turned out to true. The code employs the same kind of list processing style that caused me headache in the previous chapter. I gave up my resolve of working seriously through the text, and decided to only skim through the rest of the book.</span></div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">A quick overview of rest of the book: The chapter on generic programming is nice. Clojure also has that feature - under a name multimethods, and it is even more powerful thanks to the ability of dispatching on arbitrary predicates. The author appears to be confused about the distinction between records and objects, and tends to refer to any use of records as OOP style. The coverage of CLOS is not as in-depth as I would like. I skipped the next few chapters on </span><span style="font-family: 'courier new', monospace;">loop</span><span style="font-family: arial, helvetica, sans-serif;"> macro, </span><span style="font-family: 'courier new', monospace;">format</span><span style="font-family: arial, helvetica, sans-serif;"> facility, streams, condition system etc. I am already well versed with functional style of programming, so I skipped the chapters on that as well. The chapters on macros and DSL were enjoyable, and provided some motivating examples for macros. And as it turns out, the book does not cover continuations, which was a bit of a disappointment. </span></div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">Overall, it's a good book if you want to learn the basics of Common Lisp in a fun way. However, if your goals are similar to mine (the ones that I mentioned in the beginning), there is not much you're going to gain from this book.</span></div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">Now a few complaints about the language itself (with some side-by-side Clojure comparisons):</span></div>
<div>
<ol>
<li style="font-family: arial;"><span style="font-family: arial, helvetica, sans-serif;">It's a Lisp-2. The topic of Lisp-2 vs Lisp-1 is perhaps as contentious in the Lisp community as static vs dynamic is in the PLT community. So I'll say this: <i>I prefer </i>Lisp-1. I understand that both approaches have their merits and drawbacks, and it ultimately comes down to what trade-offs one is ready to settle for. My choices lead me to the path of Lisp-1.</span></li>
<li><span style="font-family: arial, helvetica, sans-serif;">Non-descriptive, cryptic, and possibly misleading identifier names. Without firing a Google search, can you tell me what </span><span style="font-family: 'courier new', monospace;">princ</span><span style="font-family: arial, helvetica, sans-serif;">, </span><span style="font-family: 'courier new', monospace;">prin1</span><span style="font-family: arial, helvetica, sans-serif;">, and </span><span style="font-family: 'courier new', monospace;">progn</span><span style="font-family: arial, helvetica, sans-serif;"> stand for? Quick, what do you guess </span><span style="font-family: 'courier new', monospace;">labels</span><span style="font-family: arial, helvetica, sans-serif;"> macro does? What do you think </span><span style="font-family: 'courier new', monospace;">assoc</span><span style="font-family: arial, helvetica, sans-serif;"> function does? In what ways do you think </span><span style="font-family: 'courier new', monospace;">equalp, equal, eql,</span><span style="font-family: arial, helvetica, sans-serif;"> and </span><span style="font-family: 'courier new', monospace;">eq</span><span style="font-family: arial, helvetica, sans-serif;"> differ from each other? What about </span><span style="font-family: 'courier new', monospace;">mapc, maplist,</span><span style="font-family: arial, helvetica, sans-serif;"> and </span><span style="font-family: 'courier new', monospace;">mapl</span><span style="font-family: arial, helvetica, sans-serif;">? Then there is this </span><span style="font-family: 'courier new', monospace;">remove-if-not</span><span style="font-family: arial, helvetica, sans-serif;"> function which is a double negation, and could instead have been named </span><span style="font-family: 'Courier New', Courier, monospace;">retain</span><span style="font-family: arial, helvetica, sans-serif;">. I could go on and on. I agree that when programming functionally one often needs to invent a new vocabulary, but I am of the opinion that these neologisms must be chosen carefully and not be misleading. Common Lisp falls flat on its face in this regard. </span></li>
<li style="font-family: arial;"><span style="font-family: arial, helvetica, sans-serif;">Truthiness semantics are simple (</span><span style="font-family: 'courier new', monospace;">nil</span><span style="font-family: arial, helvetica, sans-serif;"> is false, everything else is true), and lead to an elegant programming style where one can just return computed values instead of true and false. However it has some peculiar corner cases, which make one question the worthiness of this style. Again, I concede that this is subjective matter, and depending on what trade-offs one finds more acceptable, one can have an opinion different from mine.</span></li>
<li style="font-family: arial;"><span style="font-family: arial, helvetica, sans-serif;">Equality in Common Lisp is a complete mess. There are functions like </span><span style="font-family: 'courier new', monospace;">eq, eql, equal, equalp, =</span><span style="font-family: arial, helvetica, sans-serif;"> etc. (You can look up the online references if you wish to learn about how they differ from each other.) Clojure gets this right: </span><span style="font-family: 'courier new', monospace;">=</span><span style="font-family: arial, helvetica, sans-serif;"> for value equality, </span><span style="font-family: 'courier new', monospace;">identical?</span><span style="font-family: arial, helvetica, sans-serif;"> for referential equality. That's all.</span></li>
<li style="font-family: arial;"><span style="font-family: 'courier new', monospace;">let*</span><span style="font-family: arial, helvetica, sans-serif;"> macro. Quetzalcoatl knows why the ability of binding sequentially is not present it </span><span style="font-family: 'courier new', monospace;">let</span><span style="font-family: arial, helvetica, sans-serif;"> itself. (There is some discussion in <a href="http://stackoverflow.com/questions/554949/let-versus-let-in-common-lisp">this stackoverflow thread</a>.) Clojure <a href="http://clojure.org/special_forms#Special%20Forms--(let%20%5Bbindings*%20%5D%20exprs*)">gets this right</a>, too.</span></li>
<li style="font-family: arial;"><span style="font-family: 'courier new', monospace;">loop</span><span style="font-family: arial, helvetica, sans-serif;"> macro. I think this one is just horrible. Why anyone thought this would be a good idea is beyond me.</span></li>
<li style="font-family: arial;"><span style="font-family: arial, helvetica, sans-serif;">Multiple return values. The semantics are complicated, and not worth the gain. One can just return lists/vectors, which is what Arc and Clojure do.</span></li>
<li style="font-family: arial;"><span style="font-family: arial, helvetica, sans-serif;">As I mentioned before, processing lists with </span><span style="font-family: 'courier new', monospace;">cadr, cdar, caddr</span><span style="font-family: arial, helvetica, sans-serif;"> etc is a pain. Clojure has destructuring which makes list processing way more pleasant. Also, when appropriate, Clojure encourages use of maps and records over lists, which adds to code clarity.</span></li>
<li style="font-family: arial;"><span style="font-family: arial, helvetica, sans-serif;">Setting up the environment is hard for neophytes (like me). IDEA (my preferred IDE), Eclipse, and Netbeans do not have plugins for Common Lisp. I set up Emacs and <a href="http://common-lisp.net/project/slime/">SLIME</a>. That took two days of yak-shaving. For building, I was going to get <a href="http://www.quicklisp.org/">Quicklisp</a> and <a href="http://common-lisp.net/project/asdf">asdf</a>, but I gave up in exasperation. This is a not a complaint about the language per se, but its ecosystem, and therefore an important one.</span></li>
</ol>
</div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">Common Lisp is a Lisp, and one could argue that some of my above complaints could be resolved with a bit of language-taming. But that's not the point. The above is the criticism of not the language alone, but also its standard library, its widespread conventions, its ecosystem, and to an extent, its community. Judging by all these factors, I am not impressed.</span></div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;"><br /></span></div>
<div style="font-family: arial;">
<span style="font-family: arial, helvetica, sans-serif;">As a side-effect, this book has left me with an added appreciation for Clojure and Rich Hickey. Clojure indeed simplifies a LOT of things from Common Lisp to make developers' lives easier (oops, I meant <a href="http://www.infoq.com/presentations/Simple-Made-Easy">simpler</a> ;-), and kudos to Rich Hickey for that.</span></div>
<div style="font-family: arial;">
<br /></div>
</div>
<div style="font-family: arial; font-size: small; text-align: -webkit-auto;">
<span style="font-family: arial, helvetica, sans-serif;">- γ</span></div>
</div>Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com4tag:blogger.com,1999:blog-1586964767032798423.post-74349416288487574842012-03-28T02:01:00.000+05:302012-03-28T02:04:45.919+05:30Composition with non-deterministic computations<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<div style="font-size: small;">
<span style="font-family: Arial, Helvetica, sans-serif;">A deterministic computation has a type </span><span style="font-family: 'Courier New', Courier, monospace;">A -> B</span><span style="font-family: Arial, Helvetica, sans-serif;">. It has input type </span><span style="font-family: 'Courier New', Courier, monospace;">A</span><span style="font-family: Arial, Helvetica, sans-serif;">, and result type </span><span style="font-family: 'Courier New', Courier, monospace;">B</span><span style="font-family: Arial, Helvetica, sans-serif;">. Only one result. Hence just </span><span style="font-family: 'Courier New', Courier, monospace;">B</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></div>
<div style="font-size: small;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="font-size: small;">
<span style="font-family: Arial, Helvetica, sans-serif;">If the computation however is non-determinstic, it would have several possible result values. Let us assume it returns all these possible values in a list. The type of the computation then would be </span><span style="font-family: 'Courier New', Courier, monospace;">A -> [B]</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></div>
<div style="font-size: small;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="font-size: small;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="font-size: small;">
<span style="font-family: Arial, Helvetica, sans-serif;">Now consider the following two scenarios involving deterministic computations:</span></div>
<div style="font-size: small;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="font-size: small;">
<span style="font-family: Arial, Helvetica, sans-serif;">1. </span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">You have two functions: </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">f :: A -> B</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">, and </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">g :: B -> C</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">. You have to apply </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">f</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"> followed by </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">g</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"> to a value of type </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">A</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">. That is, the function required would be: </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">(g . f)</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">.</span></div>
<div style="font-size: small;">
<span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"><br /></span></div>
<div style="font-size: small;">
<span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">2. You have three functions: </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">f :: A -> B</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">, </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">g :: C -> D</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">, </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">h :: B -> D -> E</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">. You have two values, </span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">one of type </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">A</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">, other of type </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">C</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">. You apply to them </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">f</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"> and </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">g</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"> respectively. And the two results you get, you pass them to </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">h</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">. i.e. </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">h (f a) (g c)</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">. </span></div>
<div style="font-size: small;">
<span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"><br /></span></div>
<div style="font-size: small;">
<span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">Or in a more verbose manner:</span></div>
<div style="font-size: small;">
<span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"><br /></span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="line-height: 18px;">let x = f a</span></span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="line-height: 18px;"> y = g b</span></span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="line-height: 18px;"> in h x y</span></span></div>
<div style="font-size: small;">
<span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"><br /></span></div>
<div style="font-size: small;">
<span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"><br /></span></div>
<div style="font-size: small;">
<span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">The </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">Applicative</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"> and </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">Monad</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"> instances for list are defined with the the non-deterministic computation view I talked about above. </span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">Let us see how they help us retain composability in the non-deterministic versions of the scenarios we just discussed:</span></div>
<div style="font-size: small;">
<span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"><br /></span></div>
<div style="font-size: small;">
<span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">1. Our functions now will be: </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">f :: A -> [B]</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"> and </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">g :: B -> [C]</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">. </span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">We have a value of type </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">A</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">. We need to apply </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">f</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"> to it. Then we will have a list of values of type </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">B</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">. We need to apply </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">g</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"> to each of those values. Then we will have </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">[[C]]</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">, which we will have to flatten to get </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">[C]</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">. List's </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">Monad</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"> instance already takes care of these steps, and thus the required function can be obtained with a simple composition: </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">g <=< f</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">.</span></div>
<div style="font-size: small;">
<span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"><br /></span></div>
<div style="font-size: small;">
<span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">2. We have three functions as before: </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">f :: A -> [B]</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">, </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">g :: C -> [D]</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">, and </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">h :: B -> D -> E</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;">. We can use </span><span style="background-color: white; line-height: 18px; text-align: -webkit-auto;"><span style="font-family: 'Courier New', Courier, monospace;">Applicative</span></span><span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"> functions here, as shown below:</span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="font-family: arial, sans-serif;"><span style="line-height: 18px;"><br /></span></span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="line-height: 18px;">h <$> (f a) <*> (g c)</span></span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="font-family: arial, sans-serif;"><span style="line-height: 18px;"><br /></span></span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="font-family: arial, sans-serif;"><span style="line-height: 18px;">Or use monadic syntax:</span></span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="font-family: arial, sans-serif;"><span style="line-height: 18px;"><br /></span></span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="line-height: 18px;">do </span><span style="line-height: 18px;">x <- f a</span></span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="line-height: 18px;"> y <- g b</span></span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="line-height: 18px;"> return h x y</span></span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="font-family: arial, sans-serif;"><span style="line-height: 18px;"><br /></span></span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="font-family: arial, sans-serif;"><span style="line-height: 18px;"><br /></span></span></div>
<div style="font-size: small; text-align: -webkit-auto;">
<span style="line-height: 18px;"><span style="font-family: arial, sans-serif;">Pretty close to their deterministic counterparts, aren't they? To learn more about the </span><span style="font-family: 'Courier New', Courier, monospace;">Applicative</span><span style="font-family: arial, sans-serif;"> and </span><span style="font-family: 'Courier New', Courier, monospace;">Monad</span><span style="font-family: arial, sans-serif;"> instances of list, you can refer to </span><a href="http://learnyouahaskell.com/functors-applicative-functors-and-monoids" style="font-family: arial, sans-serif;">this</a><span style="font-family: arial, sans-serif;"> and </span><a href="http://learnyouahaskell.com/a-fistful-of-monads" style="font-family: arial, sans-serif;">this</a><span style="font-family: arial, sans-serif;"> chapter from LYAH.</span></span></div>
<div style="font-size: small;">
<span style="background-color: white; font-family: arial, sans-serif; line-height: 18px; text-align: -webkit-auto;"><br /></span></div>
<div style="font-size: small;">
<span style="background-color: white; color: #333333; font-family: Arial, Helvetica, sans-serif; line-height: 19px;">- γ</span></div>
</div>Zimbabwe vgtjbkjkijhttp://www.blogger.com/profile/10950240139175717925noreply@blogger.com4