<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1463803170752156221</id><updated>2012-02-16T05:08:17.062-08:00</updated><category term='ruby'/><category term='objective-c'/><category term='nio'/><category term='multiple dispatch'/><category term='threads'/><category term='dynamic languages'/><category term='java'/><category term='documentation'/><category term='programming'/><category term='type inference'/><category term='programming languages'/><category term='D'/><category term='newspeak'/><title type='text'>Monkeypatched</title><subtitle type='html'>Uninteresting Opinions on Programming and related subjects.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>18</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-5526718796125873843</id><published>2009-07-16T02:35:00.000-07:00</published><updated>2009-07-18T02:46:48.838-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dynamic languages'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='objective-c'/><title type='text'>A New Dynamic Dispatch Algorithm?</title><content type='html'>I'm playing around a little with dynamic dispatch algorithms in a dynamically typed language.&lt;br /&gt;&lt;br /&gt;An idea I had was for each function to create a small dispatch table, where each function slot also was a tree node.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;typedef struct Slot&lt;br /&gt;{&lt;br /&gt;   SEL selector;&lt;br /&gt;   IMP function;&lt;br /&gt;   struct Slot* left;&lt;br /&gt;   struct Slot* right;&lt;br /&gt;} Slot;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With the class looking like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;typedef struct Class&lt;br /&gt;{&lt;br /&gt;   // ... Other stuff&lt;br /&gt;   Slot slot[FUNCTION_SLOTS];&lt;br /&gt;   // ... More stuff&lt;br /&gt;} Class;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For dispatch we can now do:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Slot* slotPtr = object-&gt;class-&gt;slot + selector &amp; SEL_HASH;&lt;br /&gt;do&lt;br /&gt;{&lt;br /&gt;   if (slotPtr-&gt;selector == selector) return slotPtr-&gt;function(object, selector);&lt;br /&gt;   slotPtr = (slotPtr-&gt;selector &gt; selector) ? slotPtr-&gt;left : slotPtr-&gt;right;&lt;br /&gt;} while (slotPtr);&lt;br /&gt;// ... execute MethodNotFound:&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This means a worst case O(log(N)) lookup where N is the maximum number of methods hashed to the same slot.&lt;br /&gt;&lt;br /&gt;My tests seem to indicate that it is surprisingly fast, at least when inlining the dispatch method:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Best case:                   207 million sends/s.&lt;br /&gt;Worst case 6&amp;lt;N&amp;lt;11:           138 million sends/s&lt;br /&gt;Direct dispatch table call:  234 million sends/s.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I'm not sure how reliable these benchmarks are, but it would be interesting to compare these results to the algorithm in the Objective-C runtime.&lt;br /&gt;&lt;br /&gt;The downside of course is that all classes need to keep all methods they respond to in the dispatch table, as opposed to only the methods they override.&lt;br /&gt;&lt;br /&gt;[Edit:]&lt;br /&gt;Here are results of microbenchmarks on the Obj-C runtime (smaller is better):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Virtual call            1.00&lt;br /&gt;Best case inlined call  1.13&lt;br /&gt;Best case non-inlined   1.77&lt;br /&gt;Best case lookup        1.82&lt;br /&gt;Worst case inlined call 1.70&lt;br /&gt;Worst case non-inlined  2.30&lt;br /&gt;Worst case lookup       2.44&lt;br /&gt;Objective-C OS X 10.5   1.77&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that the Objective-C result gives the best case for the runtime.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1463803170752156221-5526718796125873843?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/5526718796125873843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=5526718796125873843' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/5526718796125873843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/5526718796125873843'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2009/07/new-dynamic-dispatch-algorithm.html' title='A New Dynamic Dispatch Algorithm?'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-4106432049628233131</id><published>2009-05-15T23:17:00.000-07:00</published><updated>2009-05-16T00:12:05.509-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='programming languages'/><title type='text'>How should the syntax look in a c-like language with closures?</title><content type='html'>&lt;div&gt;I'm trying to see if I can create a nice syntax for a language that looks as close to C/C++/Java as possible while allowing syntax-like constructs to be defined by the programmer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It turns out it's not as easy as it sounds.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The problem lies in defining multi-part function. We start out easy: how do you define the following code as functions?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;if (b) &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   doWork();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;else&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   doSomeOtherWork();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;A stab at this particular syntax-turned-function might look like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;void if_new(boolean b, &amp;amp;statement) else(&amp;amp;elsestatement)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   if (b)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;      statement();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;      return;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   elsestatement();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That looks mighty fine (let's assume the compiler knows that our syntax with the "&amp;amp;statement" means that it should take a block and turn it into a function), but what about the compiler?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;if_new(b) { doSomething(); } &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;else { doSomethingElse(); }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;fooFun() { foo(); }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;barFun() { bar(); }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this case, how does the compiler know that the first line is a multi-part function and the second is not? I.e. how does it know that I want the function &lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;if_new(b)else()&lt;/span&gt;, but not &lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;fooFun()barFun()&lt;span class="Apple-style-span"  style=" ;font-family:Georgia;"&gt;? &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style=" ;font-family:Georgia;"&gt;One solution would be to impose a terminating ";" tax on every {}, like this:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;if_new(b) { doSomething(); } &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;else { doSomethingElse(); };&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;fooFun() { foo(); };&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;barFun() { bar(); };&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Another solution would be to make a much looser compilation the first time, and then actually treat these functions as formal syntax extensions, so that when the compiler sees "&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;if_new&lt;/span&gt;" it would recognize that an "&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;else&lt;/span&gt;" that follows it should be part of the function signature.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This sounds vaguely ok until you realize that you probably would like to be able to have multi-part object methods as well.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;An alternative, though syntax-altering, would be to explicitly add a linking character, something like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;if_new(b) &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{ &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   doSomething(); &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;} &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;:else &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{ &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   doSomethingElse(); &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unfortunately this means that all other multi-part syntax would have to follow the same rules, e.g.:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;if (x)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;:else&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;do&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;:while(x);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;try&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;:catch (Exception e)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;:finally&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;":" was the least intrusive character I could find, but if anyone else has a better suggestion I'd be happy to hear it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What got me thinking if this could be done was a &lt;a href="http://gafter.blogspot.com/2007/01/methodnamesinpieces.html"&gt;blog entry by Neal Gafter&lt;/a&gt; on multi-part method names in Java, and a &lt;a href="http://jroller.com/jadda/entry/multipiece_method_names"&gt;follow-up by Stefan Schulz&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1463803170752156221-4106432049628233131?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/4106432049628233131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=4106432049628233131' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/4106432049628233131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/4106432049628233131'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2009/05/how-should-syntax-look-in-c-like.html' title='How should the syntax look in a c-like language with closures?'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-7987166206757716874</id><published>2009-02-19T05:38:00.001-08:00</published><updated>2009-02-19T06:19:03.715-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='programming languages'/><title type='text'>(Ruby) Closures - jack of all trades, master of none.</title><content type='html'>&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;Ruby is based around closures. Closures are both used to represent blocks of code, as well as anonymous functions:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As an anonymous function:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;[1, 2, 3, 4].select { |i| i % 2 == 0 }  &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;# =&gt; returns [2, 4]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As a block of code:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;10.times do&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  puts "Hello World"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;end&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The problem is that they are not quite the same, and don't solve quite the same problem. In fact, I would go so far as to say that closures solve both problems... poorly.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As an anonymous function, closures grab a whole lot more context than you usually would like, and especially in ruby where you each closure by necessity always retain the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;complete&lt;/span&gt;&lt;/span&gt; context.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Its double nature as block and anonymous function means that exiting a closure occasionally works a bit different that expected, "return" alternately exits the current method or just returns the closure with that value. In some cases one can use "break" with an argument (a bit depending on what version of ruby you're using):&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;def test1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  [1, 2].collect(&amp;amp;Proc.new{ |i| return i })&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;end&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;p test1 # =&gt; 1&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;def test2&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  [1, 2].collect(&amp;amp;lambda{ |i| return i })&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;end&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;p test2 # =&gt; 1 ([1, 2] in 1.9)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;def test3&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  [1, 2].collect { |i| return i } &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;end&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;p test3 # =&gt; 1&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;def test4&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  [1, 2].collect(&amp;amp;Proc.new{ |i| break i })&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;end&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;p test4 # Illegal&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;def test5&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  [1, 2].collect(&amp;amp;lambda{ |i| break i })&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;end&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;p test5 # [1,2] (Illegal in 1.8)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;def test6&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  [1, 2].collect { |i| break i } &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;end&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;p test6 # =&gt; 1&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am tempted to suggest that instead of lumping these two different usages into a single concept (the closure), we would be better served by separating these into anonymous functions and blocks.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A block would inherit context but an anonymous function would not (it would instead resolve variable values during creation).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Of course, the following could would be slightly different from the closure version:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;a = 1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;f = function() { return a; }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;a = 2&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;p f.call() # =&gt; 1 (2 if this would have been a closure)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For our blocks this would allow us to unroll method calls, and in general optimize methods taking blocks as arguments by treating them as if the methods were macros.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Blocks and anonymous functions might not cover everything you can do with a closure, but how often do you really want a function that retains the whole context it was created in? &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1463803170752156221-7987166206757716874?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/7987166206757716874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=7987166206757716874' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/7987166206757716874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/7987166206757716874'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2009/02/ruby-closures-jack-of-all-trades-master.html' title='(Ruby) Closures - jack of all trades, master of none.'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-6455159239992951859</id><published>2008-12-27T04:32:00.000-08:00</published><updated>2008-12-27T04:35:38.074-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>New version of xmlwise out now.</title><content type='html'>My tiny java library for looking through xml has been updated. The only new addition is a small addition to allow simple reading of &lt;a href="http://en.wikipedia.org/wiki/Property_list"&gt;plist&lt;/a&gt; files.  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1463803170752156221-6455159239992951859?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/6455159239992951859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=6455159239992951859' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/6455159239992951859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/6455159239992951859'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/12/new-version-of-xmlwise-out-now.html' title='New version of xmlwise out now.'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-7411450383009637965</id><published>2008-11-16T05:40:00.000-08:00</published><updated>2008-11-16T06:09:21.305-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Read The Code</title><content type='html'>&lt;div&gt;I've been thinking a bit about code reading lately. When code reading usually comes up in a discussion, it is usually about how to document the code and how much comments to add.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But I'm thinking about the skill of pure code reading - the ability to read raw source code and figure out how it works. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Up until recently, I wasn't really aware of its importance. To be more exact, I assumed everyone's code reading skill more or less followed the overall amount of programming experience. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It turns out it's not quite like that. Instead I've come to understand that code reading is a skill quite separate from the "general programming" skill.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I talked to one colleague about reading code, and he told me his way through complex code was not to rush headlong into the code and read it until he understood it (my preferred method), but instead he would look to divide and refactor the code into separate pieces with clear interfaces until each piece could be understood on its own.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;While I think that this is a good approach to clear up complex code, it will still be hard to do the best possible refactorings unless you really understand the inner workings of the code you trying to clean.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This brings to mind a story that was related to me by another of my colleagues:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;This colleague had been hired as a consultant to finish some software project. Working his way through the code he was struck by how strange the programmer who originally worked on the project had designed the program.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Believing the previous programmer had simply made some design mistakes, he went ahead and threw away the weird parts of the code and started to rewrite them. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;His newly written code started out pretty clean, but as he began work on the details he noticed the need for amendments to his original design.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As he implemented more of the details and corrected his design to accomodate them, he began to realize that his design grew more and more to resemble the original "strange" design he had thrown out.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think this illustrates how hard it is to know what parts of the code are needlessly complex and can be safely thrown away, and what parts are complex because the code is handling some very complex details.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I suspect that good code reading skills always will be an edge, and in some cases even an essential skill.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what can we do to get better?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;There are a few ways I know of that will teach code reading: &lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;When reading a programming example, always try to run the whole programming code in your head to figure out what it does - never use code you don't understand.&lt;/li&gt;&lt;li&gt;Fix bugs in other people's code.&lt;/li&gt;&lt;li&gt;Translate code from one language into another.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;I haven't read it myself, but I suspect Diomidis Spinellis's &lt;a href="http://www.spinellis.gr/codereading/"&gt;Code Reading&lt;/a&gt; also has some good ideas, and Joel Spolsky has an interesting &lt;a href="http://www.joelonsoftware.com/articles/fog0000000053.html"&gt;blog entry&lt;/a&gt; that suggested a form "pair-reading" to get through truly complex code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But most important is, as always, the &lt;span class="Apple-style-span" style="font-style: italic; font-weight: bold;"&gt;desire&lt;/span&gt; to improve.&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/1463803170752156221-7411450383009637965?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/7411450383009637965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=7411450383009637965' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/7411450383009637965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/7411450383009637965'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/11/read-code.html' title='Read The Code'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-2753011462495004768</id><published>2008-11-14T07:50:00.001-08:00</published><updated>2009-02-19T06:21:37.549-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='documentation'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Good docs</title><content type='html'>&lt;div&gt;Good source code documentation is valuable because trying to document your code well tells you how (re)usable your code is: &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- If it's hard to explain (i.e. hard to write clear documentation) then it is hard to understand. &lt;/div&gt;&lt;div&gt;- If it is hard to understand it is hard to use (correctly). &lt;/div&gt;&lt;div&gt;- If it is hard to use, then others (and probably you yourself as well) are most likely to write something new next time rather than using or bug-fixing your code.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1463803170752156221-2753011462495004768?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/2753011462495004768/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=2753011462495004768' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/2753011462495004768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/2753011462495004768'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/11/good-docs.html' title='Good docs'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-2283299322342027678</id><published>2008-10-26T01:24:00.000-07:00</published><updated>2008-10-26T01:35:39.216-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='nio'/><title type='text'>Busy busy</title><content type='html'>Not much written in a while, but that is mostly because I've been busy with different projects. I added a list to this blog with the tiny open source projects I'm working/have been working on.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Naga&lt;/span&gt;&lt;/span&gt; is my wrapper library around Java NIO that implements the surprisingly complex amount of boiler-plate code you usually need to use NIO for socket client-server communication.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Xmlwise&lt;/span&gt;&lt;/span&gt; is even more modest. Basically it is a few Java classes that extract data from an already parsed XML document, making the data easy to access by moving it into standard structures (HashMaps and LinkedLists). These classes have made it a delight for me to work with XML documents, and hopefully they'll be of use to others as well.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are some other libs in progress as well.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1463803170752156221-2283299322342027678?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/2283299322342027678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=2283299322342027678' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/2283299322342027678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/2283299322342027678'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/10/busy-busy.html' title='Busy busy'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-7842869816452007483</id><published>2008-10-10T01:10:00.000-07:00</published><updated>2008-10-10T01:43:25.134-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='documentation'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>The sad sad state of automatic docs</title><content type='html'>&lt;div&gt;At work I do server programming in Java and after a while I guess you start to get erronous idea that all automatic docs are like javadoc or better.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oh, so &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;rdoc&lt;/span&gt; (Ruby) sucks like the end of the world, and &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;ri&lt;/span&gt; is a joke, but those are just exceptions - right?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;...or so I thought until I tried to look at some Doxygen documentation for LLVM... It made me want to claw my eyes out to make the horrible thing go away. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I mean &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;WHAT IS WRONG WITH THE WORLD&lt;/span&gt; people!? Look, when old-timers &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;man&lt;/span&gt; and &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;javadoc&lt;/span&gt; still is the cutting edge, you know you're in a really sad place.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I thought the Objective-C documentation was pretty bad, but it's like a shining beacon of light in comparison.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The bat-crazy thing is that people write stuff like "I love Doxygen, it is teh bestest", like there is even a remote possibly it could be true.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I read one exchange where people argued that the reason Doxygen docs sucked - everywhere - was because people didn't configure it right and didn't stick with the conventions...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I hate to break it to you people but it is a &lt;span class="Apple-style-span" style="font-style: italic;"&gt;f*****g tool&lt;/span&gt;, and a tool is supposed to &lt;span class="Apple-style-span" style="font-style: italic;"&gt;help&lt;/span&gt;, not make you spend hours in configuration and figuring out best practices. So if your so-called tool isn't helpful, you're way better off writing the docs by hand - and I don't care if the tool creates some fancy but utterly unusable class diagrams, it is still worthless.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Javadoc&lt;/span&gt; and &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;man&lt;/span&gt; already shows exactly what any documentation &lt;span class="Apple-style-span" style="font-style: italic;"&gt;at least&lt;/span&gt; have to live up to. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It is really easy, here is a check-list on what an auto-doc tool needs.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;1. &lt;/span&gt;&lt;span class="Apple-style-span" style=""&gt;&lt;span class="Apple-style-span" style="font-style: italic; "&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Great&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt; formatting. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Not "acceptable", not "good". It has to be great. You already had to break your coding flow to look something up, so the formatting needs to be crisp sharp to guide you to exactly the information you need as fast as possible so you can get back as fast as possible.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;2. Zero configuration. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Configurable tools suck, yes they suck. Because most of the time "configurability" is nothing more than an excuse for the tool coder not to figure out good defaults for you.&lt;br /&gt;&lt;br /&gt;Yes it is worthwhile to have some configurable parameters, but it should be the exception rather than the rule. If things are configurable, then doc A and doc B will look different, and a programmer used to look at docs generated with style A will be confused by style B and vice-versa. In documentation, consistency is king.&lt;br /&gt;&lt;br /&gt;Obviously this has to be language specific, but within a language the docs should look the same. If you are making a tool and plan to make the user to configure everything, then you are a lazy bastard.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;3. Well thought out and clear doc conventions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Your tool should make it easy for a programmer to know what the can make the auto-doc tool improve the documentation.&lt;br /&gt;Start looking at &lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;Javadoc&lt;/span&gt; - it is not great but it works. We have the basic &lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;@param&lt;/span&gt;, &lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;@throws&lt;/span&gt; and &lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;@return&lt;/span&gt;. It should be easy to expand that and adapt specific conventions for each language.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;4. Remember the needs of the programmer&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Find the common use cases and optimize for them.&lt;br /&gt;&lt;br /&gt;When programming Java, in the majority of cases I look up docs for one of three reasons:&lt;br /&gt;&lt;br /&gt;  1. To find the correct method to call on a class.&lt;br /&gt;  2. To understand the workings of a method of a class.&lt;br /&gt;  3. To find the correct class to use in a library/framework.&lt;br /&gt;&lt;br /&gt;Javadoc is fairly optimized to for this: It's easy to scroll through the methods. If you click a method then the description gives you the basic arguments, and there is a doc convention to describe the most important information (parameters, return value, when exceptions are thrown). &lt;br /&gt;It is also easy to find a class due to the package structuring and the quick links to implementing classes/subclasses.&lt;/blockquote&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Automatic documentation &lt;span class="Apple-style-span" style="font-style: italic;"&gt;is&lt;/span&gt; a solved problem. Too bad no-one seems to be looking at the solutions.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm going to finish with a quote from the Qt-list: &lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;blockquote&gt;"It's [blaming Doxygen for the bad documentation], or blame almost every single user of the tool. At this point, I'd prefer to blame the tool."&lt;/blockquote&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1463803170752156221-7842869816452007483?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/7842869816452007483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=7842869816452007483' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/7842869816452007483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/7842869816452007483'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/10/sad-sad-state-of-automatic-docs.html' title='The sad sad state of automatic docs'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-3123361841036735630</id><published>2008-10-04T10:57:00.000-07:00</published><updated>2008-10-04T11:07:41.875-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dynamic languages'/><category scheme='http://www.blogger.com/atom/ns#' term='programming languages'/><title type='text'>The old static vs dynamic typing...</title><content type='html'>&lt;span class="Apple-style-span"  style=" ;font-family:Times;"&gt;&lt;div style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; width: auto; font: normal normal normal 100%/normal Georgia, serif; text-align: left; "&gt;&lt;div&gt;Instead of rehashing the old arguments, I'd like to point out some observations I've made.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The best GUI builder I've encountered is Interface Builder on Mac OS X and it works because Objective-C is a dynamically typed language. It is very to use and yet incredibly powerful.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What you notice from the beginning, is that you are building the GUI by instantiating flexible objects, instead of creating thousands of subclasses like Java would make you do.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;IB is one of the few development tools that actually manage to deliver on the concept of object oriented programming as assembly of reusable building blocks.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What makes this possible is the way dynamic typing naturally decouples the system. It is almost like magic.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Another kind of magic made possible by dynamic typing is dynamic message forwarding.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here is an example, code is in an imagined dynamically typed Java.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here is a tree class:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Class Tree&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;Map m_values;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;public Tree()&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;    &lt;/span&gt;m_values = new HashMap();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;public Object methodMissing(Method method, &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                              Object... args)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;    &lt;/span&gt;if (args.length == 0)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;    &lt;/span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;      &lt;/span&gt;return m_values.get(method.getName());&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;    &lt;/span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;    &lt;/span&gt;if (args.length == 1 &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        &amp;amp;&amp;amp; isSetterMethod(method.getName()))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;    &lt;/span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;      &lt;/span&gt;set(getVariableToSet(method.getName()), args[0]);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;    &lt;/span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;public Object set(String value, Object object)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;    &lt;/span&gt;m_values.put(value, object);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;public Object addBranch(String name)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;    &lt;/span&gt;m_values.put(name, new Tree());&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  // return true if the string is a typical &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  // setter, e.g. "setSomeVariable"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  public boolean isSetterMethod(String) { ... } &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  // return variable name from a setter, e.g. &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  // "setSomeVariable" returns "someVariable"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  &lt;/span&gt;public boolean getVariableToSet(String) { ... } &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We can use it this way:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Tree registry = new Tree();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;t.addBranch("settings");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;t.settings().setTimeout(100L);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;t.settings().setHost("www.google.com");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;System.out.println(t.settings().timeout()); &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;// prints "100"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;System.out.println(t.settings().host()); &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;// prints "www.google.com"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Although this kind of coding can be misused, it is immensely powerful when it comes to avoiding boilerplate coding. In fact, the whole concept of automatic code generation used by many Java frameworks becomes completely unnecessary in dynamically typed languages. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Without dynamic typing, we deny ourselves a range of tools that does not fit in a statically typed universe. If all you've used is statically typed languages it is hard to understand the kind of freedom dynamic typing really give you, and therefore it's also hard to understand what you are sacrificing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That said, a statically typed language has the advantage of clarity of intent which can be a substantial win in certain situations.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is why I think that the next big development language ought to be dynamically typed but with optional static typing: the best of both worlds.&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/1463803170752156221-3123361841036735630?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/3123361841036735630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=3123361841036735630' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/3123361841036735630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/3123361841036735630'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/10/old-static-vs-dynamic-typing.html' title='The old static vs dynamic typing...'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-639012717558262165</id><published>2008-09-21T12:12:00.000-07:00</published><updated>2008-09-21T13:31:38.427-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='newspeak'/><category scheme='http://www.blogger.com/atom/ns#' term='dynamic languages'/><category scheme='http://www.blogger.com/atom/ns#' term='programming languages'/><title type='text'>Heard about Newspeak</title><content type='html'>&lt;a href="http://newspeaklanguage.org/"&gt;Newspeak&lt;/a&gt; hit the blogosphere recently, popping up on &lt;a href="http://www.reddit.com/"&gt;Reddit&lt;/a&gt;.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I obviously had to have a look, and it could be briefly described as an OO language with a (currently) smalltalk-ish syntax. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is not Smalltalk however, despite borrowed syntax and Smalltalk-like dynamic typing. Instead it tries to be a new language that incorporates many of the newer ideas in language design.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One of the people working on Newspeak is &lt;a href="http://bracha.org/"&gt;Gilad Bracha&lt;/a&gt;. Aside from working on &lt;a href="http://www.strongtalk.org/"&gt;Strongtalk&lt;/a&gt; (a &lt;span class="Apple-style-span" style="font-style: italic;"&gt;fast&lt;/span&gt; Smalltalk implementation with optional typing) he's known for writing a lot of papers on various aspects on OO as well as having had a hand in how generics was added to Java. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Looking through the papers is like looking through the feature list of &lt;a href="http://newspeaklanguage.org/"&gt;Newspeak&lt;/a&gt;: pluggable types, the concept of &lt;span class="Apple-style-span" style="font-style: italic;"&gt;m&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;irrors&lt;/span&gt; for reflection, mixins for Strongtalk... they're all there.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I could write something about the language in general, but it's easier just to direct you to &lt;a href="http://newspeaklanguage.org/"&gt;the website&lt;/a&gt; for the overview.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, I was reading through the spec today and found a bunch of small but interesting things about the language. For instance, Newspeak will be implementing fixed decimal representations, which means that doing something like 1.0000000000001 - 1.0 will actually return 0.0000000000001 instead of some unexpected number due to an imprecise floating point representation. It will use &lt;a href="http://en.wikipedia.org/wiki/Actor_model"&gt;Actor model&lt;/a&gt; concurrency (very nice), it's going to have true immutable objects and of course the mirrors and pluggable types are there too.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Everything boiling down to a (potentially) very interesting language.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;/C  &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1463803170752156221-639012717558262165?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/639012717558262165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=639012717558262165' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/639012717558262165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/639012717558262165'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/09/heard-about-newspeak.html' title='Heard about Newspeak'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-8753429953987777188</id><published>2008-09-08T08:12:00.001-07:00</published><updated>2008-09-08T08:50:35.521-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='dynamic languages'/><category scheme='http://www.blogger.com/atom/ns#' term='programming languages'/><category scheme='http://www.blogger.com/atom/ns#' term='multiple dispatch'/><title type='text'>More multiple dispatch</title><content type='html'>&lt;div&gt;I've been looking a bit more at multiple dispatch (multimethods). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The neat thing is that you can view multiple dispatch as sort of a superset of dynamic typing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For example, if I define (I'm going to use Java-like syntax here) the free function:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;void open(Door this, Key key)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;then this is equivalent to creating the method&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;class Door&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   void open(Key key)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;      ....&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So something like &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;door.open(myKey)&lt;/span&gt; could be considered simply syntactic sugar for &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;open(door, myKey)&lt;/span&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unlike in Java, this would compile:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Door door = new Door();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Object hiddenDoor = door;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;hiddenDoor.open(myKey);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;...since the actual check is always done during runtime.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If we try to pass off something as a door, this will fail during runtime as well:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Dog dog = new Dog();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;dog.open(myKey); // =&gt; Runtime Error!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Which is essentially dynamic typing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What is so damn cool about multiple dispatch, is that this far from all you can do with it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In an dynamically typed language like Ruby, your method would look like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;class Door&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   def open(key)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;      ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   end&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;end&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But what happens if we do something like &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;door.open(tomato)&lt;/span&gt;? Well there are two ways out: fail-fast or fail-at-some-other-time. Fail-fast would mean some check on the incoming object to make sure that it has the required key-like properties, fail-later would be to let the "key" fail when - at some later time - it is used under the assumption that it is a key.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With typed multiple dispatch we can make sure that it is a key (like in a statically typed language), while retaining a lot of flexibility.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, there is one issue. What if &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Key&lt;/span&gt; is a class, and you want to pass in a &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;LockPick&lt;/span&gt; that doesn't inherit from &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Key&lt;/span&gt;?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Basically what you want to do is:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;LockPick pick = new LockPick(key);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;door.open(pick);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The standard way to solve this in normal Java would be to replace the &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Key&lt;/span&gt; with an interface and let both &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;LockPick&lt;/span&gt; and &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Key&lt;/span&gt; implement it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So we replace the function with:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;void open(Door this, KeyInterface keyInterface)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now as long as &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Key&lt;/span&gt; and &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;LockPick&lt;/span&gt; both implement &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;KeyInterface&lt;/span&gt; we're ok.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What happens in Java is that &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;KeyInterface&lt;/span&gt; actually allows us to have something akin to multiple inheritance while retaining most of the simplicity of single inheritance.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With single inheritance like Java, we cannot create&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;class TrollWarrior extends Warrior, Troll&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Instead we have to select one to be an interface, like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;class TrollWarrior extends Warrior implements Troll&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   ...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Something funny happens if we have multiple-dispatch though:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If we can define:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;void exposeToSunlight(Object self) {}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;void exposeToSunlight(Troll self)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   self.turnToStone();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then obviously &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;humanWarrior.exposeToSunlight()&lt;/span&gt;is going to be different than &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;trollWarrior.exposeToSunlight()&lt;/span&gt;! So what has happened? Well, it turns out that once we add multiple dispatch, interfaces basically turn into classes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The downside is that multiple inheritance can be a bit tricky, especially when functions overlap. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Say both classes A and B implement their special version of &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;toString()&lt;/span&gt;, what version should the class C, inheriting from A and B use?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It turns out that creating a precedence rule isn't trivial. Fortunately, the problem has pretty much been solved already, and the answer is called &lt;a href="http://192.220.96.201/dylan/linearization-oopsla96.html"&gt;C3 &lt;/a&gt;&lt;a href="http://192.220.96.201/dylan/linearization-oopsla96.html"&gt;linearization&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Basically this is an algorithm that takes an inheritance tree and flattens it in a way that ensures consistency in three ways (hence the 3).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here is a pseudo Java example:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;class A&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;public String hello() { return "A"; }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;class B&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;public String hello() { return "B"; }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;class C extends B&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;public String hello() { return "C"; }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;class D extends A, B&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;class E extends A, C&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If we suppose that &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;new D().hello()&lt;/span&gt; returns "A", what does &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;new E().hello()&lt;/span&gt; return?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The surprising result is that many implementations of multiple dispatch in different languages would return "C"! The C3 algorithm however, does the right thing and gives us the "A" we would expect.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The C3 linearization algorithm was first created for Dylan, but has eventually worked itself into other languages as default.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I couldn't find any implementation of the algorithm in other languages than Dylan and Scheme, but the page on C3 for Python 2.3 had a &lt;a href="http://www.python.org/download/releases/2.3/mro/"&gt;very clear description&lt;/a&gt; of the algorithm.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here's my Ruby version of it (the Java version was about 5 times as long):&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;def c3(own_class, list_of_&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;linearizations&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  &lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;linearization&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; = [own_class]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  while !list_of_&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;linearizations&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;.empty? do&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    next_value = list_of_&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;linearizations&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;.find do |c| &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;      list_of_&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;linearizations&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;.all? do |d| &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        !d[1..-1].member?(c[0])&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;      end&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    end&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    raise "Illegal inheritance"  unless next_value&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    head = next_value[0]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    &lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;linearization&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; &lt;&lt;&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    list_of_&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;linearizations&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;.each { |c| c.delete(head) }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;    list_of_&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;linearizations&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;.reject! { |c| c.empty? }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  end&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;  &lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;linearization&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;end&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It might look a bit tricky, but it's not so bad once you wrap your head around it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Multiple dispatch keeps looking better every time I look at it, which makes me all the more embarrassed that I never looked at CLOS (CLOS bases its OO system on multiple dispatch). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was really surprised and impressed by the fact that support for dynamic typing and multiple inheritance arose spontaneously from just following consequences of basic multiple dispatch. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1463803170752156221-8753429953987777188?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/8753429953987777188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=8753429953987777188' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/8753429953987777188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/8753429953987777188'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/09/more-multiple-dispatch.html' title='More multiple dispatch'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-8241285388943284734</id><published>2008-09-03T12:13:00.000-07:00</published><updated>2008-09-04T10:27:56.267-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='threads'/><category scheme='http://www.blogger.com/atom/ns#' term='nio'/><title type='text'>Java multi threaded blocking IO wins over NIO?!</title><content type='html'>I just read through a blog post titled "&lt;a href="http://paultyma.blogspot.com/2008/03/writing-java-multithreaded-servers.html"&gt;Writing Java Multithreaded Servers - What's old is new&lt;/a&gt;". Basically they did some &lt;span class="Apple-style-span" style="font-style: italic;"&gt;serious&lt;/span&gt; benchmarking on java with NIO vs threads with blocking IO and found that the latter was faster and scaled well too.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Before you run into the streets shouting "Lies! Bloody lies all of it!", I think I should mention that this was on the 2.6 Linux kernel. If you have played around with threads on earlier Linux kernels, you know that threads on those systems ate resources like crazy. Apparently the new threading implementation changed all that. Interestingly, Windows XP also show significantly better performance with multiple threads rather than NIO.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Talk about the world turning upside down.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That said, I still am not 100% convinced that the last word has been said. Most of the examples were of IO where data flows in one direction at a time. This is where multi-threaded blocking IO rules. But what if you have something like say an online poker server, where you have continuous input and output? Suddenly one thread isn't good enough, you need at least one for input and one for output. In addition, any timeouts require yet another thread, since it has to be unaffected by the blocking IO.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So say you have your java process with 15k connections. That's a whopping 30k threads just to handle the IO. That is not counting the threads for the poker tables or db access.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What's more, both input and output threads become little more than worker threads to receive and send data, since the actual gameplay will necessarily run on another thread. This means that all the connection input thread will do is really to read input and dispatch it to some poker table thread. A message being another word for "event".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Which means we're back to event handling just like in the NIO case, and we just gained 30k threads mostly doing nothing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I'm trying to say is that I don't think the results are as conclusive as they may seem. Yes, there are many applications where threads with blocking IO makes things incredibly easy to code, and that's where the benchmarks are applicable, but then there are other situations where they quite simply doesn't make sense, like in the poker server example, where each connection would require more threads and those threads in turn would need to communicate with other threads a lot more.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&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/1463803170752156221-8241285388943284734?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/8241285388943284734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=8241285388943284734' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/8241285388943284734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/8241285388943284734'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/09/java-multi-threaded-blocking-io-wins.html' title='Java multi threaded blocking IO wins over NIO?!'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-1740956235130388624</id><published>2008-08-31T01:35:00.000-07:00</published><updated>2008-09-08T08:37:02.627-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming languages'/><category scheme='http://www.blogger.com/atom/ns#' term='multiple dispatch'/><title type='text'>Multiple Dispatch can be neat</title><content type='html'>I was looking at &lt;a href="http://tunes.org/~eihrul/ecoop.pdf"&gt;this paper&lt;/a&gt; regarding multiple dispatch.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Coming from a java point of view, I still remember the disappointment the first time I realized that Java didn't have multiple dispatch. You know, the first time you realize that:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;public static void a(Object o)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;   &lt;/span&gt;System.out.print("1");&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;public static void a(Number n)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;   &lt;/span&gt;System.out.print("2");&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;public static void main(String... args)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;   &lt;/span&gt;Object o = new Integer(3);&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;   &lt;/span&gt;a(o);&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;   &lt;/span&gt;a((Number) o);&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;...would write "12" instead of "22".  (Of course, in functional languages this is taken even further with pattern matching)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I found more examples when looking at &lt;a href="http://slate.tunes.org/"&gt;Slate,&lt;/a&gt; a Smalltalk-ish langage with this type of multiple dispatch (apparently development on the language is pretty much abandoned now though). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The advantages with multiple dispatch is discussed in the paper I linked to, but as a quick recap it allows you to push variant behaviour into different methods instead of using something like "instance of" or its variants.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sure, it is possible to push back behaviour to the target object, but it is not always possible. Here is a standard "equals" method in java:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;public boolean equals(Object otherKey) &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   if (this == otherKey) &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;      return true;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   if (otherKey instanceof Key) &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;      Key key = (Key) otherKey;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;      return m_id == key.getId();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   return false;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;If java had multiple dispatch we could simplify this to:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;public boolean equals(Key otherKey) &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;   return m_id == key.getId();&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style=" ;font-family:Georgia;"&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;public boolean equals(Object otherObject) &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   return false;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Which one is better should be pretty obvious.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There has been work on &lt;a href="http://research.att.com/~bs/multimethods.pdf"&gt;multiple dispatch for C++&lt;/a&gt; that almost made it to C++0x, but apparently it came a bit too late to be included. CLOS and Dylan are the two languages usually mentioned in regards to multiple dispatch, but there is also support for it in &lt;a href="http://nice.sourceforge.net/"&gt;Nice&lt;/a&gt;, the previously mentioned &lt;a href="http://slate.tunes.org/"&gt;Slate&lt;/a&gt;, Cecil, &lt;a href="http://dev.perl.org/perl6/"&gt;Perl 6&lt;/a&gt; and &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&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/1463803170752156221-1740956235130388624?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/1740956235130388624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=1740956235130388624' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/1740956235130388624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/1740956235130388624'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/08/multiple-dispatch-can-be-neat.html' title='Multiple Dispatch can be neat'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-1424576059650829485</id><published>2008-08-26T08:43:00.000-07:00</published><updated>2008-09-04T10:29:55.281-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming languages'/><title type='text'>My Own Language Wish List</title><content type='html'>I am working on a programming language idea, it's just for fun and nothing will probably come out of it, but the research itself is proving incredibly rewarding.&lt;br /&gt;&lt;br /&gt;Here is my wish list:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;OO with C-like syntax&lt;/li&gt;&lt;li&gt;Both implicitly and explicitly defined protocols &lt;span class="Apple-style-span" style="font-style: italic;"&gt;(interfaces)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Mixins for shared implementation.&lt;/li&gt;&lt;li&gt;&lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/chapter_4_section_1.html#//apple_ref/doc/uid/TP30001163-CH20-SW1"&gt;Categories&lt;/a&gt; &lt;span class="Apple-style-span" style="font-style: italic;"&gt;(add methods but not ivars to existing classes)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Dynamically typed with optional static typing with both static and runtime checks.&lt;/li&gt;&lt;li&gt;Unambiguous grammar &lt;span class="Apple-style-span" style="font-style: italic;"&gt;(Compare with Ruby where you can shadow methods with local variables and vice-versa)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;All statements return a value &lt;span class="Apple-style-span" style="font-style: italic;"&gt;("self" is default)&lt;span class="Apple-style-span" style="font-style: normal; "&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-style: normal; "&gt;Compiles to C&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-style: normal; "&gt;Should work seamlessly with C-code &lt;/span&gt;(may include .h files, call C directly without implicit type conversion)&lt;span class="Apple-style-span" style="font-style: normal; "&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-style: normal; "&gt;Module system similar to that of &lt;a href="http://www.digitalmars.com/d/2.0/module.html"&gt;D&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-style: normal; "&gt;Real hygienic macros.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-style: normal; "&gt;Coroutines&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-style: normal; "&gt;Closures&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-style: normal; "&gt;Invariants&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-style: normal; "&gt;First class functions.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-style: normal; "&gt;Metaprogramming &lt;/span&gt;(including directly working with the current context, replacing Closure bindings etc)&lt;span class="Apple-style-span" style="font-style: normal; "&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-style: normal; "&gt;&lt;a href="http://www.cs.umd.edu/~jfoster/arrows.pdf"&gt;Arrows&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I'm also considering no direct thread access, but to provide other ways to easily parallelize things across multiple threads.&lt;br /&gt;&lt;br /&gt;Basically I think that raw multithreading usually is more of a problem than a solution.&lt;br /&gt;&lt;br /&gt;Asynchronous communication should be built in and be the default. I am looking at &lt;a href="http://www.iolanguage.com/"&gt;Io&lt;/a&gt; as a good example here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1463803170752156221-1424576059650829485?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/1424576059650829485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=1424576059650829485' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/1424576059650829485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/1424576059650829485'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/08/i-am-working-on-programming-language.html' title='My Own Language Wish List'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-1210787827925524161</id><published>2008-08-24T00:26:00.001-07:00</published><updated>2008-09-04T10:30:32.995-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dynamic languages'/><category scheme='http://www.blogger.com/atom/ns#' term='programming languages'/><category scheme='http://www.blogger.com/atom/ns#' term='type inference'/><title type='text'>The Compiler Puzzle</title><content type='html'>&lt;span class="Apple-style-span"   style="  ;font-family:Helvetica;font-size:12px;"&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; "&gt;I've been playing with the idea to create a programming language, mostly for fun - to learn something about writing programming languages. &lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; min-height: 16px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; "&gt;Now I almost regret it, it's like an addiction, reading about different languages, compile-time optimization, fast message dispatch, garbage collection algorithms and the list goes on. It's really a fascinating subject, as addictive as any puzzler game.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; min-height: 16px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; "&gt;This is, by the way, why I even started to look at D in depth (unfortunately for me, D 2.0 has no mac compiler so I can't really play around with it), and today I stumbled over &lt;a href="http://factorcode.org/"&gt;&lt;span style="text-decoration: underline; color: rgb(75, 34, 136); "&gt;Factor&lt;/span&gt;&lt;/a&gt; while looking for ways to optimize simple calls like +, -, *, % and /. &lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; min-height: 16px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; "&gt;One problem in dynamically typed languages without primitives is that a simple a + 1 is as expensive as the call a.doSomething(1).&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; min-height: 16px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; "&gt;So the code that looks like this in C:&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; min-height: 16px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;int someFunction(int a, int b, int c)&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;a = 10 * b + c;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;b = a % 37;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;c += (a + c) % 3;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;return a + b + c;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;}&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;  &lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; min-height: 16px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; "&gt;would in a dynamically typed language with a naive compiler translate to:&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; min-height: 16px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;someFunction(a, b, c)&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;a = b.mult(10).add(c);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;b = a.mod(37);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;c = c.add(a.add(c).mod(3));&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;return a.add(b).add(c);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal 'Courier New'; "&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; min-height: 16px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; "&gt;If this was C++ and the methods non-virtual, then it would be a simple thing for the compiler to inline them, with dynamic dispatch on the other hand, it's not that simple, and when you have dynamic typing the situation is even worse, because at compile time there is no way to even know what type a, b and c will have. It gets worse because dynamic message passing is a lot slower than than normal dynamic dispatch in statically typed languages.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; min-height: 16px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; "&gt;One of the ways to alleviate this problem somewhat is by using type inference, which is one thing that Factor does.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Georgia; "&gt;It's like a game... how do you make the computer work as fast when you feed it objects it has to figure how to use, as when it is given clear instructions? If &lt;span class="Apple-style-span" style="font-style: italic;"&gt;"as fast"&lt;/span&gt; is impossible, then how do you get it really, really close? Oh, it's a very nice puzzler indeed.&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/1463803170752156221-1210787827925524161?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/1210787827925524161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=1210787827925524161' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/1210787827925524161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/1210787827925524161'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/08/compiler-puzzle.html' title='The Compiler Puzzle'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-2403617952868567681</id><published>2008-08-23T05:52:00.000-07:00</published><updated>2008-09-04T10:31:00.999-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>I like Ruby - but big projects suck.</title><content type='html'>&lt;div&gt;I like Ruby, I like it a lot, but I keep running into some issues. &lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But first off let me say that for small programs, Ruby is absolutely wonderful. It is sad to see people struggle to write x10 or x100 the amount of code trying to do the same thing in Java because they don't know anything easier to use.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But then there are the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;huge&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt; projects. The ones with 50.000+ lines of code if written in Java and a fraction of that if written in Ruby. That is where the problems show up. Because even at 50.000 lines of code, a project is quite manageable in Java with a good IDE. With Ruby, 5000 is frickin bad.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think some of the reason is because Ruby doesn't provide an easy way to maintain a project structure. Where a hierarchy is almost required in Java, it is actually outright &lt;span class="Apple-style-span" style="font-style: italic;"&gt;hard&lt;/span&gt; to get it to work in Ruby. I don't particularly enjoy adding a header to every ruby file just to make sure it both can run stand-alone and compile properly with the rest of the project. Unit tests need even more path-magic to work.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The problem is compounded by the fact that you really would like to have well encapsulated libraries of code within a single project. In Ruby you sometimes write fiendishly clever and hard-to-understand code to simplify development in the rest of the code. Normally you'd then hide that implementation either as a separate jar/library/module, or at least in some (in Java terms) sub-package to insulate you from the implementation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unfortunately there are few ways to achieve that aside from building a full-fledged gem. And since there are no interfaces/protocols in Ruby, nor is it immediately clear from a class definition what public functions and methods your code actually provides, you probably are going try to read that code many times again, trying to understand exactly what it did, losing something like half an hour of productive work every time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This problem could have been made smaller if rdoc was better, but when comparing it to say Javadoc, it is laughingly bad. Add to this the fact that rdoc is really lacking everywhere, both for ruby core classes and as for ruby gems, you should count yourself lucky if you find one with rdocs. So... again you are forced to read the actual code to understand how to properly use it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Speaking of gems... this is yet another sad point compared to other languages. Jars and classpaths with Java suck, but at least you have your dependencies bundled up in a few files, whereas with gems you have them installed somewhere on your computer. This might be convenient for development, but not as good if you are writing something as a stand-alone program. Even c headers bundled with a library is a lot easier to get the hang of.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When I look at Python, which seems to have a sane module system and even docs bundled with the classes. I can't help but to wonder why Ruby hasn't borrowed these things already. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Could it really be that most people still are only using Ruby for small projects?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1463803170752156221-2403617952868567681?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/2403617952868567681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=2403617952868567681' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/2403617952868567681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/2403617952868567681'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/08/i-like-ruby-but-big-projects-suck.html' title='I like Ruby - but big projects suck.'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-3256166746323881344</id><published>2008-08-19T02:46:00.000-07:00</published><updated>2008-09-04T10:31:19.086-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='D'/><category scheme='http://www.blogger.com/atom/ns#' term='programming languages'/><title type='text'>D' nice kitchen sink</title><content type='html'>I have been looking a bit at D, without playing around with it any. That, of course, means I know nothing about the language whatsoever. It looks like it has pretty much &lt;span style="font-style:italic;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;everything&lt;/span&gt;&lt;/span&gt; in it. &lt;div&gt;&lt;br /&gt;C-style programming - &lt;span class="Apple-style-span" style="font-style: italic;"&gt;check&lt;/span&gt;, type inferrence - &lt;span class="Apple-style-span" style="font-style: italic;"&gt;check&lt;/span&gt;, contracts - &lt;span class="Apple-style-span" style="font-style: italic;"&gt;check&lt;/span&gt;, modules - &lt;span class="Apple-style-span" style="font-style: italic;"&gt;check&lt;/span&gt;, classes - &lt;span class="Apple-style-span" style="font-style: italic;"&gt;check&lt;/span&gt; ...and so on.&lt;br /&gt;&lt;br /&gt;(Which actually makes me pretty reluctant to use it for anything. Kitchen-sink programming languages always worry me for some reason.)&lt;br /&gt;&lt;br /&gt;Anyway, the really cool thing about it is all those articles that keep popping up where people &lt;span style="font-style:italic;"&gt;extend&lt;/span&gt; it to do neat things.&lt;br /&gt;&lt;br /&gt;I only have two articles on the top of my head:&lt;br /&gt;&lt;a href="http://www.digitalmars.com/d/2.0/accu-functional.pdf"&gt;www.digitalmars.com/d/2.0/accu-functional.pdf&lt;/a&gt;&lt;br /&gt;&lt;a href="http://bartoszmilewski.wordpress.com/2008/08/16/thin-lock-implementation/"&gt;bartoszmilewski.wordpress.com/2008/08/16/thin-lock-implementation/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;...but there are a lot more of them, and they're not just interesting from a D-programmer perspective, but the articles actually feel relevant to other imperative languages as well.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;Very&lt;/span&gt; nice indeed.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1463803170752156221-3256166746323881344?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/3256166746323881344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=3256166746323881344' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/3256166746323881344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/3256166746323881344'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/08/d-nice-kitchen-sink.html' title='D&apos; nice kitchen sink'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1463803170752156221.post-6662184822358993364</id><published>2008-08-19T00:13:00.000-07:00</published><updated>2008-08-19T00:18:23.258-07:00</updated><title type='text'>Starting a blog</title><content type='html'>So, after getting addicted to reading programmer blogs, I'm going to try my hand at keeping one of my own. We'll see how it works out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1463803170752156221-6662184822358993364?l=monkeypatched.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://monkeypatched.blogspot.com/feeds/6662184822358993364/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1463803170752156221&amp;postID=6662184822358993364' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/6662184822358993364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1463803170752156221/posts/default/6662184822358993364'/><link rel='alternate' type='text/html' href='http://monkeypatched.blogspot.com/2008/08/starting-blog.html' title='Starting a blog'/><author><name>Christoffer Lernö</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://1.bp.blogspot.com/_q4DXX7owlWg/SLEkW43CPzI/AAAAAAAAAAo/a7NAr9uXDus/S220/kgs.jpg'/></author><thr:total>0</thr:total></entry></feed>
