<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.razie.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-20018300</atom:id><lastBuildDate>Mon, 30 Jan 2012 23:41:39 +0000</lastBuildDate><category>dsl</category><category>bitching</category><category>design</category><category>cool</category><category>principle</category><category>scala</category><category>graph</category><category>architecture</category><category>agile</category><category>learning</category><category>software</category><category>evolution</category><title>RazBlog</title><description>Razie's ramblings...</description><link>http://blog.razie.com/</link><managingEditor>noreply@blogger.com (Razie)</managingEditor><generator>Blogger</generator><openSearch:totalResults>31</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.razie.com/Razblog" /><feedburner:info uri="razblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-6872595395615334034</guid><pubDate>Thu, 13 Oct 2011 21:16:00 +0000</pubDate><atom:updated>2011-10-26T15:19:58.438-04:00</atom:updated><title>OMG, scala is a complex language!</title><description>&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;NOTE that I cross-posted this to http://blog.coolscala.com/2011/10/omg-scala-is-complex-language.html&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Calibri;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Calibri;"&gt;I keep seeing this and, maybe it’s true. Let’s chase this complexity for a bit&amp;nbsp;and go through some of the biggest scala differentiators (from Java or C++, as major OO languages).&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;&lt;strong&gt;&lt;span style="color: orange;"&gt;Smart compiler infers types&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;The compiler can infer the types for the most part, so people have to type a lot less repetitive information, which they used to type in both Java and C++. For instance, since “john” is obviously a String, the type of the variable is inferred by the compiler to be String so I don’t have to type it again:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;val someone = “John”&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;I have seen this feature both praised and held against the language as “added complexity”, so I don’t know what to say. I just love typing less and feeling less stupid, every time I declare a value or variable.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;&lt;strong&gt;&lt;span style="color: orange;"&gt;Simplified class definitions&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;Since OO is all about defining classes, scala made do with a bunch of stuff in one go, so that my domain models are dead-simple:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;class Person (val firstName:String, val lastName:String)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;This, in Java and C++ takes about one page of code: with constructors, getters, setters etc. Scala observed that people don’t need to type one page to inform a stupid compiler that they want a person with a first and last names, so it’s all condensed in this one line, much like a table would look in SQL.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;Is this added complexity? Well, I do need to worry about overriding the generated getters/setters ONLY if I need to, so I don’t really know if it’s more complex.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;Me? I love this particular feature so much, that honestly, I don’t care what you think &lt;/span&gt;&lt;span style="font-family: Wingdings;"&gt;J&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;&lt;strong&gt;&lt;span style="color: orange;"&gt;Unifying methods and operators&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;All programming languages I know discriminate between methods with names like “&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;append&lt;/span&gt;” and operators like “&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;+=&lt;/span&gt;”. Some do not even allow re-definition of some hardcoded operators (Java) while some allow infix notation only for operators (C++).&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;Scala simply makes do with ALL these restrictions and states that the name of a method can be pretty much anything and all can use the infix notation, so I can have:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ListBuffer(1,2,3) append 4&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;As well as&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ListBuffer(1,2,3) += 4&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;The only difference would be the precedence rules, which are customary in all languages. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;Some people obviously would see this as “more complex” than both Java and C++ since they can now do whatever they can… but I see it as “simpler” than both. Operators have been held against C++ before so it really is not surprising that they are held against scala as well.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;This is, after all, what makes scala such as perfect DSL framework, allowing natural language such as:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;“Mary” with “a purse” and “red shoes” should look “nice”&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;&lt;strong&gt;&lt;span style="color: orange;"&gt;Types – variance&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;In both Java and C++, the generics have certain hard-coded and limited behavior (i.e. non-variance) and allow only a few constructs (like &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;List&amp;lt;T extends Person&amp;gt;&lt;/span&gt;). &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;In scala, there is a default behavior, where List[Person] is non-variant, but everything is customizable. If you want co-variance, just tell the compiler &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;List[+Person]&lt;/span&gt; or &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;List[-Person]&lt;/span&gt; for contra-variance. Just like Java, I can use &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;List[T &amp;lt;: Person]&lt;/span&gt; but I can use the reverse just as well: &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;List [T &amp;gt;: Person]&lt;/span&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;Since scala supports implicits (with finer control than C++), another construct is available: &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;List[T &amp;lt;% Person].&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;Is this more complicated? Well, just like the operators – it lifts certain limitations of other languages, so it’s both more complicated, since there’s more stuff to learn and simpler, since there’s less rules to live by.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;I personally enjoy the extra control… do I actually use it? Not on a daily basis, the defaults are good enough.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;&lt;strong&gt;&lt;span style="color: orange;"&gt;Constructors only?&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;Most languages only allow data types (objects) to be constructed. This is normal in Java and C++.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;Well, there’s the flipside, where I can de-construct an object and I don’t mean de-allocating its memory. Consider this:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: x-small;"&gt;someone match {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp; case Person(first,last) =&amp;gt; println (“ name is “ + first + ” “ + last)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: x-small;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;You can see what I mean by de-constructing: took an already created object, someone, and de-constructed into its components. I know this looks foreign to most OO personnel, but trust you me, it is insanely cool and useful. Think what you would have to type in either Java or C++ to achieve the same thing, with if (instanceof) and then type cast and assign two variables and whatnot.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;Is this more complex? Well, this is totally new functionality so I guess it is. But I love having it! Trust me, you will, too!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;By the way, the match/case construct is way more powerful than your regular switch/case which can only handle constants… we can de-construct types, match constants, match types… and more! Check this out:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: x-small;"&gt;someone match {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp; case Person(first,last) =&amp;gt; println (“ name is “ + first + ” “ + last)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp; case “John” |”Mary” =&amp;gt; println (“hello, “ + someone)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp; case s:String =&amp;gt; println (“name is “ + s)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp; case _ =&amp;gt; println (“don’t know what this is…”)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: x-small;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;Is this more complex? I don’t know… in Java or C++ this is between one and two pages of code. This looks simpler and more intuitive to me… granted, I got used to it but so can you!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;&lt;strong&gt;&lt;span style="color: orange;"&gt;Conclusion&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;There’s more areas of the language, but these are some of the major differences I have time for&amp;nbsp;right now. If you have others, post up and I’ll get into those as well.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;I did not get into the functional areas of the language, since that would require comparing with other functional languages and I’m not an FP guy. C++ comes close by allowing passing pointers to methods to other functions while Java 8 I think has some proposed lambda syntax.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;Is it more complex? Well, there’s two ways to look at it:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;&lt;strong&gt;Yes,&lt;/strong&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;There are more symbols and features that one can use&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: Calibri;"&gt;There’s more computer science I need to learn (contra-variance, pattern matching, lambdas, closures etc)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;&lt;strong&gt;No,&lt;o:p&gt;&lt;/o:p&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;The real-world problems to solve are the same and&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: Calibri;"&gt;To do the same in either Java or C++ is either impossible or takes many times more code… and uglier code at that&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;What do I think? I don’t really care. To me it was cool to learn these concepts that I had forgotten since university and my new vocabulary allows me to solve the usual problems in just a few lines of code and head for an early lunch, while my mates are still writing some getter or setter…&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;span style="font-family: Calibri;"&gt;What do you think?&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Calibri;"&gt;&lt;/span&gt;&lt;/div&gt;P.S. This is a great detaiked discussion of complex vs complicated: &lt;a href="http://lamp.epfl.ch/~odersky/blogs/isscalacomplex.html"&gt;http://lamp.epfl.ch/~odersky/blogs/isscalacomplex.html&lt;/a&gt;&lt;br /&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-6872595395615334034?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/WaS_hSjfCB4" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/WaS_hSjfCB4/omg-scala-is-complex-language.html</link><author>noreply@blogger.com (Razvan)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.razie.com/2011/10/omg-scala-is-complex-language.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-6665974598094695257</guid><pubDate>Thu, 13 Oct 2011 01:13:00 +0000</pubDate><atom:updated>2011-10-17T13:18:57.521-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">learning</category><category domain="http://www.blogger.com/atom/ns#">scala</category><title>Quick scala – step 1: setup</title><description>This post has a new home. If you want to setup a scala development environment, read: &lt;a href="http://blog.coolscala.com/2011/10/quick-scala-step-1-setup.html"&gt;http://blog.coolscala.com/2011/10/quick-scala-step-1-setup.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-6665974598094695257?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/jSsbxCtf5qA" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/jSsbxCtf5qA/quick-scala-step-1-setup.html</link><author>noreply@blogger.com (Razvan)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.razie.com/2011/10/quick-scala-step-1-setup.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-7878870245456542478</guid><pubDate>Wed, 17 Aug 2011 16:29:00 +0000</pubDate><atom:updated>2011-10-12T21:13:21.336-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">dsl</category><category domain="http://www.blogger.com/atom/ns#">scala</category><title>Scala DSL technique - if-else constructs</title><description>Believe it or not, I've had a hard time coming up with this construct, so I figured it's worth publishing it, maybe save others the hassle.
&lt;br /&gt;
&lt;br /&gt;
You want to come up with a recursive if/else construct, like below (I used a dollar sign to denote the DSL if - I've used wif/welse in the past - use whatever you want):
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;  var branch = 1

  val expr =

    $if(branch == 1) {

      v("a") := 11

      v("b") := 12

    } $else $if(branch == 2) {

      v("a") := 21

      v("b") := 22

    } $else $if(branch == 3) {

      v("a") := 31

      v("b") := 32

    } $else {

      v("a") := 41

      v("b") := 42

    }&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Note the recursive if-else-if-else-if-else. The idea is that the if/else token will modify its own else branch depending on the following else - either the final else {} or an else followed by an if:
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;  case class TIf(cond: () =&amp;gt; Boolean, body: () =&amp;gt; Unit, var elsebranch: Option[TElse] = None) extends Token("IF ") {

    val scope = TScope(body)

    def $else[T](body: =&amp;gt; T) = { this.lastif.elsebranch = Some(TElse(() =&amp;gt; body)); this }

    def $else(i: TIf) = {

      this.lastif.elsebranch = Some(TElseIf(i))

      this

    }

    def lastif = elsebranch.map(_.lastif).getOrElse(this)

    ...&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Also note that the way scala works is that the if-else tree is built from the top, so each else() is actually invoked on the root IF, therefore it needs to recursively find the last unbound IF and bind itself there as the elsebranch.
&lt;br /&gt;
&lt;br /&gt;
Having said that, find the full code and use it as a template, &lt;a href="https://github.com/razie/razbase/blob/master/base/src/test/scala/razie/dsl/test/DslCollectorIfElseTestSimple.scala"&gt;here&lt;/a&gt;.
&lt;br /&gt;
&lt;br /&gt;
Enjoy!
&lt;br /&gt;
&lt;br /&gt;
P.S. One issue with the simplified version built here is that it doesn't stop you from simple syntax errors like having an if-else-else... how would you fix it so the compiler stops you rather than the runtime exception?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-7878870245456542478?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/ZnFooLwJVNk" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/ZnFooLwJVNk/scala-dsl-technique-if-else-constructs.html</link><author>noreply@blogger.com (Razvan)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.razie.com/2011/08/scala-dsl-technique-if-else-constructs.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-7179654482155144997</guid><pubDate>Tue, 16 Aug 2011 16:43:00 +0000</pubDate><atom:updated>2011-08-16T13:07:19.550-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">dsl</category><category domain="http://www.blogger.com/atom/ns#">scala</category><title>A scala DSL technique - collecting</title><description>When coming up with a scala internal DSL, it is often that one will come up with constructs that produce things that need collected, in a list, tree or similar.
&lt;br /&gt;
&lt;br /&gt;For instance, instructions for a robot:
&lt;br /&gt;
&lt;br /&gt;&lt;pre&gt;$if (condition) {
&lt;br /&gt;  move(1) :: move(2) :: move(3) :: Nil
&lt;br /&gt;  move(1) + move(2) + move(3)
&lt;br /&gt;  }&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;Due to syntax restrictions, it is often that people use operators to chain these, like the overloaded + above.
&lt;br /&gt;
&lt;br /&gt;There is a technique you can use to make this look more familiar:
&lt;br /&gt;
&lt;br /&gt;&lt;pre&gt;$if (condition) {
&lt;br /&gt;  move(1)
&lt;br /&gt;  move(2)
&lt;br /&gt;  move(3)
&lt;br /&gt;  }&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;While not the nicest, the idea is to use a static collector and collect the actions in there. You'll need levels, so that collecting nested blocks don't interfere, so there is a stack of collectors. Also, these collectors need to be thread-local so that different collecting threads don't interfere.
&lt;br /&gt;
&lt;br /&gt;A reusable collector is in &lt;a href="https://github.com/razie/razbase/tree/master/base/src/main/scala/razie/dsl/DslCollector.scala"&gt;DslCollector.scala&lt;/a&gt; and a sample in &lt;a href="https://github.com/razie/razbase/blob/master/base/src/test/scala/razie/dsl/test/DslCollectorTest.scala"&gt;DslCollectorTest.scala&lt;/a&gt; 
&lt;br /&gt;
&lt;br /&gt;For this pattern, you have a Collector, a Collectable and the actual constructs:
&lt;br /&gt;
&lt;br /&gt;&lt;pre&gt;  case class move(i: Int) extends DslCollectable
&lt;br /&gt;
&lt;br /&gt;  def test1 = expect(move(1) :: move(2) :: Nil) {
&lt;br /&gt;    val collected = new collection.mutable.ListBuffer[Any]()
&lt;br /&gt;
&lt;br /&gt;    DslCollector.collect { collected += _ }(1) { // start a collector level
&lt;br /&gt;      move(1) //collects itself
&lt;br /&gt;      move(2) //collects itself
&lt;br /&gt;    } // collector ends
&lt;br /&gt;
&lt;br /&gt;    collected
&lt;br /&gt;  }&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;You can then embedd this in a higher-level construct of your DSL, like the &lt;code&gt;$if&lt;/code&gt; used in the example.
&lt;br /&gt;
&lt;br /&gt;Enjoy!
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-7179654482155144997?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/L1YbSBYd-bM" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/L1YbSBYd-bM/scala-dsl-technique-collecting.html</link><author>noreply@blogger.com (Razvan)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.razie.com/2011/08/scala-dsl-technique-collecting.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-3179273075877696107</guid><pubDate>Tue, 05 Apr 2011 18:17:00 +0000</pubDate><atom:updated>2011-06-24T11:43:40.242-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">bitching</category><title>My worst internet shopping experience - gogglesgiant.com</title><description>My worst internet shopping experience, by far, has been with GogglesGiant.com , trying to get replacement goggles for my son's ski goggles, in the middle of the season.Order two pairs, in early February, from their online store at gogglesgiant.com, promises of fast shipping etc.&lt;br /&gt;&lt;br /&gt;After two weeks I ask them that I haven't' seen a shipping notice and what's the delay and they reply that there's a high order volume and will ship when they can! Seriously, I will forward anyone their email!&lt;br /&gt;&lt;br /&gt;I know I should've asked for the order to be cancelled right there, but I can't take a hint, eh?&lt;br /&gt;&lt;br /&gt;After another week I receive a shipment notice with no tracking number. After another 3 weeks I receive the package, for a grand total of 6 weeks.&lt;br /&gt;&lt;br /&gt;By now is late March and the season is basically over!&lt;br /&gt;&lt;br /&gt;Done? Nope.They screw up and send me the wrong size for one of the lens. I write them back with a photo of the SKU and get ignored! After 1 week, I write again and receive this reply: mail us back the wrong lens and we will refund the cost of the lens. They refuse to send me the right lens, will just refund the cost, without shipping charges.&lt;br /&gt;&lt;br /&gt;Reason: "we can't modify the original order". Seriously? I know it sounds too hard to believe, but these guys are for real! Again, I will forward anyone their original emails!&lt;br /&gt;&lt;br /&gt;I get stuff shipped for free from Hong Kong in 3 weeks and these guys take 5-6 weeks! They refuse to make good on the order! It's insane, really! I would seriously suggest you look elsewhere for goggles. Ebay hasn't failed me yet. Actually this was the first time I strayed from Amazon and Ebay and I get screwed.&lt;br /&gt;&lt;br /&gt;Also, they are a Yahoo Store and theirs is the worse complaining and merchant rating system ever. I hope they go banckrupt. I will and you should avoid any so called Yahoo Store.&lt;br /&gt;&lt;br /&gt;I won't send them the wrong size only to get screwed again. I'll loose 40$ but I won't throw more good moneys after the bad.&lt;br /&gt;&lt;br /&gt;Again - Goggles Giant cost me 40$, send me the wrong size, didn't send the order until after the season was over and have the worse customer service online... who lies through their nose!&lt;br /&gt;&lt;br /&gt;Unfortunately I don't have a lot of recourse here. I can't even open a ticket with my credit card company because it has been like 9 weeks already now... smart buggers! Yahoo stores accept complaints only 6 weeks and after 30 minutes of browsing their website I can't even figure out how to rate this store or open a complaint!&lt;br /&gt;&lt;br /&gt;Argh!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-3179273075877696107?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/c41RN-ypWxc" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/c41RN-ypWxc/my-worst-internet-shopping-experience.html</link><author>noreply@blogger.com (Razvan)</author><thr:total>2</thr:total><feedburner:origLink>http://blog.razie.com/2011/04/my-worst-internet-shopping-experience.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-3537169067248362530</guid><pubDate>Fri, 21 Jan 2011 22:39:00 +0000</pubDate><atom:updated>2011-01-21T18:04:35.381-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">dsl</category><category domain="http://www.blogger.com/atom/ns#">scala</category><title>Scala DSL - realistic looking options</title><description>Trying to simulate the way options are passed to unix commands via '-'.&lt;br /&gt;&lt;br /&gt;The idea is to define a set of applicable flags and an - operator. The end result is being able to write this beauty:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;rm -r -f apply "gigi.file"&lt;/pre&gt;Without further ado, here's the sample code:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/790585.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;br /&gt;We're limiting the flags and making this type-safe with the Flag case class. If you had more types of commands, you could limit the actual flags for each of them with custom Flag classes.&lt;br /&gt;&lt;br /&gt;The main idea is counting on scala's &lt;a href="http://www.scala-lang.org/node/118"&gt;infix notation&lt;/a&gt;. The different flags accumulate in sequence and in the end, the resulting command (now with flags) is applied.&lt;br /&gt;&lt;br /&gt;The magic of the infix notation is revealed by this equivalent form:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;rm.-(r).-(f).apply("gigi.file")&lt;/pre&gt;Further things to consider:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;combining options&lt;/li&gt;&lt;li&gt;simplifying away the "apply" from the syntax&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This sample is available &lt;a href="https://github.com/razie/learnscala/blob/master/src/main/scala/razie/learn/dsl/fs1/CmdOptions.scala"&gt;here&lt;/a&gt; and I wrote it while playing with a unix-looking scala shell for file management: &lt;a href="https://github.com/razie/scalafs"&gt;https://github.com/razie/scalafs&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Have fun! &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-3537169067248362530?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/TwD1-FoapgI" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/TwD1-FoapgI/scala-dsl-realistic-looking-options.html</link><author>noreply@blogger.com (Razvan)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.razie.com/2011/01/scala-dsl-realistic-looking-options.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-2599043546108804333</guid><pubDate>Thu, 02 Dec 2010 16:29:00 +0000</pubDate><atom:updated>2010-12-02T11:32:31.236-05:00</atom:updated><title>Embracing change</title><description>&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;o:officedocumentsettings&gt;   &lt;o:allowpng/&gt;  &lt;/o:OfficeDocumentSettings&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:worddocument&gt;   &lt;w:view&gt;Normal&lt;/w:View&gt;   &lt;w:zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:trackmoves/&gt;   &lt;w:trackformatting/&gt;   &lt;w:punctuationkerning/&gt;   &lt;w:validateagainstschemas/&gt;   &lt;w:saveifxmlinvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:ignoremixedcontent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:alwaysshowplaceholdertext&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:donotpromoteqf/&gt;   &lt;w:lidthemeother&gt;EN-CA&lt;/w:LidThemeOther&gt;   &lt;w:lidthemeasian&gt;X-NONE&lt;/w:LidThemeAsian&gt;   &lt;w:lidthemecomplexscript&gt;X-NONE&lt;/w:LidThemeComplexScript&gt;   &lt;w:compatibility&gt;    &lt;w:breakwrappedtables/&gt;    &lt;w:snaptogridincell/&gt;    &lt;w:wraptextwithpunct/&gt;    &lt;w:useasianbreakrules/&gt;    &lt;w:dontgrowautofit/&gt;    &lt;w:splitpgbreakandparamark/&gt;    &lt;w:enableopentypekerning/&gt;    &lt;w:dontflipmirrorindents/&gt;    &lt;w:overridetablestylehps/&gt;   &lt;/w:Compatibility&gt;   &lt;m:mathpr&gt;    &lt;m:mathfont val="Cambria Math"&gt;    &lt;m:brkbin val="before"&gt;    &lt;m:brkbinsub val="&amp;#45;-"&gt;    &lt;m:smallfrac val="off"&gt;    &lt;m:dispdef/&gt;    &lt;m:lmargin val="0"&gt;    &lt;m:rmargin val="0"&gt;    &lt;m:defjc val="centerGroup"&gt;    &lt;m:wrapindent val="1440"&gt;    &lt;m:intlim val="subSup"&gt;    &lt;m:narylim val="undOvr"&gt;   &lt;/m:mathPr&gt;&lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:latentstyles deflockedstate="false" defunhidewhenused="true" defsemihidden="true" defqformat="false" defpriority="99" latentstylecount="267"&gt;   &lt;w:lsdexception locked="false" priority="0" semihidden="false" unhidewhenused="false" qformat="true" name="Normal"&gt;   &lt;w:lsdexception locked="false" priority="9" semihidden="false" unhidewhenused="false" qformat="true" name="heading 1"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 2"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 3"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 4"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 5"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 6"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 7"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 8"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 9"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 1"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 2"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 3"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 4"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 5"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 6"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 7"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 8"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 9"&gt;   &lt;w:lsdexception locked="false" priority="35" qformat="true" name="caption"&gt;   &lt;w:lsdexception locked="false" priority="10" semihidden="false" unhidewhenused="false" qformat="true" name="Title"&gt;   &lt;w:lsdexception locked="false" priority="1" name="Default Paragraph Font"&gt;   &lt;w:lsdexception locked="false" priority="11" semihidden="false" unhidewhenused="false" qformat="true" name="Subtitle"&gt;   &lt;w:lsdexception locked="false" priority="22" semihidden="false" unhidewhenused="false" qformat="true" name="Strong"&gt;   &lt;w:lsdexception locked="false" priority="20" semihidden="false" unhidewhenused="false" qformat="true" name="Emphasis"&gt;   &lt;w:lsdexception locked="false" priority="59" semihidden="false" unhidewhenused="false" name="Table Grid"&gt;   &lt;w:lsdexception locked="false" unhidewhenused="false" name="Placeholder Text"&gt;   &lt;w:lsdexception locked="false" priority="1" semihidden="false" unhidewhenused="false" qformat="true" name="No Spacing"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 1"&gt;   &lt;w:lsdexception locked="false" unhidewhenused="false" name="Revision"&gt;   &lt;w:lsdexception locked="false" priority="34" semihidden="false" unhidewhenused="false" qformat="true" name="List Paragraph"&gt;   &lt;w:lsdexception locked="false" priority="29" semihidden="false" unhidewhenused="false" qformat="true" name="Quote"&gt;   &lt;w:lsdexception locked="false" priority="30" semihidden="false" unhidewhenused="false" qformat="true" name="Intense Quote"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="19" semihidden="false" unhidewhenused="false" qformat="true" name="Subtle Emphasis"&gt;   &lt;w:lsdexception locked="false" priority="21" semihidden="false" unhidewhenused="false" qformat="true" name="Intense Emphasis"&gt;   &lt;w:lsdexception locked="false" priority="31" semihidden="false" unhidewhenused="false" qformat="true" name="Subtle Reference"&gt;   &lt;w:lsdexception locked="false" priority="32" semihidden="false" unhidewhenused="false" qformat="true" name="Intense Reference"&gt;   &lt;w:lsdexception locked="false" priority="33" semihidden="false" unhidewhenused="false" qformat="true" name="Book Title"&gt;   &lt;w:lsdexception locked="false" priority="37" name="Bibliography"&gt;   &lt;w:lsdexception locked="false" priority="39" qformat="true" name="TOC Heading"&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt;  /* Style Definitions */  table.MsoNormalTable  {mso-style-name:"Table Normal";  mso-tstyle-rowband-size:0;  mso-tstyle-colband-size:0;  mso-style-noshow:yes;  mso-style-priority:99;  mso-style-parent:"";  mso-padding-alt:0cm 5.4pt 0cm 5.4pt;  mso-para-margin-top:0cm;  mso-para-margin-right:0cm;  mso-para-margin-bottom:10.0pt;  mso-para-margin-left:0cm;  line-height:115%;  mso-pagination:widow-orphan;  font-size:11.0pt;  font-family:"Calibri","sans-serif";  mso-ascii-font-family:Calibri;  mso-ascii-theme-font:minor-latin;  mso-hansi-font-family:Calibri;  mso-hansi-theme-font:minor-latin;  mso-bidi-font-family:"Times New Roman";  mso-bidi-theme-font:minor-bidi;  mso-fareast-language:EN-US;} &lt;/style&gt; &lt;![endif]--&gt;  &lt;p class="MsoNormal"&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;o:officedocumentsettings&gt;   &lt;o:allowpng/&gt;  &lt;/o:OfficeDocumentSettings&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:worddocument&gt;   &lt;w:view&gt;Normal&lt;/w:View&gt;   &lt;w:zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:trackmoves/&gt;   &lt;w:trackformatting/&gt;   &lt;w:punctuationkerning/&gt;   &lt;w:validateagainstschemas/&gt;   &lt;w:saveifxmlinvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:ignoremixedcontent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:alwaysshowplaceholdertext&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:donotpromoteqf/&gt;   &lt;w:lidthemeother&gt;EN-CA&lt;/w:LidThemeOther&gt;   &lt;w:lidthemeasian&gt;X-NONE&lt;/w:LidThemeAsian&gt;   &lt;w:lidthemecomplexscript&gt;X-NONE&lt;/w:LidThemeComplexScript&gt;   &lt;w:compatibility&gt;    &lt;w:breakwrappedtables/&gt;    &lt;w:snaptogridincell/&gt;    &lt;w:wraptextwithpunct/&gt;    &lt;w:useasianbreakrules/&gt;    &lt;w:dontgrowautofit/&gt;    &lt;w:splitpgbreakandparamark/&gt;    &lt;w:enableopentypekerning/&gt;    &lt;w:dontflipmirrorindents/&gt;    &lt;w:overridetablestylehps/&gt;   &lt;/w:Compatibility&gt;   &lt;m:mathpr&gt;    &lt;m:mathfont val="Cambria Math"&gt;    &lt;m:brkbin val="before"&gt;    &lt;m:brkbinsub val="&amp;#45;-"&gt;    &lt;m:smallfrac val="off"&gt;    &lt;m:dispdef/&gt;    &lt;m:lmargin val="0"&gt;    &lt;m:rmargin val="0"&gt;    &lt;m:defjc val="centerGroup"&gt;    &lt;m:wrapindent val="1440"&gt;    &lt;m:intlim val="subSup"&gt;    &lt;m:narylim val="undOvr"&gt;   &lt;/m:mathPr&gt;&lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:latentstyles deflockedstate="false" defunhidewhenused="true" defsemihidden="true" defqformat="false" defpriority="99" latentstylecount="267"&gt;   &lt;w:lsdexception locked="false" priority="0" semihidden="false" unhidewhenused="false" qformat="true" name="Normal"&gt;   &lt;w:lsdexception locked="false" priority="9" semihidden="false" unhidewhenused="false" qformat="true" name="heading 1"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 2"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 3"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 4"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 5"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 6"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 7"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 8"&gt;   &lt;w:lsdexception locked="false" priority="9" qformat="true" name="heading 9"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 1"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 2"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 3"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 4"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 5"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 6"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 7"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 8"&gt;   &lt;w:lsdexception locked="false" priority="39" name="toc 9"&gt;   &lt;w:lsdexception locked="false" priority="35" qformat="true" name="caption"&gt;   &lt;w:lsdexception locked="false" priority="10" semihidden="false" unhidewhenused="false" qformat="true" name="Title"&gt;   &lt;w:lsdexception locked="false" priority="1" name="Default Paragraph Font"&gt;   &lt;w:lsdexception locked="false" priority="11" semihidden="false" unhidewhenused="false" qformat="true" name="Subtitle"&gt;   &lt;w:lsdexception locked="false" priority="22" semihidden="false" unhidewhenused="false" qformat="true" name="Strong"&gt;   &lt;w:lsdexception locked="false" priority="20" semihidden="false" unhidewhenused="false" qformat="true" name="Emphasis"&gt;   &lt;w:lsdexception locked="false" priority="59" semihidden="false" unhidewhenused="false" name="Table Grid"&gt;   &lt;w:lsdexception locked="false" unhidewhenused="false" name="Placeholder Text"&gt;   &lt;w:lsdexception locked="false" priority="1" semihidden="false" unhidewhenused="false" qformat="true" name="No Spacing"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 1"&gt;   &lt;w:lsdexception locked="false" unhidewhenused="false" name="Revision"&gt;   &lt;w:lsdexception locked="false" priority="34" semihidden="false" unhidewhenused="false" qformat="true" name="List Paragraph"&gt;   &lt;w:lsdexception locked="false" priority="29" semihidden="false" unhidewhenused="false" qformat="true" name="Quote"&gt;   &lt;w:lsdexception locked="false" priority="30" semihidden="false" unhidewhenused="false" qformat="true" name="Intense Quote"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 1"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 2"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 3"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 4"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 5"&gt;   &lt;w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 6"&gt;   &lt;w:lsdexception locked="false" priority="19" semihidden="false" unhidewhenused="false" qformat="true" name="Subtle Emphasis"&gt;   &lt;w:lsdexception locked="false" priority="21" semihidden="false" unhidewhenused="false" qformat="true" name="Intense Emphasis"&gt;   &lt;w:lsdexception locked="false" priority="31" semihidden="false" unhidewhenused="false" qformat="true" name="Subtle Reference"&gt;   &lt;w:lsdexception locked="false" priority="32" semihidden="false" unhidewhenused="false" qformat="true" name="Intense Reference"&gt;   &lt;w:lsdexception locked="false" priority="33" semihidden="false" unhidewhenused="false" qformat="true" name="Book Title"&gt;   &lt;w:lsdexception locked="false" priority="37" name="Bibliography"&gt;   &lt;w:lsdexception locked="false" priority="39" qformat="true" name="TOC Heading"&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt;  /* Style Definitions */  table.MsoNormalTable  {mso-style-name:"Table Normal";  mso-tstyle-rowband-size:0;  mso-tstyle-colband-size:0;  mso-style-noshow:yes;  mso-style-priority:99;  mso-style-parent:"";  mso-padding-alt:0cm 5.4pt 0cm 5.4pt;  mso-para-margin-top:0cm;  mso-para-margin-right:0cm;  mso-para-margin-bottom:10.0pt;  mso-para-margin-left:0cm;  line-height:115%;  mso-pagination:widow-orphan;  font-size:11.0pt;  font-family:"Calibri","sans-serif";  mso-ascii-font-family:Calibri;  mso-ascii-theme-font:minor-latin;  mso-hansi-font-family:Calibri;  mso-hansi-theme-font:minor-latin;  mso-bidi-font-family:"Times New Roman";  mso-bidi-theme-font:minor-bidi;  mso-fareast-language:EN-US;} &lt;/style&gt; &lt;![endif]--&gt;  &lt;/p&gt;&lt;p class="MsoNormal"&gt;A little story of changes and why having options is awesome.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;My favorite browser was Chrome, obviously. Until I got a tablet PC and Chrome sucked at multitouch and gestures. Then my favourite browser became IE… of all things. Then I wanted to disable flash to get more juice out of the battery and less crap on the screen… now my default browser is Firefox.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;My favorite Twitter client was Tweetdeck until I got really bored with its inability to browse wide when I turned the iPhone around. Now my favourite tweet client is Twitter’s.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;A few things to note from this:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;The “bar” keeps rising as useful features become standard.&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;Change is accelerating and the world is a better place because of this.&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;Competition and voting with feet is insanely healthy (or healthy for the insane?).&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;I think that most people put up with missing features only for a while and what really kills software is slowness to evolve as well as lack of frequent releases. &lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;One must always have some cheap features on a short term roadmap, to ensure that clients will get something continuously&lt;/li&gt;&lt;/ul&gt;          &lt;p class="MsoNormal"&gt;It also begs a few questions:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;&lt;span style="font: 7pt &amp;quot;Times New Roman&amp;quot;;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Do you think that people become accustomed to seeing through the software they use and focus on the actual problem, switching said software often?&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;&lt;span style="font: 7pt &amp;quot;Times New Roman&amp;quot;;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;How does this translate into a change-hating enterprise environment?&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Symbol;"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;Why do we still have politicians?&lt;/li&gt;&lt;/ul&gt;      &lt;p class="MsoNormal"&gt;P.S. I wrote this using vi inside a Word document, on my tablet, while commuting to work; published it by tethering my internet connection through the iPhone while listening to an internet radio station stream…how cool is that? Can that be considered “giving back to the internet”? Are we Borg?&lt;/p&gt;&lt;p class="MsoNormal"&gt;P.S. 2 - right after, iPhone crashed 3 times trying to sever the tether...not sure what that means...&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-2599043546108804333?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/lZe9HoDC-TQ" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/lZe9HoDC-TQ/embracing-change.html</link><author>noreply@blogger.com (Razvan)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.razie.com/2010/12/embracing-change.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-4115141669581646049</guid><pubDate>Wed, 15 Sep 2010 15:04:00 +0000</pubDate><atom:updated>2011-07-11T11:38:05.017-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">software</category><category domain="http://www.blogger.com/atom/ns#">dsl</category><category domain="http://www.blogger.com/atom/ns#">scala</category><title>A scala Workflow: Engine and DSL</title><description>I've been meaning to write a workflow engine/language for sometime and recently, some scala DSL discussions gave me the motive. I know there's tons of workflow products but none complete and to my liking.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I started in May, worked on it a few hours here and there, for a few weeks and then didn't find the time to complete, so this is still work-in-progress, a snail-pace kind of progress. Since the basic ideas are in place, I figured it's worth advertising, maybe attract some converts and start a religion!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The project is over at &lt;a href="http://github.com/razie/gremlins"&gt;http://github.com/razie/gremlins&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Manifesto&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This is not really meant to be a full-blown BPEL or BPMN environment, but a tiny, extensible but sweet and easily embedable workflow framework, that one can use to automate things inside the house, study the behavior of certain grains of sand or write more readable and interactive complex algorithms.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There's more details in the vision page &lt;a href="http://github.com/razie/gremlins/blob/master/Gremlins.markdown"&gt;http://github.com/razie/gremlins/blob/master/Gremlins.markdown&lt;/a&gt;), but these are the basic principles behind this project:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;A workflow is just a graph of activities through which an engine carves one or more concurrent paths&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;The workflow has many views: text DSL, scala DSL, graphical etc&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;There's only a small set of base/core activities.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Complex activities are built as patterns from lower-level activities&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;There's a gremlin distribution API, uniformly implemented by all engines and components in a cloud&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Branches (sections of the graph) of a bigger workflow could run on multiple devices/agents&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Distributed branches, wherever they run, can be related back and managed as a unit&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Since these are all plain graphs, certain graph transformations should be able to turn a state machine into a workflow or a PI into a BPEL or whatever you want into something you'd like...&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So far, 1-4 are prototyped and 5-8 are "in progress": a basic concurrent engine and DSL are in place... I dind't get to the distributed part yet.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Examples&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The magic of a scala DSL makes this simple CSP style workflow possible:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1076098.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Doesn't look like scala code? Well... it is and it's proof of why scala is scalable! Of course, this comes with one of those "don't do this at home" annotations.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;More complex examples include a scala version:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1076105.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;br /&gt;or a text version:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1076110.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you'd like to stay up-to-date, follow me on &lt;a href="http://twitter.com/razie"&gt;http://twitter.com/razie&lt;/a&gt; - among boring tweets of mine or interesting re-tweets of others, you may find some updates on my projects.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-4115141669581646049?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/kwOp4aUVBuk" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/kwOp4aUVBuk/scala-workflow-engine-and-dsl.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2010/09/scala-workflow-engine-and-dsl.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-5811364783260677803</guid><pubDate>Wed, 18 Aug 2010 16:14:00 +0000</pubDate><atom:updated>2010-08-18T12:20:52.400-04:00</atom:updated><title>The Book Of JOSH</title><description>&lt;span class="Apple-style-span"   style="  color: rgb(102, 102, 102); font-family:Verdana, Arial, Helvetica, sans-serif;font-size:11px;"&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;[Razie's note] I recently realized that I'm also shifting my mental models trending back to simplicity, so I wanted to re-read this blog...but could only find a copy of it - the original had disappeared. I enjoyed it a lot and figured the more copies the better, so I shamelessly copied the copy below. Enjoy!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;hr /&gt;&lt;div class="entry-main"&gt;&lt;div class="entry-date"&gt;&lt;/div&gt;&lt;div class="entry-date"&gt;&lt;/div&gt;&lt;div class="entry-date"&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;For reasons unknown, this article has been removed from the author’s blog, but Google Reader remembered it for me! I have not been able to find the author’s contact information.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;All credits to &lt;/span&gt;&lt;a href="http://thegreylensmansview.blogspot.com/" style="text-decoration: none; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;The Grey Lens Man&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;!&lt;/span&gt;&lt;/p&gt;&lt;hr /&gt;&lt;div class="entry-main"&gt;&lt;div class="entry-date"&gt;&lt;/div&gt;&lt;div class="entry-date"&gt;&lt;/div&gt;&lt;div class="entry-date"&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Mar 23, 2009 1:47 PM&lt;/span&gt;&lt;/div&gt;&lt;h2 class="entry-title" style="font-size: 16px; font-weight: 700; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "&gt;&lt;a class="entry-title-link" href="http://thegreylensmansview.blogspot.com/2009/02/book-of-josh.html" target="_blank" style="text-decoration: none; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;The Book Of JOSH&lt;br /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;div class="entry-author"&gt;&lt;span class="entry-source-title-parent"&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;from &lt;/span&gt;&lt;a class="entry-source-title" href="http://thegreylensmansview.blogspot.com/" target="_blank" style="text-decoration: none; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;The Grey Lens Man’s View&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt; &lt;/span&gt;&lt;span class="entry-author-parent"&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;by &lt;/span&gt;&lt;span class="entry-author-name"&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;The Grey Lens Man&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="entry-body"&gt;&lt;div&gt;&lt;div class="item-body"&gt;&lt;div&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Scala In The Enterprise&lt;br /&gt;&lt;span style="font-weight: bold; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Recently, we’ve decided to use Scala as part of an enterprise software solution stack. And I’d like to mention a few things on &lt;/span&gt;&lt;span style="font-style: italic; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;how the hell that was allowed to happen.&lt;/span&gt;&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;But first lets take a stroll and talk about a thing called enterprise IT.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;&lt;br /&gt;The Problem&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;You see, I have a small problem – 3 million lines of RPG and COBOL, 5,500 logical and physical files on a few AS400s that are not exactly cheap. Even better through the years, the system has been cloned and forked so several incompatible versions of exist through out the world.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;A few years ago I spent 3 months focused on the “original” implementation in a architectural reverse engineering exercise. The result, I know roughly the raison d’etre for 10% or ~ 300K SLOC of code and a few hundred files. 90% of that self-contained universe of code and tables is my personal dark matter question, I know its out there, just no clue as to its nature.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;I won’t go into excruciating detail, but let me leave it like this; within that 2.5 T of data there resides a special flag in the customer file, which determines the fundamental nature of how a customer interacts with the system, and it can be found in Filler3, third byte from the left. In one file, the Account ID column sometimes actually does contain the Account number but not alway, sometimes its something else and its torched us. And you’ll never guess what that ZipLoc3 column_really_ contains (hint: nothing like a zipcode).&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Yet this system is responsible for several billion in revenue. If the mainframe goes off line a few pagers chirp, but if that system goes off line, it’s klaxons and battle stations.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Universal agreement, its got to go. It has been end-of-life scheduled more often then a serial killer on death row. IT leadership comes and goes, yet, a full decade later it sits there in the data center laughing at me like an evil essence hosting Steven King basement furnace.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Within the last year of so, it’s reached such a state of chaotic entropy, its decay is not only apparent to IT, but now the business, and worse the customer as well.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;What Can Be Done?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;No one wants to keep it on life support, so doubling down the head count to reverse entropy, or putting some sort of SOA lipstick on this pig is something we’d like to avoid. The problems are fundamental and systemic.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Being customer facing, it’s where all of the businesses most “brilliant” ideas tend to accumulate through the years. Lets just say they’ve been very creative. Nuff said.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;We threw a check at it and a consulting team tried for 18 months to move onto an ERP solution and barely made a dent, though I do believe the team purchased their own private Caribbean Island from the billing fees. It just won’t map to a COTS or ERP package without a struggle and anything less the monetary cost of a government TARP program.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;On and off over the years, my boss, out of left field, using the &lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;pluralis maiestatis&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt; would say “we should rewrite it all from scratch.” Having been broken like John McCain on a few Death Marches I’d look at him repeating “the horror… the horror.”&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Then during one of my annual hypomanic phases I’d wake up and just know that if put back together ol’ jelled team from that project back in ‘01, well we could rewrite that sucker in no time. That COCOMO II model, most assuredly &lt;/span&gt;&lt;span style="font-style: italic; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;did not&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt; apply to us. My boss, with a look of concern, would nod sagely and suggest I think about it a bit more. I’d recover my senses in a day or two.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;And so it sits in the data center, spewing heat and laughing. And it is evil.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;All This Sturm und Drang&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;&lt;br /&gt;As a company we know how to do it by the book as we are several years into an ERP implementation. We have standards documents on how we develop standards, requirements/design/functional templates, change control, copious meetings, PMs, PMO office, analysts, and even a few software developers to actually implement things.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;We make RUP look like monkeys with a football, Dilbert but a pale shadow irony of our realism, and Forrestor articles look like descriptions of primitive tribal organization. We have PROCESS.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;In addition, we have been a full blown java company for in-house application for years. We got it in spades, Struts, Spring, Hibernate, J2EE, ADF, TOPLINK, Ant, Maven, Eclipse, Rational, …&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;We drink Kool-Aid by the 55 gallon drum round here.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Java&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;&lt;br /&gt;A number of years ago with the support of a key IT executive, I led a jelled, vertical team which brought Java into the company hard and fast. It was seismic.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;There was no end of debate, questions, consternation and gnashing of teeth throughout IT and beyond, which we totally ignored. We didn’t know we were supposed to form a technology introduction committee to shepherd this through the IT Leadership Committee approval process. We damn sure didn’t seek forgiveness after the fact, much less permission before the act.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;A wild ride, in a more wild time, this was pre-PROCESS. Small team, modest budget, mega-hours, fun times and a result that the business loved. It gave us the #1 ranking in our industry and we held it for a number of years.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;I’m reasonably proficient in and knowledgeable of the Java Universe.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Lets, just say it, Java, by design, is a pretty simplistic language, I would argue even a crippled language for uses other then its original design point, which was certainly not server side enterprise IT. As a result, the cottage industries around Java are practically their own Industrial Sectors.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Java is the Brier Rabbit of IT. Once touched you can’t let go. Its simplistic enough to be inadequate in almost every situation. The commercial world just loves this aspect of Java as they exploit revenue streams from filling these gaps via endless Frameworks, Patterns, APIs, Annotations, IDEs and Toolsets.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;The dirty secret of course is 25 – 50% of all of it is pure overhead, without direct value, but necessary to overcome the inherent limitations of Java.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;On the other hand, the upside of Java for enterprise IT is pretty obvious. Any problem you might have can be solved with money and armies of plug and play bodies and you get mountains of buzz material for those presentations.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;But honestly, is this anyway to deliver the IT solutions your company needs?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;  font-size:14px;"&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Full Circle&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Where were we …. Yes, you see, I have a small problem.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;So whats the issue, you say? I write a whole blog about nothing, you say? We all know the right answer, you’re pointing out? Yea, I know, its intuitively obvious to the casual observer.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;We’ll rewrite it from scratch.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Course we’ll need a cluster of WebSphere Application Servers, and an Oracle RAC cluster for all that data. Don’t forget the middleware needed to transition over from the legacy systems, so toss in an ESB cluster, and what heck a couple of BPEL servers too.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Need a SOA Center of Excellence of course too. Can’t integrate without some common XML Business Object Schemas. Also need to roll the Rational RUP suite and some beefy IDE environments and for that shiny look, sprinkle the works with lots of WS-* sparkly dust. Bake 3-5 years or until done, whenever.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;My presentation slides for all this will be killer. I can sell this stuff. I’m good at it. I’ll look like a bloody genius. I’ll have Vendors fawning all over me. And the best part is the bubble on this mess won’t pop for YEARS, when I’ll have plenty of plausible deniability. “Hey the plan was perfect, the business, IT managers and their people were incapable of executing it.”&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;I feel like the enterprise IT equivalent of an AIG trader pocketing ill gotten gains from writing Credit Default Swaps that we can’t pay off.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:14px;"&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Losing My Religion&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;&lt;br /&gt;I’ve lost my faith in it all. I need a new religion.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;I don’t want monolithic 10 ton solutions I need to wrestle into place with a small armies. I don’t want clusters of application servers fronting a behemoth RAC data cluster. I don’t want web management consoles which rival the Space Shuttle’s dash board.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;I want a simple yet effective structural system where I can select and compose reusable modular solutions into simple, targeted solutions. The solution size should be isomorphic to the problem size. It leverages what it needs to solve the problem and no more.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;I don’t want 100K source lines of code, with 33K lines of fluff and stuff. Where one of every in three lines of code has nothing to do with the business logic. Where you can’t even find the business logic in the mounds of patterns, abstractions, frameworks, annotation, cut points and verbosity.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;I want the problem domain reflected in the code and the code to capture the essence of the problem domain.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;I don’t want massive XML documents constrained by committee designed XSD Schema BODs shuttling around clusters of ESB and BPEL middleware.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;I want dirt simple intra system communication in the data center.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;The Book Of JOSH&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Through a marvelous, even devious, set of circumstances, I’m presented with the opportunity to address my little problem without proscribed constraints, a true green field opportunity.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:14px;"&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;son &lt;/span&gt;&lt;span style="font-size:14px;"&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;O&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;SGi &lt;/span&gt;&lt;span style="font-size:14px;"&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;S&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;cala &lt;/span&gt;&lt;span style="font-size:14px;"&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;H&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;TTP&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Json&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt; delivers on what XML promised. Simple to understand, effective data markup accessible and usable by human and computer alike. Serialization/Deserialization is on par with or faster then XML, Thrift and Protocol Buffers. Sure I’m losing XSD Schema type checking, SOAP and WS-* standardization. I’m taking that trade.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;OSGi&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt; a standardized dynamic, modular framework for versioned components and services. Pick a logger component, a HTTP server component, a ??? component, add your own internal components and you have a dedicated application solution. Micro deployment with true replacement. What am I giving up? The monolithic J2EE application servlet loaded with 25 frameworks, SCA and XML configuration hell. Taking the trade.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;HTTP&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt; is simple, effective, fast enough, and widely supported. I’m tired of needlessly complex and endless proprietary protocols to move simple data from A to B with all the accompanying firewall port insanity. Yes, HTTP is not perfect. But I’m taking this trade where I can as well.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;All interfaces will be simple REST inspired APIs based on HTTP+JSON. This is an immediate consequence of the JOSH stack.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Scala&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt; is by far the toughest, yet the easiest selection in the JOSH stack. I wrestled far more with the JSON or XML or Thrift or Protocol Buffers decision.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Without hesitation I know Scala is the right choice from a pure solutioning aspect. But lets face it, what a tough, tough sell from the propeller headed guys to the pointy headed guys.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;First, I’m a bit of a computer language aficionado. I’ve written multiple, actual programs in SML, Scheme, Haskell which I’ve used within the enterprise. Why? Because when faced with certain “one time” problems I can knock out a simple utility far faster XXX then in Java. But in almost all cases these were throw away utilities for one time situations.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;I’ve toyed with Dylan, Ruby, Python, Groovy, Lisp, Ocaml, Modula 2, Oberon, …&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;To date I’ve only advocated and pushed Python for utility scripting at both the Application and System Administration levels. Never, at any time did it ever even cross my mind to advocate anything other then Java and a bit of Python for enterprise application development until now.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Java has been stretched way beyond its modest design point. Its literally falling apart from bloat.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Joshua Boch has numerous presentations of the current state of affairs with Java and the proposed functional extensions and closures are headed. He quotes the following from the Java community.&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;“I am completely and totally humbled. Laid low. I realize now that I am simply not smart at all. I made the mistake of thinking that I could understand generics. I simply cannot. I just can’t. This is really depressing. It is the first time that I’ve ever not been able to understand something related to computers, in any domain, anywhere, period.”&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;“I’m the lead architect here, have a PhD in physics, and have been working daily in Java for 10 years and know it pretty well. The other guy is a very senior enterprise developer (wrote an email system that sends 600 million emails/year with almost no maintenance). If we can’t get [generics], it’s highly unlikely that the ‘average’ developer will ever in our lifetimes be able to figure this stuff out.”&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;That’s just generics. And if you seen the proposed syntax for closures, well its readily apparent, Java’s elastic modulus has been exceeded. A crippled language has been fast marched evolved into a broken language.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Plenty of blame for all here. In the last 50 years academia and commercial entities have given us boutique languages, COBOL, C++ and Java.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;A Proper Programming Language For Business Development&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;It’s the age of the Jetson’s, and a decent programming language for enterprise business applications doesn’t exist.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;So lets design one.&lt;/span&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Simple, clean and full featured.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Ready of concurrency, distributed applications on mult-core commodity boxes.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Allow for the explicit control of state and state mutation.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Support for modularity, and scaling in the large.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Multiparadigm to support mapping the commonality and variability of the domain problem to the code.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Capable of supporting Application Oriented Language / Domain Specific Language development (AOL/DSL).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Cross platform, with a large supporting tool suite universe.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Open and not subject to Vendor locking.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Fast&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;OO&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Functional&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Conceptual Integrity.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Allow control of, if not out right banishment of the null pointer.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Rich libraries.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Strongly Typed&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Practical and Pragmatic&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Accessible to the average developer, empowering to your A players.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Runs on a portable VM.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Leverage existing extensive Java libraries.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;This is Scala.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:14px;"&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;So How Is It Going&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;Fast forward… Currently a very small team and myself are near completion of the first major functional component on the JOSH stack.&lt;br /&gt;&lt;br /&gt;All of the development talent on the team are experienced Java developers. And they have been effective from Day 1.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;No real discussions of covariance and contravariance was required. We did discuss HOF, anonymous lamba, closures, cut syntax, maps, folds, reduces. And strangely their heads did not explode. We did discuss the evil of mutable state, and referentially transparent functions.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;They were enthralled.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;No detailed lectures on the deep underlying structure of Catamorphism, Anamorphism, Apomorphism, Hylomorphism and Paramorphism was required to get solid code at a cleaner and higher level, with less bloat then equivalent Java.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;A core aspect of system is combinator based threading state through a composed computation. No problems in understanding were observed.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;In fact in terms of difficulty, they struggled somewhat more with Git then they did with Scala, Linux then they did with Scala, IDEs issues then they did with Scala, and Maven then they did with Scala.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;At a minimum they wrote better Java idomatic code in Scala then they did in Java and proactively adopted more idiomatic Scala as time went by.&lt;br /&gt;&lt;br /&gt;Visual Basic now has lambda and no one expects a VB developer to throw himself off a building. Yet somehow, these days too many think Java developers can’t handle more advanced functionality.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;I’ve seen too much of “I just did this fold thingy and my co-workers could _never_ understand that” is a bit overblown. OK, if they have never seen it before, they might not get it in 10 mins. But working with the team on the basics for 10 hours or 10 days will certainly do it.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;But bottom line, enterprise Java developers can transition to Scala. I know this, because I’ve directly observed it.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:14px;"&gt;&lt;span style="font-weight: bold; "&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;JOSH has no Data&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;The JOSH stack is lacking a letter, because a solution for persisted data is missing in the stack.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;A great deal of what needs to be done does not require a ACID RDB cluster. Some of it does and I’m kicking that can down the road.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="color:#CCCCCC;"&gt;For the rest, either the data is ReadOnly and loaded a 1-3 times a day or is best persisted by a distributed Key-Value storage system. A number of these are now available as open source solutions and at the right moment I’ll need to pick one and add that letter to the JOSH stack.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-5811364783260677803?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/PFEm-vCtcEg" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/PFEm-vCtcEg/book-of-josh.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2010/08/book-of-josh.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-4036770707375775730</guid><pubDate>Mon, 09 Aug 2010 15:30:00 +0000</pubDate><atom:updated>2011-06-24T11:42:47.174-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">bitching</category><title>Google wave is dead</title><description>...yeah, the "king of the interactive communication is dead, long live the king".&lt;br /&gt;&lt;br /&gt;While enthusiastic in the beginning, I must say that we didn't used it as much as we thought we'd be. The technology behind it however is awesome, but I must agree, the implementation wasn’t the greatest. It should be embedded in google docs and integrated with email and IM. I think I already saw some of that in google docs recently…&lt;br /&gt;&lt;br /&gt;For instance click on an email thread and "turn to wave". Or the same in IM, think of it as "persisting the thread".&lt;br /&gt;&lt;br /&gt;In google docs, the use of this is obvious: it's turning any doc into a version controled repository, real time wiki with embedded forum etc...yeah, makes sense. Every software MUST now have this: every wiki, every forum, every Word application...they simply &lt;span style="FONT-WEIGHT: bold"&gt;must&lt;/span&gt;! Getting this question in a flashing status bar of your favorite Word app "Do you accept interactive edit of this document, from John@somegeeks.com?". Hell, yeah...&lt;br /&gt;&lt;br /&gt;The "playback" feature was underutilized.&lt;br /&gt;&lt;br /&gt;May be surprising, but I used it mostly as an internet pad to copy/paste quotes, ideas, links and later develop them. Also to copy/paste things between laptops/computers, save them for later etc.&lt;br /&gt;&lt;br /&gt;An "internet research pad", where you could invite others etc...that I still think it's worthy of its own site.&lt;br /&gt;&lt;br /&gt;I will, spare time existing, look at integrating this with my script pad: &lt;a href="http://scripster.razie.com/play/session"&gt;http://scripster.razie.com/play/session&lt;/a&gt; - That would be bespinningly interesting.&lt;br /&gt;&lt;br /&gt;As always, don't hold your breath.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-4036770707375775730?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/KZsC5VE2WMY" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/KZsC5VE2WMY/google-wave-is-dead.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2010/08/google-wave-is-dead.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-2459727419160825684</guid><pubDate>Tue, 15 Jun 2010 15:42:00 +0000</pubDate><atom:updated>2011-06-24T11:42:20.425-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">bitching</category><title>Bitching about American Express</title><description>So, my Amex card is a little ripped and I call them to send a replacement. They said they'll change the last 4 digits of the card so now I have to update all my online and pre-authorized stuff, banking etc. &lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I explain that my card is not lost and that's a lot of work. They explain that I may cancel my account instead if I wish. I almost did that...but realized I was pissed and just backed down - I guess keeping a long-standing account is a positive for my credit history.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Anyways. I am updating all my pre-authorized and online stuff to use my MasterCard and I will simply park the new card, when it arrives, somewhere in the library.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Just like that, Amex lost a few hundred/thousand dollars in revenue and all of a sudden I feel good about it. I promise I won't use it anymore...I'll now carry a MasterCard and a Visa instead.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;The morons should realize that I don't care about what they want...but, if they want my moneys, they should really care about what I want!&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Anyways, bitching accomplished. Feel better.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Cheers&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;P.S. Their website does not have either an email option or an online form for complaints...nothing online. All they have is phone numbers (but I just hanged up) and snail mail addresses. Oh well - serves them well...they got a blog instead and "lost" a customer.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;P.S. Already switched a few monthly recurring payments and online processors to my MC. This is almost fun now.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-2459727419160825684?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/uzp01k5ARKk" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/uzp01k5ARKk/bitching-about-american-express.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2010/06/bitching-about-american-express.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-7276734972175648212</guid><pubDate>Sun, 14 Mar 2010 03:04:00 +0000</pubDate><atom:updated>2011-06-24T11:42:32.830-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">bitching</category><title>Blogger is stupid</title><description>Trying to edit a blog (&lt;a href="http://blog.homecloud.ca/2010/03/option-monad-pattern-thing.html"&gt;this one&lt;/a&gt;) I've had it: this editor right here is one of the worst I've used in a long time. It's still close to impossible to quote nice code snippets and the html it generates is riddled with DIV tags worse than a word document. &lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I guess this is the fate of things. The bad ones become good enough and the good get worse.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Shame. I shall investigate options to blogger, since the best voting is done with the feet...or, in this case, with the...fingertips...?&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I shall create my own nice code quoting system, based on the &lt;a href="http://scripster.razie.com/"&gt;scripster&lt;/a&gt; I just put together. I should probably thank them for the idea...&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;[EDIT] The code quoting is up and running - just need to work on embedding the quotes now. Try it at &lt;a href="http://www.codewitter.com/"&gt;www.codewitter.com&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-7276734972175648212?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/25j9VCckRb4" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/25j9VCckRb4/blogger-is-stupid.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2010/03/blogger-is-stupid.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-1307161256424076347</guid><pubDate>Fri, 26 Feb 2010 16:17:00 +0000</pubDate><atom:updated>2011-06-24T11:42:04.854-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">software</category><category domain="http://www.blogger.com/atom/ns#">dsl</category><category domain="http://www.blogger.com/atom/ns#">scala</category><title>Implementing a state machine in scala DSL</title><description>I had a bit of fun in the past few days writing a telnet server implementation in #scala. Part of that was implementing a state machine, which I then cleaned up so the definitions are simple.&lt;br /&gt;&lt;br /&gt;Here's a sample state machine:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="http://pastie.org/1079763.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The code is at &lt;a href="http://code.google.com/p/razie/source/browse/trunk/razie/src/razie/SM.scala"&gt;http://code.google.com/p/razie/source/browse/trunk/razie/src/razie/SM.scala&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The basic structure is:&lt;br /&gt;&lt;pre&gt; (state, event-matcher) -&amp;gt; newstate + callback ++ unitcalback... + callback :: Nil&lt;/pre&gt;The event-matcher can be:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;an event&lt;/li&gt;&lt;br /&gt;&lt;li&gt;a sequence of events&lt;/li&gt;&lt;br /&gt;&lt;li&gt;a function taking an event and returning...Boolean, of course&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The callback is a function with either of these signatures:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;def push (sm:StateMachine, t:Transition, e:Event) - use + for these&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;def reset : Unit - use ++ for these (hey, I'm still getting my head around advanced scala stuff)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Enjoy, and if you likee, contribute, eh?&lt;br /&gt;&lt;br /&gt;Here's the definition (in-work) of the high-level telnet state machine, a little more complicated but not much.&lt;br /&gt;&lt;br /&gt;The picture (thanks to &lt;a href="http://tomi.vanek.sk/index.php?page=telnet"&gt;http://tomi.vanek.sk/index.php?page=telnet&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://tomi.vanek.sk/static/telnet/Telnet%20Parser.png"&gt;&lt;img style="MARGIN: 0pt 0pt 10px 10px; WIDTH: 479px; HEIGHT: 504px; CURSOR: pointer" border="0" alt="" src="http://tomi.vanek.sk/static/telnet/Telnet%20Parser.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The state machine (when it's ready I'll post the link to the entire code):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// based on diagram at http://tomi.vanek.sk/index.php?page=telnet&lt;br /&gt;&lt;br /&gt;implicit val sm = this&lt;br /&gt;&lt;br /&gt;val sstates @ (data, cmd, app, param, neg, subneg) = ("data", "cmd", "app", "param", "neg", "subneg")&lt;br /&gt;override def start = state("data")&lt;br /&gt;&lt;br /&gt;override val transitions : Seq[Transition] =&lt;br /&gt;     (data, IAC)             -&amp;gt; cmd ::&lt;br /&gt;     (data, 0)               -&amp;gt; data :: // NOP - don't know why i get these after CR&lt;br /&gt;     (data, 10)              -&amp;gt; data :: // NOP - LF ignored?&lt;br /&gt;     (data, 13)              -&amp;gt; data + eatLine + echo ("") :: // CR&lt;br /&gt;     (data, {_:Event=&amp;gt;true}) -&amp;gt; data + eatChar + echo ("") :: // remaining chars&lt;br /&gt;     (cmd, IAC)              -&amp;gt; data ::&lt;br /&gt;     (cmd, Seq(WILL, WONT, DO, DONT)) -&amp;gt; neg + push ::&lt;br /&gt;     // TODO 3-2 should negociate stuff, i.e. reply with will/won't&lt;br /&gt;     (neg, {_:Event=&amp;gt;last==SM(DO)})   -&amp;gt; data + mode(true) + pop ::&lt;br /&gt;     (neg, {_:Event=&amp;gt;last==SM(DONT)}) -&amp;gt; data + mode(false) + pop ::&lt;br /&gt;     (neg, AnyEvent) -&amp;gt; data + echo("interesting sequence...") + pop ::  // What is this?&lt;br /&gt;     (cmd, SB) -&amp;gt; subneg ::&lt;br /&gt;     (""".*""".r, CR) -&amp;gt; data :: // it's important to reset the thing on ENTRE&lt;br /&gt;      Nil&lt;br /&gt;&lt;br /&gt;def eatChar (sm:StateMachine, t:Transition, e:Event)&lt;br /&gt;def eatLine (sm:StateMachine, t:Transition, e:Event)&lt;br /&gt;&lt;/pre&gt;Enjoy and, more importantly, have fun! &lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;If you'd like to read more of my rants about scala, see &lt;a href="http://wiki.homecloud.ca/thinking-in-scala"&gt;http://wiki.homecloud.ca/thinking-in-scala&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-1307161256424076347?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/toUE2aBmVNQ" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/toUE2aBmVNQ/implementing-state-machine-in-scala-dsl.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2010/02/implementing-state-machine-in-scala-dsl.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-8550380359595565107</guid><pubDate>Wed, 20 Jan 2010 17:48:00 +0000</pubDate><atom:updated>2010-01-20T12:54:43.224-05:00</atom:updated><title>Start dowloading torrents remotely</title><description>Say you're at work and you stumble onto a torrent you'd like to watch tonite (some documentary or the latest episode from &lt;a href="http://www.cbc.ca/nextprimeminister/blog/2008/03/download_canadas_next_great_pr.html"&gt;http://www.cbc.ca/nextprimeminister/blog/2008/03/download_canadas_next_great_pr.html&lt;/a&gt;). &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, here's one way to do it...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1. Run uTorrent at home, 24/7, even if it's not downloading anything. Configure it to automatically load torrents from a folder say "torrentstodo". This is in Preferences/Directories at the bottom.&lt;/div&gt;&lt;div&gt;2. Install LiveMesh both at home and at work&lt;/div&gt;&lt;div&gt;3. map this folder as shared on both computers: right click and say "share with LiveMesh" at home and at work just right click the "LiveMesh Folders" in explorer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then, when you like a torrent, save it to the local "torrentstodo" folder at work. LiveMesh will transfer it at home automatically. Then uTorrent will pick it up and start downloading it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Please don't steal copyrighted material when it's easily available (online) at a reasonable price :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-8550380359595565107?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/mb8aSMRWN9E" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/mb8aSMRWN9E/start-dowloading-torrents-remotely.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2010/01/start-dowloading-torrents-remotely.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-4030714006765749396</guid><pubDate>Fri, 11 Dec 2009 22:01:00 +0000</pubDate><atom:updated>2009-12-11T17:08:45.207-05:00</atom:updated><title>I'm a Code Manager</title><description>Product Manager, Project Manager, HR - i.e. People Manager, Technical Account Manager, Development Manager, Build Manager....and developers. Some develop and the rest manage stuff.&lt;br /&gt;&lt;br /&gt;WRONG!&lt;br /&gt;&lt;br /&gt;You know what? I want to be called by my new title: Code Manager. Everyone manages something and I manage code.&lt;br /&gt;&lt;br /&gt;THERE!&lt;br /&gt;&lt;br /&gt;I guess I missed the many architects, we can call them Code Benders - hey, I actually like that!&lt;br /&gt;&lt;br /&gt;Happy coding!&lt;br /&gt;&lt;br /&gt;P.S. I think I left out the Resource Manager - as in some companies, people are known as "resources". So in a project, the Project Mananger can choose 3 resources: a cofee machine, a printer and a developer. WRONG. I'm a Code Manager, not a resource, so please...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-4030714006765749396?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/IHhQA9PDJpo" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/IHhQA9PDJpo/im-code-manager.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2009/12/im-code-manager.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-1087119816086677689</guid><pubDate>Thu, 24 Sep 2009 15:35:00 +0000</pubDate><atom:updated>2009-09-24T11:54:05.809-04:00</atom:updated><title>My Nokia 770</title><description>I love my Nokia 770 and it's much more useful than the iPod - I must say...Since I was bashing all device manufacturers other than Apple, I must exclude Nokia from the list...&lt;br /&gt;&lt;br /&gt;Having the courage to come up with a Linux-based Internet tablet, when they did, puts them squarely in front of Apple...&lt;br /&gt;&lt;br /&gt;The thing is that I use them both (iPod Touch and the 770) as remotes to &lt;a href="http://wiki.homecloud.ca/WatchMovie"&gt;control movie playing at home&lt;/a&gt; and the Nokia is better equiped to be the remote. It is a little bulkier and sluggish to reconnect the WiFi, but the web browsing experience is much better, for the simple pages my application requires (larger screen helps, but the ergonomics of full-page and persistent zoom are what make it the better one).&lt;br /&gt;&lt;br /&gt;Fully customisable home screen and a host of applications out-of-the-box actually make it the winner...just to think that I've had it for a few years now and it cost half what the iPod did...why is this new iPod touch so backwards? Target market? Well, I guess simplicity does have its benefits...it is a &lt;span style="font-style: italic;"&gt;portable&lt;/span&gt; music player first of all!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-1087119816086677689?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/fNObEyatngs" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/fNObEyatngs/my-nokia-770.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2009/09/my-nokia-770.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-8661873191875399330</guid><pubDate>Mon, 21 Sep 2009 16:08:00 +0000</pubDate><atom:updated>2011-06-24T11:41:34.516-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">bitching</category><title>iPods suck nicely</title><description>Just gave in and got the new iPod Touch (32G) this weekend. Let's see...&lt;br /&gt;&lt;br /&gt;Couldn't even take it out of the box - I was afraid to break it - I went back and asked a "Mac Helper" for help and he explained how to take it out - apparently Apple just won the abnormal packaging contest!&lt;br /&gt;&lt;br /&gt;Walked again out of the store only to come back: when turned on, the thing only displays an image suggesting plugging its USB into iTunes. I had to go back and explained that I just paid 400$ for a toy that doesn't work...they finally convinced me to just refrain from returning it and wait until I got home to plug it in and see what's what.&lt;br /&gt;&lt;br /&gt;Well - finally got home and started playing with it. It does grow on you and you start to wonder how come every OTHER device manufacturer out there seems to be sooo stupid. They do deserve the market share they're left with!&lt;br /&gt;&lt;br /&gt;But then you start to notice the noticeables:&lt;br /&gt;- the only dark screen is the home screen...most others are the same stupid black on white as your microsoft outlook...and there's no obvious way to change the "skin".&lt;br /&gt;- the browser, while smart, is also stupid. I.e. the "zoom", while nicely done with the pinching manouver, is not remembered when you click on the next page&lt;br /&gt;- the home screen doesn't go wide when you turn the thing...non-sensical since when you can go back and forth between "wide" apps, you pass through the home screen and have to turn the thing again...&lt;br /&gt;&lt;br /&gt;Overall, they can get away with all these, just because the thing is so nice in many other ways...but it goes to prove the limits of every day life - nobody's perfect.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-8661873191875399330?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/WTqYQSzA9XA" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/WTqYQSzA9XA/ipods-suck-nicely.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2009/09/ipods-suck-nicely.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-5645985736880659758</guid><pubDate>Thu, 17 Sep 2009 03:50:00 +0000</pubDate><atom:updated>2011-06-24T11:41:18.489-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">software</category><category domain="http://www.blogger.com/atom/ns#">scala</category><title>converting Java collections to scala collections</title><description>This took me many hours to figure out. I didn't find a word about it in the (quite a bit of) stuff I read, including the "Programming in Scala" book, blogs, posts etc.&lt;br /&gt;&lt;br /&gt;How to best convert java collections into scala collections and back. This is crucial, as lots of would-be scalaistas would still carry around some kind of Java library, be it JNDI or JTA or some in-house non-rewritables!&lt;br /&gt;&lt;br /&gt;As of scala 2.7, scala.collection.jcl.Convertions is your friend. As of scala 2.8, scala.collection.JavaConversions is your best friend. Enough said.&lt;br /&gt;&lt;br /&gt;Interestingly, I use List pretty much everywhere in my code. However, as you'll see, since List is the only one that doesn't freely convert from one to the other, it follows that you should use Seq[A] in all your scala code...hmmmm&lt;br /&gt;&lt;br /&gt;[later edit] Also, your arguably best friend in scala is the scala.collections.mutable.ListBuffer - check it out, it's all you thought List would be! Although, after a while, you will find yourself relying on mutable collections less and less...&lt;br /&gt;&lt;br /&gt;To get the full power of the implicit java to scala conversions, make sure you import the contents of the class, note the underscore below:&lt;br /&gt;&lt;pre&gt;&lt;span class="Apple-style-span"  style="color:#ff0000;"&gt;import scala.collection.JavaConversions._&lt;/span&gt;&lt;/pre&gt;[Later edit] I removed my examples here as being too clumsy :) use the import above instead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-5645985736880659758?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/Rm5Q996M2Fs" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/Rm5Q996M2Fs/converting-java-collections-to-scala.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2009/09/converting-java-collections-to-scala.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-4964447402674024615</guid><pubDate>Tue, 11 Aug 2009 20:25:00 +0000</pubDate><atom:updated>2009-08-11T16:27:32.141-04:00</atom:updated><title>Increase battery capacity to 123% :)</title><description>&lt;a href="http://2.bp.blogspot.com/_AgcP7L_T8ZQ/SoHUJ6AfTQI/AAAAAAAAAE0/1kZHmvOp83w/s1600-h/battery.PNG"&gt;&lt;img style="MARGIN: 0px 0px 10px 10px; WIDTH: 303px; FLOAT: right; HEIGHT: 103px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5368805497457560834" border="0" alt="" src="http://2.bp.blogspot.com/_AgcP7L_T8ZQ/SoHUJ6AfTQI/AAAAAAAAAE0/1kZHmvOp83w/s320/battery.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;Just got this "warning" from my own laptop...no comments!&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-4964447402674024615?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/GN7f_NNLlkE" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/GN7f_NNLlkE/increase-battery-capacity-to-123.html</link><author>noreply@blogger.com (Razie)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_AgcP7L_T8ZQ/SoHUJ6AfTQI/AAAAAAAAAE0/1kZHmvOp83w/s72-c/battery.PNG" height="72" width="72" /><feedburner:origLink>http://blog.razie.com/2009/08/increase-battery-capacity-to-123.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-7812248735757975469</guid><pubDate>Fri, 05 Jun 2009 14:51:00 +0000</pubDate><atom:updated>2011-06-24T11:40:53.008-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cool</category><title>Process Explorer - me likee</title><description>Installed this &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx"&gt;Process Explorer &lt;/a&gt;a while back and it replaces the windows classic Task management stuff which is hopeless!&lt;br /&gt;&lt;br /&gt;I love it. The best features are:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;it shows a lot of information about what's running&lt;/li&gt;&lt;br /&gt;&lt;li&gt;you can search for a process just by typing the name&lt;/li&gt;&lt;br /&gt;&lt;li&gt;when you say "kill" it actually kills them asap rather than think and wait and ask for confirmation about 10 times...&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;Whoa! Goodie! Me likee.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-7812248735757975469?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/qmpZG_Sypj4" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/qmpZG_Sypj4/process-explorer-me-likee.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2009/06/process-explorer-me-likee.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-3479036256209147430</guid><pubDate>Thu, 14 May 2009 16:59:00 +0000</pubDate><atom:updated>2011-06-24T11:40:35.981-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cool</category><category domain="http://www.blogger.com/atom/ns#">evolution</category><title>Your own newspaper</title><description>Here's the culmination of the freedom from the mainstream: you can create your own newspaper, from the feeds you want: &lt;a href="http://feedjournal.com/index.html"&gt;http://feedjournal.com/index.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Not only are we using feed readers, we can now print our own newspapers - that's so cool...interestingly enough, this is just another of the &lt;a href="http://www.amazon.ca/Sovereign-Individual-Mastering-Transition-Information/dp/0684832720"&gt;Sovereign Individual &lt;/a&gt;predictions...&lt;br /&gt;&lt;br /&gt;And...to complete the picture, for the retarded sites that don't support content feeds, here's a free service that does it: &lt;a href="http://changedetection.com/"&gt;ChangeDetection&lt;/a&gt;. It is simple to use and no catches that I could find...&lt;br /&gt;&lt;br /&gt;If you're looking, there's actually more of these page2rss services, including &lt;a href="http://page2rss.com/"&gt;http://page2rss.com&lt;/a&gt; - really simple! The &lt;a href="http://www.watchthatpage.com/"&gt;http://www.watchthatpage.com/&lt;/a&gt; seems more complicated, while &lt;a href="http://www.followthatpage.com/"&gt;http://www.followthatpage.com/&lt;/a&gt; can do only email...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Happy newsprinting!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-3479036256209147430?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/1uxL8A2QqJU" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/1uxL8A2QqJU/your-own-newspaper.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2009/05/your-own-newspaper.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-4657128882461953782</guid><pubDate>Tue, 21 Apr 2009 16:50:00 +0000</pubDate><atom:updated>2011-06-24T11:40:10.938-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">software</category><category domain="http://www.blogger.com/atom/ns#">scala</category><title>Optional arguments in Scala</title><description>I couldn't find much on the web with this search and it took me maybe 15 min to figure it out, so here's the low down on using optional arguments in Scala. There's a description in section 8.8 in the Programming in Scala book - they call them "repeated parameters".&lt;br /&gt;&lt;br /&gt;Using this notation you can overload Java methods with optional parms as well as pass them over to a "super." method (which was what I needed to do):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def takesOptionalArgs (x:String*) = {&lt;br /&gt;   println ("Scala println: ", x.mkString(" "))&lt;br /&gt;   java.lang.System.out.printf ("Java printf: %s %s %s", x:_*)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This special syntax instructs the compiler to pass the x array elements individually, not as an array!&lt;br /&gt;&lt;br /&gt;Cheers.&lt;br /&gt;&lt;br /&gt;[later edit] P.S. Note that there's an outstanding defect for overloading java vararg methods - it currently doesn't work: &lt;a href="https://lampsvn.epfl.ch/trac/scala/ticket/1459"&gt;https://lampsvn.epfl.ch/trac/scala/ticket/1459&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-4657128882461953782?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/j2ng50Vukt0" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/j2ng50Vukt0/optional-arguments-in-scala.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2009/04/optional-arguments-in-scala.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-809872695050601243</guid><pubDate>Tue, 14 Apr 2009 18:13:00 +0000</pubDate><atom:updated>2011-06-24T11:39:47.636-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">agile</category><category domain="http://www.blogger.com/atom/ns#">software</category><title>Agile Architecture talk from Coplien</title><description>&lt;p&gt;For a nice glimpse at the future of programming as it evolves, I strongly recommend this talk from my favorite architecture guy: Coplien. Prerequisites: get a beer, slippers and a robe, the conclusion is not light reading!&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://blog.jaoo.dk/2009/03/04/handling-architecture-in-the-agile-world/"&gt;http://blog.jaoo.dk/2009/03/04/handling-architecture-in-the-agile-world/&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Some of the things that deserve emphasis:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;The need that the application’s own model matches the model the users have in their head, i.e. the “view of the world” is obvious, but, unfortunately, it is not obvious to many…&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Architecture is the essence of structure (the form), not the structure itself. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;A good agile/lean architecture:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;supports change&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Supports user interaction&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Lowers discovery costs, rework&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;Other memorables:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Habitable code – code where the designer could choose to live. Do you like your code? Would you live with it?&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Refactoring is bad! We want to avoid re-work…you need a system view, not code–as-you-think!&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The long forgotten purpose of OO is to capture the model from the user’s mind, not create toys for developers!&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;(Razie says hmm): Do object diagrams instead of class diagrams – users think in terms of instances, not abstract classes.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The GUI is not something between the GUI and the model, is a tool allowing the user to mess with the model! Kent Beck said “you can’t hide a bad architecture behind a good GUI”.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;(Razie says hmm): Requirements are the LAST thing you look at when doing architecture!&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Need architecture upfront, code just-in-time!&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Java is a TOY language.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Scala’s got traits, baby!&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;This is the brief follow up: &lt;a href="http://blog.jaoo.dk/2008/12/20/jaoo-video-2008-james-o-coplien/"&gt;http://blog.jaoo.dk/2008/12/20/jaoo-video-2008-james-o-coplien/&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Peter Coad’s now a pilot, but his role-based color modeling should’ve taken off! &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-809872695050601243?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/iw_UI2UXC2U" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/iw_UI2UXC2U/agile-architecture-talk-from-coplien.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2009/04/agile-architecture-talk-from-coplien.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-2111007781862265238</guid><pubDate>Thu, 12 Mar 2009 14:44:00 +0000</pubDate><atom:updated>2009-03-12T10:49:19.254-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">design</category><category domain="http://www.blogger.com/atom/ns#">architecture</category><category domain="http://www.blogger.com/atom/ns#">principle</category><title>Components vs Frameworks</title><description>ABSTRACT: One of Razie's infamous uber-principles: I see frameworks as being the opposite of components. When architecting parts of a system, use this to decide on one or the other - this point of view could enrich the designer's arsenal of decision principles.&lt;br /&gt;TAGS: architecture, design, principle&lt;br /&gt;&lt;br /&gt;When you're talking about "writing code", the best option is generally reusing an existing piece of code and customizing it. Reusable pieces of code are normally in the category of either components or frameworks.&lt;br /&gt;&lt;br /&gt;Components are more or less black boxes with well defined inputs/outputs and customization settings.&lt;br /&gt;&lt;br /&gt;Frameworks, while they may also have defined inputs/outputs, they generally cannot be used as is. You write "plugins" (i.e. proxies or strategies) that customize a piece of the puzzle and then combine them to achieve the functionality the framework is intended for.&lt;br /&gt;&lt;br /&gt;I see frameworks as being the opposite of components, given how they're used: while components are pre-determined pieces of functionality, which you combine to achieve a flexible structure, frameworks define first an immutable structure and then allow you to customize some aspects of it.&lt;br /&gt;&lt;br /&gt;Patterns fall sqarely in the framework category, since they prescribe a structure with roles to fill out.&lt;br /&gt;&lt;br /&gt;In terms of initialization and configuration, components get everything up-front, while frameworks usually will use a callback to retrieve configuration, when needed. At least it's easier to always follow this pattern: use of factories indicates frameworks, for instance.&lt;br /&gt;&lt;br /&gt;Depending on the level you're at and your point of view, it is relative whether a given library falls in either category. For instance, a component could take a "strategy" as an input.&lt;br /&gt;&lt;br /&gt;When you look at a system, you will see components made of frameworks, made of components, made of frameworks etc. A system is made of sub-systems, which can only be of either kind :) since they're the two opposite forms of sub-system architecture.&lt;br /&gt;&lt;br /&gt;CONCLUSION&lt;br /&gt;&lt;br /&gt;Making the distinction and decision between component vs. framework, when designing, is important, since the denomination of "component" carries lots of semantics: independence, self-sufficiency, black-box, upfront initialization etc.&lt;br /&gt;&lt;br /&gt;Frameworks allow flexibility in the detail but are inflexible structure-wise. A framework that is too flexible is called a mess.&lt;br /&gt;&lt;br /&gt;A framework with all variabilities fixed is a component.&lt;br /&gt;&lt;br /&gt;Keep thinking and have fun, eh? I certainly am!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-2111007781862265238?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/DBlHZ4bH0-k" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/DBlHZ4bH0-k/components-vs-frameworks.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2009/03/components-vs-frameworks.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-20018300.post-4294438285939674855</guid><pubDate>Tue, 17 Feb 2009 17:18:00 +0000</pubDate><atom:updated>2011-06-24T11:39:08.667-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">bitching</category><title>Google Chrome and your passwords in clear-text</title><description>It was fun using the "remember passwords" feature until i figured out that Chrome will show your remembered passwords in clear-text...&lt;br /&gt;&lt;br /&gt;...it's probably the worse feature I've seen implemented so far, this year...but it's just february...and you didn't see what I have to say about CIRA-the Canandian internet registrar- yet, eh?&lt;br /&gt;&lt;br /&gt;[later edit]...this is especially evil since now evildoers could change the passwords to all your accounts and lock you out - otherwise, even if they find your laptop logged into all those accounts, they couldn't change your password before you did...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20018300-4294438285939674855?l=blog.razie.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Razblog/~4/2tFMLuDNgvQ" height="1" width="1"/&gt;</description><link>http://feeds.razie.com/~r/Razblog/~3/2tFMLuDNgvQ/google-chrome-and-your-passwords-in.html</link><author>noreply@blogger.com (Razie)</author><feedburner:origLink>http://blog.razie.com/2009/02/google-chrome-and-your-passwords-in.html</feedburner:origLink></item></channel></rss>

