<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<feed xmlns="http://www.w3.org/2005/Atom">

	<title>Unofficial Erlang Planet</title>
	<link rel="self" href="http://www.erlangplanet.org/atom.xml"/>
	<link href="http://www.erlangplanet.org/"/>
	<id>http://www.erlangplanet.org/atom.xml</id>
	<updated>2010-03-10T23:01:10+00:00</updated>
	<generator uri="http://www.planetplanet.org/">Planet/2.0 +http://www.planetplanet.org</generator>

	<entry xml:lang="en">
		<title type="html">Zotonic destroys WordPress and rethinks the CMS with Erlang</title>
		<link href="http://erlanginside.com/zotonic-destroys-wordpress-and-rethinks-the-cms-with-erlang-149"/>
		<id>http://erlanginside.com/?p=149</id>
		<updated>2010-03-09T20:50:03+00:00</updated>
		<content type="html">A chat with Marc Worrell, Lead Architect of Zotonic - a new Content Management System written entirely in Erlang.</content>
		<author>
			<name>Chad DePue</name>
			<uri>http://erlanginside.com</uri>
		</author>
		<source>
			<title type="html">Erlang Inside</title>
			<subtitle type="html">News and Information on Erlang and Concurrent Computing</subtitle>
			<link rel="self" href="http://erlanginside.com/feed/atom"/>
			<id>http://erlanginside.com/feed/atom</id>
			<updated>2010-03-09T21:00:48+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">CouchDB Case Study: Assay Depot</title>
		<link href="http://damienkatz.net/2010/03/couchdb_case_study_assay_depot.html"/>
		<id>tag:damienkatz.net,2010://1.556</id>
		<updated>2010-03-06T23:40:35+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;&lt;a href=&quot;http://blog.couch.io/post/430899411/assay-depot-cio-chris-petersen-discusses-couchdb&quot;&gt;Apache CouchDB Case Study: Assay Depot&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;&lt;div&gt;...replication give this ability that would have been much more difficult to accomplish in MySQL. We could have done this in a relational manner but it would have been very challenging, very custom. CouchDB give a lot of the benefits for free.
&lt;/div&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;div&gt;CouchDB has changed the way I think about developing web applications&lt;/div&gt;&lt;/blockquote&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-03-06T23:46:10+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Talkr.IM XMPP/Jabber server gets Apple Push notifications</title>
		<link href="http://www.process-one.net/en/blogs/article/talkr.im_xmpp_jabber_server_gets_apple_push_notifications/"/>
		<id>tag:process-one.net,2010:en/blogs/3.2464</id>
		<updated>2010-03-04T09:43:17+00:00</updated>
		<content type="html">&lt;p&gt;The free public XMPP/Jabber server Talkr.IM gets Apple Push notifications for iPhone.&lt;/p&gt; &lt;p&gt;The ProcessOne's free, open, public XMPP/Jabber server Talkr.IM is gaining a new feature: Apple Push  notifications. This well enable users to get notified of offline messages when they arrive, as well as simulate a continued XMPP session on iPhone devices that still do not implement multitasking.&lt;/p&gt;
&lt;p&gt;For the latter feature, since the iPhone still does not accept to run applications in the background, if you want to use another application, you will have to shutdown your XMPP client and thus disconnect from Talkr.IM. With the Push feature enabled on your XMPP client (if this one supports Apple Push notifications), you can tell your contacts you are still online when you are using other applications. You will then automatically receive notifications of new messages. And when you re-open your XMPP client, you will receive these messages.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.process-one.net/en/solutions/oneteam_iphone/&quot;&gt;OneTeam for iPhone&lt;/a&gt; has the Apple Push feature enabled: you will be able to use it on you Talkr.IM account. Just use you Jabber ID, like username@talkr.im, and for a simple configuration, go to the &quot;Settings&quot; tab, then &quot;Push settings&quot;.&lt;/p&gt;
&lt;p&gt;The Talkr.IM XMPP server will stop at 10:00am CET. This means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;01:00am Los Angeles&lt;/li&gt;
&lt;li&gt;04:00am New York&lt;/li&gt;
&lt;li&gt;12:00 Moscow&lt;/li&gt;
&lt;li&gt;18:00 Tokyo&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: the Apple Push module is installed on Talkr.IM, and working fine. You can use it on &lt;a href=&quot;http://www.process-one.net/en/solutions/oneteam_iphone/&quot;&gt;OneTeam for iPhone&lt;/a&gt;. You can run a APNS module on your own ejabberd server with &lt;a href=&quot;http://www.process-one.net/en/imstore/#impush&quot;&gt;IMpush&lt;/a&gt;.&lt;/p&gt;</content>
		<author>
			<name>Nicolas Vérité</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:03:03</id>
			<updated>2010-03-04T09:46:36+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">ejabberd tip: simple health check</title>
		<link href="http://www.process-one.net/en/blogs/article/ejabberd_tip_simple_health_check/"/>
		<id>tag:process-one.net,2010:en/blogs/3.2462</id>
		<updated>2010-03-03T16:27:29+00:00</updated>
		<content type="html">&lt;p&gt;An ejabberd health check mechanism might be useful in your deployments, but using the HTTP file server might be overkill...&lt;/p&gt; &lt;p&gt;Some people want to do regular health checks on ejabberd, which is always a good idea. Doing a health check over XMPP might not be the solution, here is at least two reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;with a pure ad-hoc solution like a cron script, you might need an XMPP library you might not want to install on your servers&lt;/li&gt;
&lt;li&gt;monitoring systems might not talk XMPP at all...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So people first think of the internal ejabberd HTTP file server, which then they have to configure through a specific listener and the right module... possibly with logs, they would have to manage (rotate, parse, clean, etc.).&lt;/p&gt;
&lt;p&gt;Sometimes people just don't think there is already an HTTP listener on their internal BOSH Connection Manager. You would argue that BOSH uses the HTTP POST method. But the ejabberd BOSH Connection Manager replies to simple GET:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;wget &lt;a href=&quot;http://www.process-one.net/en?URL=http%3A%2F%2Fmyserver.net%2Fhttp-bind&quot;&gt;http://myserver.net/http-bind&lt;/a&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And ejabberd will answer:&lt;/p&gt;
&lt;h1&gt;ejabberd mod_http_bind v1.2&lt;/h1&gt;
&lt;p&gt;An implementation of &lt;a href=&quot;http://xmpp.org/extensions/xep-0206.html&quot;&gt;XMPP over BOSH  (XEP-0206)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This web page is only informative. To use HTTP-Bind  you need a Jabber/XMPP client that supports it.&lt;/p&gt;</content>
		<author>
			<name>Nicolas Vérité</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:03:03</id>
			<updated>2010-03-04T09:46:36+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry>
		<title type="html">BBC and CouchDB</title>
		<link href="http://damienkatz.net/2010/03/bbc_and_couchdb.html"/>
		<id>tag:damienkatz.net,2010://1.555</id>
		<updated>2010-03-01T22:11:06+00:00</updated>
		<content type="html" xml:lang="en">&lt;blockquote&gt;&lt;div&gt;Vaguely interesting KV/#couchdb stat from the BBC - 3.3 billion requests handled since last summer, running at about 150-170 million per day&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;http://twitter.com/endafarrell/status/9820160677&quot;&gt;http://twitter.com/endafarrell/status/9820160677&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-03-06T23:46:10+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Memory matters - even in Erlang</title>
		<link href="http://www.lshift.net/blog/2010/02/28/memory-matters-even-in-erlang"/>
		<id>http://www.lshift.net/blog/?p=481</id>
		<updated>2010-02-28T21:42:43+00:00</updated>
		<content type="html">&lt;p&gt;
Some time ago we got an interesting bug report for &lt;a href=&quot;http://www.rabbitmq.com/&quot; id=&quot;y62y&quot; title=&quot;RabbitMQ&quot;&gt;RabbitMQ&lt;/a&gt;. Surprisingly, unlike other complex bugs, this one is easy to describe:&amp;nbsp;&lt;br /&gt;
&lt;p&gt;&lt;i&gt;At some point basic.get suddenly starts being very slow - about 9 times slower!&lt;/i&gt;&lt;/p&gt;
&lt;span id=&quot;more-481&quot;&gt;&lt;/span&gt;

&lt;p&gt;&lt;i&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;Basic.get doesn&amp;#8217;t do anything complex - it just pops a message from a queue. This behaviour was quite unexpected. Our initial tests confirmed that we have a problem when a queue contains thousands of elements:&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;pre&gt;queue_length: 90001  basic_get 3333 times took: 1421.250ms
queue_length: 83335  basic_get 3333 times took: 1576.664ms
queue_length: 60004  basic_get 3333 times took: 1403.086ms
queue_length: 53338  basic_get 3333 times took: 9659.434ms [ look at that! ]
queue_length: 50005  basic_get 3333 times took: 9885.598ms
queue_length: 46672  basic_get 3333 times took: 8562.136ms&lt;/pre&gt;
&lt;p&gt;
Let me repeat that. Usually popping a message from a queue takes Xms. At some point, it slows down to 9*Xms.
&lt;/p&gt;

&lt;p&gt;It turned out that the problem is with the &lt;i&gt;&lt;a href=&quot;http://ftp.sunet.se/pub/lang/erlang/doc/man/queue.html#len-1&quot; id=&quot;d89l&quot; title=&quot;queue:length()&quot;&gt;queue:len()&lt;/a&gt;&lt;/i&gt; function, which is executed during the &lt;i&gt;basic.get&lt;/i&gt;. Actually, &lt;i&gt;queue:len()&lt;/i&gt; calls only &lt;i&gt;&lt;a href=&quot;http://www.erlang.org/doc/man/erlang.html#length-1&quot; id=&quot;somh&quot; title=&quot;erlang:length()&quot;&gt;erlang:length()&lt;/a&gt;&lt;/i&gt; builtin. At some point it switches to the &amp;#8220;slow&amp;#8221; mode.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Erlang:length()&lt;/i&gt; is a builtin that iterates through a linked list and counts it&amp;#8217;s length. It&amp;#8217;s complexity is&amp;nbsp;&lt;i&gt;O(N)&lt;/i&gt;, where N is the length of the list. This function is implemented in the VM so it&amp;#8217;s expected to be very, very fast.&lt;/p&gt;

&lt;p&gt;The problem is not with &lt;i&gt;erlang:length()&lt;/i&gt; being slow. It&amp;#8217;s about being unpredictably slow. Let&amp;#8217;s take a look at Erlang interpreter source code (&lt;a href=&quot;http://github.com/yrashk/erlang/blob/master/erts/emulator/beam/erl_bif_guard.c#L328&quot; id=&quot;ii56&quot; title=&quot;erl_bif_guard.c:erts_gc_length_1&quot;&gt;erl_bif_guard.c:erts_gc_length_1&lt;/a&gt;). Here&amp;#8217;s the main loop for &lt;i&gt;erlang:length()&lt;/i&gt;:&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre&gt;i=0
while (is_list(list)) {
    i++;
    list = CDR(list_val(list));
}&lt;/pre&gt;

&lt;p&gt;It does nothing unusual - it just iterates through &lt;a href=&quot;http://en.wikipedia.org/wiki/Cons&quot; id=&quot;ag6g&quot; title=&quot;Cons&quot;&gt;list elements&lt;/a&gt;. However, recompiling Erlang with some debugging information confirms that the problem is indeed here:&lt;/p&gt;
&lt;pre&gt;clock_gettime(CLOCK_REALTIME, &amp;amp;t0);
while (is_list(list)) {
    i++;
    list = CDR(list_val(list));
}
clock_gettime(CLOCK_REALTIME, &amp;amp;t1);
td_ms = TIMESPEC_NSEC_SUBTRACT(t1, t0) / 1000000.0;
if (i &amp;gt; 200000 || td_ms &amp;gt; 2.0) {
    fprintf(stderr, &quot;gc_length_1(%p)=%i %.3fms\n\r&quot;, reg[live], i, td_ms);
}&lt;/pre&gt;

&lt;pre&gt;gc_length_1(0x7f4dbfa7fc19)=499999 2.221ms
gc_length_1(0x7f4dbfa7fc19)=499999 2.197ms
gc_length_1(0x7f4dbfa7fc19)=499999 2.208ms
(hibernation)
gc_length_1(0x7f4db0572049)=499999 13.793ms
gc_length_1(0x7f4db0572049)=499999 12.806ms
gc_length_1(0x7f4db0572049)=499999 12.531ms&lt;/pre&gt;&lt;p&gt;
This confirms Matthias&amp;#8217; initial guess - the slowdown starts after Erlang process hibernation.
&lt;/p&gt;

&lt;p&gt;For those who aren&amp;#8217;t Erlang experts:&amp;nbsp;&lt;a href=&quot;http://www.erlang.org/doc/man/erlang.html#hibernate-3&quot; id=&quot;g:63&quot; title=&quot;Hibernation&quot;&gt;Hibernation&lt;/a&gt;&amp;nbsp;is an operation that compacts an Erlang process. It does aggressive garbage collection and reduces the memory footprint of a process to absolute minimum.&lt;/p&gt;

&lt;p&gt;The intended result of hibernation is recovering free memory from the process. However its side effect is a new memory layout of objects allocated on the heap.&lt;/p&gt;

&lt;p&gt;Ah, how could I have forgotten! The &lt;a href=&quot;http://norvig.com/21-days.html#Answers&quot; id=&quot;uk7i&quot; title=&quot;memory access is slow&quot;&gt;memory is nowadays slow&lt;/a&gt;! What happens, is that before hibernation list elements are aligned differently, more dense. Whereas after hibernation they are sparse. It&amp;#8217;s easy to test it - let&amp;#8217;s count the average distance between pointers to list elements:&lt;/p&gt;
&lt;pre&gt;gc_length_1(0x7f5c626fbc19)=499999 2.229ms avg=16.000 dev=0.023
gc_length_1(0x7f5c626fbc19)=499999 3.349ms avg=16.000 dev=0.023
gc_length_1(0x7f5c626fbc19)=499999 3.345ms avg=16.000 dev=0.023
(hibernation)
gc_length_1(0x7f5c61f7d049)=499999 13.800ms avg=136.000 dev=0.266
gc_length_1(0x7f5c61f7d049)=499999 12.726ms avg=136.000 dev=0.266
gc_length_1(0x7f5c61f7d049)=499999 12.367ms avg=136.000 dev=0.266
&lt;/pre&gt;
&lt;p&gt;
&lt;div&gt;Confirmed! Standard deviation is surprisingly small, so we can read the numbers as:&lt;/div&gt;
&lt;ul&gt;&lt;li&gt;Before hibernation list elements are aligned exactly one after another, values are somewhere else.&lt;/li&gt;
&lt;li&gt;After hibernation list elements are interleaved with values.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;This behavior does make sense. In most cases when you traverse the list, you actually do something with the values. After hibernation, when you access list item, the value will be already loaded to the CPU cache.&lt;/p&gt;

&lt;p&gt;Knowing the mechanism, it&amp;#8217;s easy to write a &lt;a href=&quot;http://ai.pjwstk.edu.pl/~majek/dump/erlang-prefetch-length-test.erl&quot; id=&quot;cb:0&quot; title=&quot;test case that reproduces this behavior&quot;&gt;test case that reproduces the problem&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The average distance between pointers in my case is constant - the standard deviation is negligible. This information has a practical implication - we can &amp;#8220;predict&amp;#8221; where the next pointer will be. Let&amp;#8217;s use that information to &amp;#8220;fix&amp;#8221; the Erlang VM by &lt;a href=&quot;http://gcc.gnu.org/projects/prefetch.html&quot; id=&quot;wv5_&quot; title=&quot;prefetching memory&quot;&gt;prefetching memory&lt;/a&gt;!&lt;/p&gt;

&lt;pre&gt;while (is_list(list)) {
    i++;
    list2 = CDR(list_val(list));
    __builtin_prefetch((char*)list2 + 128*((long)list2-(long)list));
    list = list2;
}
&lt;/pre&gt;
&lt;div&gt;Test script running on original Erlang VM:&lt;/div&gt;
&lt;pre&gt;length: 300001  avg:0.888792ms dev:0.061587ms
length: 300001  avg:0.881030ms dev:0.040961ms
length: 300001  avg:0.875158ms dev:0.019436ms
hibernate
length: 300001  avg:14.861762ms dev:0.150635ms
length: 300001  avg:14.833733ms dev:0.017405ms
length: 300001  avg:14.884861ms dev:0.220119ms
&lt;/pre&gt;
&lt;div&gt;&lt;a href=&quot;http://ai.pjwstk.edu.pl/~majek/dump/erlang-R13B04-prefetch-length.diff&quot; id=&quot;n_0l&quot; title=&quot;Patched&quot;&gt;Patched&lt;/a&gt; Erlang VM:&lt;/div&gt;
&lt;pre&gt;length: 300001  avg:0.742822ms dev:0.029322ms
length: 300001  avg:0.739149ms dev:0.012897ms
length: 300001  avg:0.739465ms dev:0.014417ms
hibernate
length: 300001  avg:7.543693ms dev:0.284355ms
length: 300001  avg:7.342802ms dev:0.330158ms
length: 300001  avg:7.265960ms dev:0.053176ms
&lt;/pre&gt;
&lt;p&gt;
The test runs only a tiny bit faster for the &amp;#8220;fast&amp;#8221; case (dense &lt;a href=&quot;http://en.wikipedia.org/wiki/Cons&quot; id=&quot;khsh&quot; title=&quot;conses&quot;&gt;conses&lt;/a&gt;) and twice as fast for the &amp;#8220;slow&amp;#8221; case (sparse conses).&lt;/p&gt;

&lt;p&gt;Should this patch be merged into mainline Erlang? Not really. I have set the prefetch multiplier value to 128 and I don&amp;#8217;t even know if it&amp;#8217;s optimal. This was only an experiment. But it was fun to see how low-level system architecture can affect high-level applications.&lt;/p&gt;
&lt;/p&gt;</content>
		<author>
			<name>LShift</name>
			<uri>http://www.lshift.net/blog</uri>
		</author>
		<source>
			<title type="html">LShift Ltd.</title>
			<subtitle type="html">What happens at LShift</subtitle>
			<link rel="self" href="http://www.lshift.net/blog/feed/"/>
			<id>http://www.lshift.net/blog/feed/</id>
			<updated>2010-03-05T16:30:50+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Filtering lines efficiently</title>
		<link href="http://easyerl.blogspot.com/2010/02/filtering-lines-efficiently.html"/>
		<id>tag:blogger.com,1999:blog-855944390206940143.post-8276989122488926253</id>
		<updated>2010-02-24T09:00:02+00:00</updated>
		<content type="html">Whenever you are dealing with log lines or that you're program is filtering data you always have to handle 'escaping' efficiently.&lt;br /&gt;&lt;br /&gt;While developing a log module using a gen_event, I needed to escape simple quotes.&lt;br /&gt;Sometime thoses quotes were already escaped...&lt;br /&gt;&lt;br /&gt;I've found this regexp to handle gracefully the case:&lt;br /&gt;&lt;pre&gt;re:replace( Bin, &quot;(?&amp;lt;!\\\\)'&quot;, &quot;\\\\'&quot;, [ global ] ).&lt;br /&gt;&lt;/pre&gt;&lt;a name=&quot;more&quot;&gt;&lt;/a&gt;&lt;br /&gt;Not so easy to read, and because of the various backslashes, this regexp needed some tests&lt;br /&gt;before being fully usable.&lt;br /&gt;Basically this regexp only filter simple quote when they're not already escaped...&lt;br /&gt;&lt;br /&gt;Now that I've my filter for quotes and I need a filter for newline characters.&lt;br /&gt;Everytime you find some newlines in your log files, you can be sure that many tools already in your network will not treat them efficiently, worse this may break everything after ...&lt;br /&gt;&lt;br /&gt;So I came across this regexp:&lt;br /&gt;&lt;pre&gt;re:replace( Bin, &quot;[\\n\\r]+&quot;, &quot; &quot;, [ global ] ).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Finally having two filter functions for every line, I wanted to be able to add or remove easily any function.&lt;br /&gt;You can reference functions with this notation:&lt;br /&gt;&lt;pre&gt;fun filterquotes/1&lt;br /&gt;&lt;/pre&gt;Or a list of functions:&lt;br /&gt;&lt;pre&gt;[ fun filterquotes/1, fun filternewlines/1 ]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With this notation and the famous 'lists:foldl', I can filter a line with many functions quite nicely:&lt;br /&gt;&lt;pre&gt;% Data is the accumulator, but we don't change it :)&lt;br /&gt;        lists:foldl( fun( Fun, Data ) -&gt;&lt;br /&gt;                         Fun(Data) &lt;br /&gt;        end, Bin, [ fun filterquotes/1, fun filternewline/1 ]).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's the code:&lt;br /&gt;&lt;pre&gt;filter( Bin ) when is_atom(Bin) -&gt;&lt;br /&gt;        Bin;&lt;br /&gt;filter( Bin ) when is_integer(Bin) -&gt;&lt;br /&gt;        Bin;&lt;br /&gt;filter( Bin ) -&gt;&lt;br /&gt;        lists:foldl( fun( Fun, Data ) -&gt;&lt;br /&gt;                         Fun(Data) &lt;br /&gt;        end, Bin, [ fun filterquotes/1, fun filternewline/1 ]).&lt;br /&gt;&lt;br /&gt;filterquotes(Bin) -&gt;&lt;br /&gt;        re:replace( Bin, &quot;(?&amp;lt;!\\\\)'&quot;, &quot;\\\\'&quot;, [ global ] ).&lt;br /&gt;&lt;br /&gt;filternewline( Bin ) -&gt;&lt;br /&gt;        re:replace( Bin, &quot;[\\n\\r]+&quot;, &quot; &quot;, [ global ] ).&lt;br /&gt;&lt;/pre&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/855944390206940143-8276989122488926253?l=easyerl.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>rolphin</name>
			<email>noreply@blogger.com</email>
			<uri>http://easyerl.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">EazyErl ! Learn erlang the easy way !</title>
			<subtitle type="html">From simple code snippet to full blown module, find what you need and sometimes more :)</subtitle>
			<link rel="self" href="http://easyerl.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-855944390206940143</id>
			<updated>2010-03-07T12:45:04+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Reading an openssl .priv.key file and extracting the key</title>
		<link href="http://easyerl.blogspot.com/2010/02/reading-openssl-privkey-file-and.html"/>
		<id>tag:blogger.com,1999:blog-855944390206940143.post-5533665012407705943</id>
		<updated>2010-02-23T22:23:26+00:00</updated>
		<content type="html">Extracting the private key from a .priv.key file is simple.&lt;br /&gt;The private key is encrypted using a AES-128 with your passphrase.&lt;br /&gt;&lt;br /&gt;The initial vector is also stored in the file, you can extract it directly from the first line:&lt;br /&gt;&lt;pre&gt;get_salt( &quot;Salted__&quot;, Salt:8/binary, Rest/binary&gt;&gt; ) -&gt;&lt;br /&gt;        {Salt, Rest}.&lt;br /&gt;&lt;/pre&gt;&lt;a name=&quot;more&quot;&gt;&lt;/a&gt;&lt;br /&gt;The last part is handled by some md5() of your passphrase and the initial vector:&lt;br /&gt;&lt;pre&gt;Key = crypto:md5([ Password, Salt ]),&lt;br /&gt;        IV = crypto:md5([ Key, Password, Salt ]),&lt;br /&gt;        crypto:aes_cbc_128_decrypt( Key, IV, Rest).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now the full module:&lt;br /&gt;&lt;pre&gt;-module(priv_key).&lt;br /&gt;&lt;br /&gt;-compile(export_all).&lt;br /&gt;&lt;br /&gt;priv_key_file( File, Password ) -&gt;&lt;br /&gt;        {ok, Bin} = file:read_file(File),&lt;br /&gt;        {Salt, Rest} = get_salt(Bin),&lt;br /&gt;        Key = crypto:md5([ Password, Salt ]),&lt;br /&gt;        IV = crypto:md5([ Key, Password, Salt ]),&lt;br /&gt;        crypto:aes_cbc_128_decrypt( Key, IV, Rest).&lt;br /&gt;        &lt;br /&gt;get_salt( &quot;Salted__&quot;, Salt:8/binary, Rest/binary&gt;&gt; ) -&gt;&lt;br /&gt;        {Salt, Rest}.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/855944390206940143-5533665012407705943?l=easyerl.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>rolphin</name>
			<email>noreply@blogger.com</email>
			<uri>http://easyerl.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">EazyErl ! Learn erlang the easy way !</title>
			<subtitle type="html">From simple code snippet to full blown module, find what you need and sometimes more :)</subtitle>
			<link rel="self" href="http://easyerl.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-855944390206940143</id>
			<updated>2010-03-07T12:45:04+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en-gb">
		<title type="html">London Tech Meetups</title>
		<link href="http://feedproxy.google.com/~r/BarkingIguana/~3/ripH84iithM/london-tech-meetups"/>
		<id>tag:barkingiguana.com,2010-02-23:49231934267467cd6f9473e1d60d3904/755476d833c7503d2d36a16bea26d045</id>
		<updated>2010-02-23T12:25:35+00:00</updated>
		<content type="html">&lt;p&gt;It can be quite hard to find groups in your area that share your interest, and even if you find out that they exist it can be pretty hard to work out when the next meetup is. Some of the meetup groups have frankly &lt;em&gt;mental&lt;/em&gt; scheduling rules.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://johnstewartsutherland.com/&quot;&gt;John Sutherland&lt;/a&gt; has solved this problem for &lt;a href=&quot;http://edinburgh2.com/&quot;&gt;Edinburgh tech community meetups&lt;/a&gt; by listing when various groups meet and who they'd be of interest to. After asking and receiving permission I've duplicated this idea for &lt;a href=&quot;http://london2.org/&quot;&gt;London tech community meetups&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If your meetup isn't listed and you'd like it to be, email me at &lt;a href=&quot;http://barkingiguana.com/mailto:craig@barkingiguana.com&quot;&gt;craig@barkingiguana.com&lt;/a&gt; and let me know.&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/BarkingIguana/~4/ripH84iithM&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>Craig Webster</name>
			<uri>http://barkingiguana.com/?source=feed</uri>
		</author>
		<source>
			<title type="html">Barking Iguana</title>
			<subtitle type="html">Tests are for life, not just when you feel like it</subtitle>
			<link rel="self" href="http://barkingiguana.com/rss/"/>
			<id>tag:barkingiguana.com,2005:49231934267467cd6f9473e1d60d3904</id>
			<updated>2010-03-10T22:30:04+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">22 February 2010: Call for Summer 2010 Internships!</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1139"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1139</id>
		<updated>2010-02-22T12:16:21+00:00</updated>
		<content type="html">Erlang Solutions regularly provides summer internships for qualified IT students. Many former interns have said that it was the best learning experience they have ever had. We are currently interviewing for this year's summer
internships.&lt;br /&gt;&lt;br /&gt;We are located in the heart of
London. See &lt;a href=&quot;http://www.erlang-consulting.com/section/60/office-locations&quot; target=&quot;_blank&quot;&gt;contact us&lt;/a&gt; section. Applicants from all over the world are encouraged to seek the positions
(we have 9 nationalities represented in our offices) but to apply, you
have to be eligible to work in the EU. &lt;br /&gt;&lt;br /&gt;The Internships run from June 1 until the end of August, and can continue through September, depending upon student availability and interest.&lt;br /&gt;&lt;br /&gt;For more information and to apply, please visit our Jobs section &lt;a href=&quot;http://www.erlang-consulting.com/jobs/detail/21/undergraduate-summer-interns&quot; target=&quot;_self&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-03-10T23:00:54+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">DSL : Grow your syntax on top of a clean semantic model</title>
		<link href="http://debasishg.blogspot.com/2010/02/dsl-grow-your-syntax-on-top-of-clean.html"/>
		<id>tag:blogger.com,1999:blog-22587889.post-8752276955215978661</id>
		<updated>2010-02-22T10:59:16+00:00</updated>
		<content type="html">A DSL primarily has two components - &lt;i&gt;a semantic model&lt;/i&gt; that abstracts the underlying domain and a &lt;i&gt;linguistic abstraction&lt;/i&gt; on top that speaks the dialect of the user. The semantic model is the model of the domain where you can apply all the principles of DDD that Eric Evans espouses. And the linguistic abstraction is a thin veneer on top of the underlying model. The more well abstracted your model is, easier will be the construction of the layer on top of it. Here's a general architecture of a DSL engineering stack :-&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://2.bp.blogspot.com/_r-NJO1NMiu4/S4IJvohPhGI/AAAAAAAAAKc/Xx_hy4ZBCXI/s1600-h/ext_dsl_10.gif&quot;&gt;&lt;img src=&quot;http://2.bp.blogspot.com/_r-NJO1NMiu4/S4IJvohPhGI/AAAAAAAAAKc/Xx_hy4ZBCXI/s400/ext_dsl_10.gif&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5440922013752329314&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's interesting to observe that the two components of the stack evolve somewhat orthogonally.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Semantic Model evolves Bottom Up&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The semantic model usually evolves in a bottom up fashion - larger abstractions are formed from smaller abstractions using principles of composition. It can be through composition of traits or objects or it can be through composition of functions as well. How beautiful your compositions can be depends a lot on the language you use. But it's important that the semantic model also speaks the language of the domain. &lt;br /&gt;&lt;br /&gt;Here's an example code snippet from my upcoming book &lt;a href=&quot;http://www.manning.com/ghosh&quot;&gt;DSLs In Action&lt;/a&gt; that models the business rules for a trading DSL. When you do a trade on a stock exchange you get charged a list of tax and fee components depending on the market where you execute the trade. The following snippet models a business rule using Scala that finds out the list of applicable tax/fee heads for a trade ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;TaxFeeRulesImpl&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;TaxFeeRules&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;override&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;forTrade&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;trade&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Trade&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;TaxFee&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;forHKG&amp;nbsp;orElse&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;forSGP&amp;nbsp;orElse&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;forAll&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;trade&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;market&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;forHKG&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;PartialFunction&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Market&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;TaxFee&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;HKG&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;in&amp;nbsp;real&amp;nbsp;life&amp;nbsp;these&amp;nbsp;can&amp;nbsp;come&amp;nbsp;from&amp;nbsp;a&amp;nbsp;database&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;TradeTax&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Commission&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Surcharge&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;forSGP&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;PartialFunction&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Market&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;TaxFee&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;SGP&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;TradeTax&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Commission&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Surcharge&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;VAT&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;forAll&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;PartialFunction&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Market&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;TaxFee&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;_&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;TradeTax&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Commission&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//..&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The method &lt;code&gt;forTrade&lt;/code&gt; clearly expresses the business rule, which reads almost as expressive as the English version ..&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&quot;Get the Hong Kong specific list for trades executed on the Hong Kong market OR Get the Singapore specific list for trades executed on the Singapore market OR Get the most generic list valid for all other markets&quot;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Note how Scala &lt;code&gt;PartialFunction&lt;/code&gt; s can be chained together to give the above model an expressive yet succinct syntax.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Language Interface evolves Top Down&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Here you start with the domain user. What dialect does he use on the trading desk ? And then you try to build an interpreter around that which uses the services that the semantic model publishes. I call this thin layer of abstraction a &lt;b&gt;DSL Facade&lt;/b&gt; that sits between your DSL script and the underlying domain model and acts as the glue.&lt;br /&gt;&lt;br /&gt;It also depends a lot on the host language as to how you would like to implement the facade. With a language like Lisp, macros can come in very handy in designing an interpreter layer for the facade. And with macros you do bottom up programming, bending the host language to speak your dialect.&lt;br /&gt;&lt;br /&gt;When you are developing an external DSL, the EBNF rules that you specify act as the DSL Facade for growing your syntax. Within the rules you can use foreign code embedding to interact with your semantic model. &lt;br /&gt;&lt;br /&gt;In summary, when you design a DSL, the semantic model is as important as the dialect that it speaks. Having a well designed semantic model is an exercise in designing well-engineered abstractions. And as I mention in my book, the four qualities of good abstractions are &lt;i&gt;minimalism&lt;/i&gt;, &lt;i&gt;distillation&lt;/i&gt;, &lt;i&gt;extensibility&lt;/i&gt; and &lt;i&gt;composability&lt;/i&gt;.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/22587889-8752276955215978661?l=debasishg.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Debasish</name>
			<email>ghosh.debasish@gmail.com</email>
			<uri>http://debasishg.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Ruminations of a Programmer</title>
			<subtitle type="html">A programmer's blog - will deal with everything that relates to a programmer. Occasionally, it will contain some humour, some politics and some sport news.</subtitle>
			<link rel="self" href="http://debasishg.blogspot.com/feeds/posts/default?alt=rss"/>
			<id>tag:blogger.com,1999:blog-22587889</id>
			<updated>2010-03-04T07:15:02+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Code availability on git-hub</title>
		<link href="http://charpi.net/blog/2010/02/21/code-availability-on-git-hub/"/>
		<id>http://charpi.net/blog/?p=219</id>
		<updated>2010-02-21T08:54:32+00:00</updated>
		<content type="html">Bored to switch code between my private subversion repository and git-hub for my open-source projects, I decided to use exclusively git-hub for them.
My trac wiki pages are also moved to git-hub for improve the documentation of those projects.

Selenium-RC Erlang binding 
Rake tasks to build erlang code
Small mock library for erlang (Please don&amp;#8217;t use mock to test [...]</content>
		<author>
			<name>Nicolas Charpentier</name>
			<uri>http://charpi.net/blog</uri>
		</author>
		<source>
			<title type="html">Nicolas Charpentier's blog</title>
			<subtitle type="html">Yet another Agile and OpenSource oriented blog.</subtitle>
			<link rel="self" href="http://charpi.net/blog/feed/"/>
			<id>http://charpi.net/blog/feed/</id>
			<updated>2010-02-21T09:00:39+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">About Me</title>
		<link href="http://damienkatz.net/2009/12/about_me.html"/>
		<id>tag:damienkatz.net,2009://1.554</id>
		<updated>2010-02-20T04:53:36+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;&lt;img src=&quot;http://damienkatz.net/MyPicture.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
All about me. Me me me me me.&lt;/p&gt;

&lt;p&gt;Vitals:&lt;br /&gt;
Birth date - October 24, 1973&lt;br /&gt;
Height - 6'1&quot;&lt;br /&gt;
Eyes - brown&lt;br /&gt;
Hair - dark brown&lt;br /&gt;
Complexion - fair and freckly&lt;br /&gt;
Brain - wrinkly&lt;br /&gt;
Spouse - Laura Ann Katz (maiden name Toenjes)&lt;br /&gt;
Kids - Gwendolyn, Roseanna and Zack&lt;br /&gt;
Religion - unapologetically atheist&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;damien4.jpg&quot; src=&quot;http://damienkatz.net/pics/damien4.jpg&quot; width=&quot;640&quot; height=&quot;480&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I live in Piedmont CA.&lt;/p&gt;

&lt;p&gt;I am the creator of &lt;a href=&quot;http://couchdb.org/&quot;&gt;CouchDB&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I am the CEO of &lt;a href=&quot;http://couch.io/&quot;&gt;Couchio&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;CouchDB&quot; src=&quot;http://damienkatz.net/pics/logo.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;My good points:&lt;br /&gt;
I am very devoted, loving and supportive of my wife and daughters. I have a very positive attitude and am energetic. I am smart and a fast learner, especially when it comes to math, science and engineering stuff. I love solving really hard problems. I am a hard worker, and I am very passionate about my work. I am very honest. I like to make lots of jokes, sometimes they are even funny. I take good care of myself and exercise regularly. I am athletic. I read constantly (always non-fiction). I have good eye for aesthetics. I am good with my hands and like to make things. I like to bake. I generally try not to take life too seriously.&lt;/p&gt;

&lt;p&gt;My bad points:&lt;br /&gt;
I am egotistical, judgmental and sometimes have a bad temper (but I'm working on those things). I am vain and self conscious. I don't take very good care of my teeth (but I do floss regularly: once every 4 months, whether I need it or not). I am messy and disorganized. I have a short attention span in meetings and lectures. I take my work too seriously. I am brutally honest (but I'm convinced it's not really a bad point). My self-created list of bad points is oddly short, hmmmm.&lt;/p&gt;

&lt;p&gt;My weird points:&lt;br /&gt;
While I am pretty athletic (strong, fast, can jump, etc), I'm physically uncoordinated and hence suck at nearly every sport (except basketball, I'm decent at that). I am somewhat shy around new people, sometimes it comes off as being as being a snob. I spend waaay too much time in front of the computer, but that's the way I like it. I drink lots of diet soda, lots. I can't whistle. Sometimes my feet smell like hot buttered popcorn. I once was the proprietor of liquidpoop.com -- the internet's largest repository of diarrhea-related poetry. Although I'm vain, my wardrobe mostly consists of stained, freebie t-shirts and a few pairs of jeans.&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-03-06T23:46:10+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Migrating Notes/Domino to CouchDB</title>
		<link href="http://damienkatz.net/2010/02/migrating_notesdomino_to_couch.html"/>
		<id>tag:damienkatz.net,2010://1.552</id>
		<updated>2010-02-19T23:17:26+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;I've been talking to some IT shops who are migrating away from Lotus Notes and Domino. More than wanting to use something else, it seems the reasons they are migrating away is that people in management just don't like Lotus Notes.&lt;/p&gt;

&lt;p&gt;The problem these IT shops face is they don't have many good options to migrate to. Sharepoint works for very generic collaborative activities, but not so much for custom business apps that are so pervasive in large Notes installs. That doesn't mean people don't try.&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;mt-enclosure mt-enclosure-image&quot;&gt;&lt;a href=&quot;http://2sharepoint.com/lotusnotes-to-sharepoint-migration-visimigrate.html&quot;&gt;&lt;img alt=&quot;visimigrate-enterprise-architecture-thumb.jpg&quot; src=&quot;http://damienkatz.net/pics/visimigrate-enterprise-architecture-thumb.jpg&quot; width=&quot;380&quot; height=&quot;255&quot; class=&quot;mt-image-none&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;So these IT shops are interested in migrating to Apache CouchDB for obvious reasons. CouchDB is largely inspired by the Lotus Notes backend. CouchDB has a document database, peer based replication, views, full text indexing add-ons, security, and HTTP client access. It also has a very active and growing open source community.&lt;/p&gt;

&lt;p&gt;So in theory, migrating to CouchDB from Notes/Domino should be easier than migrating to any other technology. But what we don't yet have is many tools, documentation and examples for migrating from Notes to CouchDB.&lt;/p&gt;

&lt;p&gt;Anyone out there have experience with this type of thing for Notes? Anyone interested in helping us develop the tools and documentation for migrating to CouchDB? There is a lot of business opportunity here, and we are looking for partners and VARs to help customers with tools and migrations. If interested, have some ideas or feedback, feel free to email me at damien@couch.io.&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-03-06T23:46:10+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Why I don't like ActiveRecord for Domain Model Persistence</title>
		<link href="http://debasishg.blogspot.com/2010/02/why-i-dont-like-activerecord-for-domain.html"/>
		<id>tag:blogger.com,1999:blog-22587889.post-325261958861851632</id>
		<updated>2010-02-15T11:09:51+00:00</updated>
		<content type="html">When it comes to a rich domain modeling, I am not a big fan of the ActiveRecord model. The biggest problem that it entails is invasiveness - the persistence model invades into my domain model. And this was also my first reaction to the Lift-CouchDB integration module which was released recently.&lt;br /&gt;&lt;br /&gt;The moment I say ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;CouchRecord&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//..&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;my domain model becomes tied to the persistence concerns.&lt;br /&gt;&lt;br /&gt;When I started &lt;a href=&quot;http://github.com/debasishg/scouchdb&quot;&gt;scouchdb&lt;/a&gt;, my very first thought was to make it non-invasive. The Scala objects must be pure and must remain pure and completely oblivious of the underlying persistence model. In the age of polyglot persistence there is every possibility that you may need to persist a domain model across multiple storage engines. I may be using a JPA backed relational store as the enterprise online database, which gets synchronized with some offline processing that comes from a CouchDB backend. I need the domain model persistence in both my Oracle and my CouchDB engines. The ActiveRecord pattern is difficult to scale to such requirements.&lt;br /&gt;&lt;br /&gt;Here's what I implemented in scouchdb ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;Scala&amp;nbsp;abstraction&amp;nbsp;:&amp;nbsp;pure&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_keyword&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;ItemPrice&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;store&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;item&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;price&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Number&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;specification&amp;nbsp;of&amp;nbsp;the&amp;nbsp;db&amp;nbsp;server&amp;nbsp;running&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;couch&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Couch&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;&amp;quot;127.0.0.1&amp;quot;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;item_db&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Db&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;&amp;quot;item_db&amp;quot;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;create&amp;nbsp;the&amp;nbsp;database&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;couch&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;item_db&amp;nbsp;create&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;create&amp;nbsp;the&amp;nbsp;Scala&amp;nbsp;object&amp;nbsp;:&amp;nbsp;a&amp;nbsp;pure&amp;nbsp;domain&amp;nbsp;object&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;s&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;ItemPrice&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;&amp;quot;Best&amp;nbsp;Buy&amp;quot;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;&amp;quot;mac&amp;nbsp;book&amp;nbsp;pro&amp;quot;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;create&amp;nbsp;a&amp;nbsp;document&amp;nbsp;for&amp;nbsp;the&amp;nbsp;database&amp;nbsp;with&amp;nbsp;an&amp;nbsp;id&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;doc&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Doc&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;item_db&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;&amp;quot;best_buy&amp;quot;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;add&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;couch&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;doc&amp;nbsp;add&amp;nbsp;s&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;query&amp;nbsp;by&amp;nbsp;id&amp;nbsp;to&amp;nbsp;get&amp;nbsp;the&amp;nbsp;id&amp;nbsp;and&amp;nbsp;revision&amp;nbsp;of&amp;nbsp;the&amp;nbsp;document&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;id_rev&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;couch&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;item_db&amp;nbsp;by_id&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;&amp;quot;best_buy&amp;quot;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;query&amp;nbsp;by&amp;nbsp;id&amp;nbsp;to&amp;nbsp;get&amp;nbsp;back&amp;nbsp;the&amp;nbsp;object&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;returns&amp;nbsp;a&amp;nbsp;tuple3&amp;nbsp;of&amp;nbsp;(id,&amp;nbsp;rev,&amp;nbsp;object)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;sh&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;couch&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;item_db&amp;nbsp;by_id&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;&amp;quot;best_buy&amp;quot;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;classOf&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;ItemPrice&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;]))&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;got&amp;nbsp;back&amp;nbsp;the&amp;nbsp;original&amp;nbsp;object&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;sh&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;_3&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;item&amp;nbsp;should&amp;nbsp;equal&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;sh&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;_3&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;price&amp;nbsp;should&amp;nbsp;equal&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;It's a full cycle session of interaction with the CouchDB persistence engine without any intrusion into the domain abstraction. I am free to use ItemPrice domain abstraction for a relational storage as well.&lt;br /&gt;&lt;br /&gt;CouchDB offers a model of persistence where the objects that we store should be close to the granularity of domain abstractions. I should be able to store the entire Aggregate Root of my model components directly as JSON. ActiveRecord model offers a lower level of abstraction and makes you think more in terms of persistence of the individual entities. The thought process is so relational that you ultimately end up with a relational model both in terms of persistence and domain. With CouchDB you need to think in terms of documents and views and NOT in terms of relations and tables. I &lt;a href=&quot;http://debasishg.blogspot.com/2009/04/framework-inertia-couchdb-and-case-of.html&quot;&gt;blogged&lt;/a&gt; on this same subject some time back.&lt;br /&gt;&lt;br /&gt;The philosophy that I adopted in scouchdb was to decouple the domain entities from the persistence layer. You hand over a pure Scala object to the driver, it will extract a JSON model from it and write it to CouchDB. I use &lt;a href=&quot;http://github.com/debasishg/sjson&quot;&gt;sjson&lt;/a&gt; for this serialization. sjson works totally based on reflection and can transparently serialize and deserialize Scala objects that you hand over to it. From this point of view, the three aspects of managing domain abstractions, JSON serialization and persistence into CouchDB are totally orthogonal. I think this is difficult to get with an ActiveRecord based model.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/22587889-325261958861851632?l=debasishg.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Debasish</name>
			<email>ghosh.debasish@gmail.com</email>
			<uri>http://debasishg.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Ruminations of a Programmer</title>
			<subtitle type="html">A programmer's blog - will deal with everything that relates to a programmer. Occasionally, it will contain some humour, some politics and some sport news.</subtitle>
			<link rel="self" href="http://debasishg.blogspot.com/feeds/posts/default?alt=rss"/>
			<id>tag:blogger.com,1999:blog-22587889</id>
			<updated>2010-03-04T07:15:02+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Wanted: Hosting/Infrastructure Engineer</title>
		<link href="http://damienkatz.net/2010/02/wanted_hostinginfrastructure_e.html"/>
		<id>tag:damienkatz.net,2010://1.551</id>
		<updated>2010-02-12T00:18:26+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;We are looking to hire someone with strong hosting or infrastructure experience to help us develop a CouchDB hosting platform.&lt;/p&gt;

&lt;p&gt;Experience with CouchDB is nice but not necessary. We most want someone who is passionate about infrastructure with large scale hosting experience and with open source contributions.&lt;/p&gt;

&lt;p&gt;We offer competitive pay, stock options, great health benefits and 6 weeks vacation, and an opportunity to change the world.&lt;/p&gt;

&lt;p&gt;Email inquiries to damien@couch.io&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-03-06T23:46:10+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">First week in the new office</title>
		<link href="http://damienkatz.net/2010/02/first_week_in_the_new_office.html"/>
		<id>tag:damienkatz.net,2010://1.548</id>
		<updated>2010-02-09T00:40:32+00:00</updated>
		<content type="html" xml:lang="en">&lt;p&gt;Last week was our first week in our new office in Old Downtown Oakland. It's a really neat area with lots of restaurants and bars, and hardly any murders.&lt;/p&gt;

&lt;p&gt;Oh yeah, we've changed our name to Couchio. Our new blog will be here &lt;a href=&quot;http://couch.io&quot;&gt;http://blog.couch.io/&lt;/a&gt; soon.&lt;/p&gt;

&lt;p&gt;Our office:&lt;br /&gt;
&lt;span class=&quot;mt-enclosure mt-enclosure-image&quot;&gt;&lt;a href=&quot;http://damienkatz.net/pics/office%20-%204.jpg&quot;&gt;&lt;img alt=&quot;office - 4.jpg&quot; src=&quot;http://damienkatz.net/pics/office - 4-thumb-400x267.jpg&quot; width=&quot;400&quot; height=&quot;267&quot; class=&quot;mt-image-none&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Our office manager Claire:&lt;br /&gt;
&lt;span class=&quot;mt-enclosure mt-enclosure-image&quot;&gt;&lt;a href=&quot;http://damienkatz.net/pics/office%20-%206.jpg&quot;&gt;&lt;img alt=&quot;office - 6.jpg&quot; src=&quot;http://damienkatz.net/pics/office - 6-thumb-400x472.jpg&quot; width=&quot;400&quot; height=&quot;472&quot; class=&quot;mt-image-none&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Chris and Mikeal:&lt;br /&gt;
&lt;span class=&quot;mt-enclosure mt-enclosure-image&quot;&gt;&lt;a href=&quot;http://damienkatz.net/pics/office%20-%201.jpg&quot;&gt;&lt;img alt=&quot;office - 1.jpg&quot; src=&quot;http://damienkatz.net/pics/office - 1-thumb-400x267.jpg&quot; width=&quot;400&quot; height=&quot;267&quot; class=&quot;mt-image-none&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Claire and Jan:&lt;br /&gt;
&lt;span class=&quot;mt-enclosure mt-enclosure-image&quot;&gt;&lt;a href=&quot;http://damienkatz.net/pics/office%20-%202.jpg&quot;&gt;&lt;img alt=&quot;office - 2.jpg&quot; src=&quot;http://damienkatz.net/pics/office - 2-thumb-400x267.jpg&quot; width=&quot;400&quot; height=&quot;267&quot; class=&quot;mt-image-none&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Nitin:&lt;br /&gt;
&lt;span class=&quot;mt-enclosure mt-enclosure-image&quot;&gt;&lt;a href=&quot;http://damienkatz.net/pics/office%20-%208.jpg&quot;&gt;&lt;img alt=&quot;office - 8.jpg&quot; src=&quot;http://damienkatz.net/pics/office - 8-thumb-400x598.jpg&quot; width=&quot;400&quot; height=&quot;598&quot; class=&quot;mt-image-none&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Super Awesome Art by &lt;a href=&quot;http://www.juliearmbruster.net/&quot;&gt;Julie Armbruster&lt;/a&gt;:&lt;br /&gt;
&lt;span class=&quot;mt-enclosure mt-enclosure-image&quot;&gt;&lt;a href=&quot;http://damienkatz.net/pics/office%20-%203.jpg&quot;&gt;&lt;img alt=&quot;office - 3.jpg&quot; src=&quot;http://damienkatz.net/pics/office - 3-thumb-400x309.jpg&quot; width=&quot;400&quot; height=&quot;309&quot; class=&quot;mt-image-none&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Me:&lt;br /&gt;
&lt;span class=&quot;mt-enclosure mt-enclosure-image&quot;&gt;&lt;a href=&quot;http://damienkatz.net/pics/office%20-%207.jpg&quot;&gt;&lt;img alt=&quot;office - 7.jpg&quot; src=&quot;http://damienkatz.net/pics/office - 7-thumb-400x374.jpg&quot; width=&quot;400&quot; height=&quot;374&quot; class=&quot;mt-image-none&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;My Office:&lt;br /&gt;
&lt;span class=&quot;mt-enclosure mt-enclosure-image&quot;&gt;&lt;a href=&quot;http://damienkatz.net/pics/office%20-%205.jpg&quot;&gt;&lt;img alt=&quot;office - 5.jpg&quot; src=&quot;http://damienkatz.net/pics/office - 5-thumb-400x267.jpg&quot; width=&quot;400&quot; height=&quot;267&quot; class=&quot;mt-image-none&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;So far we are really disorganized and discombobulated. But I'm are working on it! I even bought Management for Dummies. Things will be running smoothly in no time ;)&lt;/p&gt;

&lt;p&gt;Also we are looking hard for someone to help us offer CouchDB support and hopefully build a whole support organization. Email me damien@couch.io if you are interested or know someone who is.&lt;/p&gt;</content>
		<author>
			<name>Damien Katz</name>
			<uri>http://damienkatz.net/</uri>
		</author>
		<source>
			<title type="html">Damien Katz</title>
			<subtitle type="html">Everybody keeps on talking about it
Nobody's getting it done</subtitle>
			<link rel="self" href="http://damienkatz.net/atom.xml"/>
			<id>tag:damienkatz.net,2008-05-05://1</id>
			<updated>2010-03-06T23:46:10+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Scala Self-Type Annotations for Constrained Orthogonality</title>
		<link href="http://debasishg.blogspot.com/2010/02/scala-self-type-annotations-for.html"/>
		<id>tag:blogger.com,1999:blog-22587889.post-7270309535014994642</id>
		<updated>2010-02-08T11:58:15+00:00</updated>
		<content type="html">I talked about &lt;a href=&quot;http://debasishg.blogspot.com/2010/01/case-for-orthogonality-in-design.html&quot;&gt;orthogonality&lt;/a&gt; in design in one of my earlier posts. We had a class &lt;code&gt;Address&lt;/code&gt; in Scala and we saw how we can combine it with other orthogonal concerns without polluting the core abstraction. We could do this because Scala offers a host of capabilities to compose smaller abstractions and build larger wholes out of them. A language is orthogonal when it allows such capabilities of composition without overlaps in functionalities between the composing featuresets.&lt;br /&gt;&lt;br /&gt;The design of Scala offers many orthogonal features - I showed some of them in my earlier post. The power of mixins for adding orthogonal features ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;a&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(..)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;LabelMaker&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;override&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;toLabel&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//..&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;and the power of Scala views with implicits ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;implicit&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;AddressToLabelMaker&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;LabelMaker&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;toLabel&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//..&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Here &lt;code&gt;Address&lt;/code&gt; and &lt;code&gt;LabelMaker&lt;/code&gt; are completely unrelated and offers truly orthogonal capabilities when mixed in. However there can be some cases where the mixins themselves &lt;i&gt;are not completely orthogonal&lt;/i&gt; to the core abstractions, but really optional extensions to them. In fact the mixins implement some functionalities that may depend on the core abstraction as well. Let's see yet another feature of the Scala type system that makes this modeling wholesome.&lt;br /&gt;&lt;br /&gt;Consider the following abstraction for a security trade that takes place in a stock exchange ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;details&amp;nbsp;ellided&amp;nbsp;for&amp;nbsp;clarity&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_keyword&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Trade&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;refNo&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;account&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;instrument&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;quantity&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unitPrice&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;principal&amp;nbsp;value&amp;nbsp;of&amp;nbsp;the&amp;nbsp;trade&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;principal&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;quantity&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;unitPrice&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;For every trade executed on the exchange we need to have a set of tax and fees associated with it. The exact set of tax and fees depend on a number of factors like type of trade, instruments traded, the exchange where it takes place etc. Let's have a couple of tax/fee traits that model this behavior ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;trait&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Tax&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;calculateTax&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//..&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_keyword&quot;&gt;trait&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Commission&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;calculateCommission&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//..&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;In the above definitions both methods &lt;code&gt;calculateTax&lt;/code&gt; and &lt;code&gt;calculateCommission&lt;/code&gt; depends on the trade being executed. One option is to keep them abstract in the above trait and provide their implementations after mixing in with &lt;code&gt;Trade&lt;/code&gt; ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;t&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Trade&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(..)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Tax&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Commission&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;implementations&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;calculateTax&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;principal&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;calculateCommission&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;principal&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;0.15&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;I did it at the instance level. You can very well use this idiom at the class level and define ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;RichTrade&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Trade&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Tax&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Commission&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//..&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;However the above composition does not clearly bring out the fact that the domain rules mandate that the abstractions &lt;code&gt;Tax&lt;/code&gt; and &lt;code&gt;Commission&lt;/code&gt; should be constrained to be used with the &lt;code&gt;Trade&lt;/code&gt; abstraction only.&lt;br /&gt;&lt;br /&gt;Scala offers one way of making this knowledge explicit at the type level .. using self-type annotations ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;trait&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Tax&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Trade&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;refers&amp;nbsp;to&amp;nbsp;principal&amp;nbsp;of&amp;nbsp;trade&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;calculateTax&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;principal&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_keyword&quot;&gt;trait&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Commission&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Trade&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//&amp;nbsp;refers&amp;nbsp;to&amp;nbsp;principal&amp;nbsp;of&amp;nbsp;trade&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;calculateCommission&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;principal&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;0.15&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The traits are still decoupled. But using Scala's self type annotations you make it explicit that &lt;code&gt;Tax&lt;/code&gt; and &lt;code&gt;Commission&lt;/code&gt; are meant to be used *only* by mixing them with Trade.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;t&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Trade&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(..)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Tax&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Commission&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;calculateTax&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;calculateCommission&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Can I call this &lt;i&gt;constraining the orthogonality&lt;/i&gt; of abstractions ? &lt;code&gt;Tax&lt;/code&gt; and &lt;code&gt;Commission&lt;/code&gt; provide orthogonal attributes to &lt;code&gt;Trade&lt;/code&gt; &lt;i&gt;optionally&lt;/i&gt; and publish their constraints explicitly in their definitions. It's not much of a difference from the earlier implementations. But I prefer to use this style to make abstractions closer to what the domain speaks.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/22587889-7270309535014994642?l=debasishg.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Debasish</name>
			<email>ghosh.debasish@gmail.com</email>
			<uri>http://debasishg.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Ruminations of a Programmer</title>
			<subtitle type="html">A programmer's blog - will deal with everything that relates to a programmer. Occasionally, it will contain some humour, some politics and some sport news.</subtitle>
			<link rel="self" href="http://debasishg.blogspot.com/feeds/posts/default?alt=rss"/>
			<id>tag:blogger.com,1999:blog-22587889</id>
			<updated>2010-03-04T07:15:02+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">02 February 2010: Erlang Solutions at QCon London 2010</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1136"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1136</id>
		<updated>2010-02-02T15:16:25+00:00</updated>
		<content type="html">Erlang Solutions Ltd. sponsors&amp;#160; &lt;a href=&quot;http://qconlondon.com/&quot; target=&quot;_blank&quot;&gt;QCon London 2010&lt;/a&gt;, hosts the track, gives the talks and organises Erlang User Group meeting there.&lt;br /&gt;&lt;br /&gt;Qcon&amp;#160; is an annual London enterprise software development conference designed for team leads, architects and project management. It gathers Java, .NET, Ruby, SOA, Agile, Erlang and architecture communities. &lt;br /&gt;&lt;br /&gt;Erlang Solutions will be present at QCon on &lt;span&gt;Friday, 12th March 2010&lt;/span&gt;, when Ulf Wiger (CTO of Erlang Solutions) will be hosting the &lt;a href=&quot;http://qconlondon.com/london-2010/tracks/show_track.jsp?trackOID=333&quot; target=&quot;_blank&quot;&gt;Concurrency Challenge&lt;/a&gt; track. He will also give an introductory talk &lt;a href=&quot;http://qconlondon.com/london-2010/presentation/Introduction%3A+The+Concurrency+Challenge&quot; target=&quot;_blank&quot;&gt;The Concurrency Challenge&lt;/a&gt; at &lt;span&gt;10:20&lt;/span&gt; and a presentation on &lt;a href=&quot;http://qconlondon.com/london-2010/presentation/Death+by+accidental+complexity&quot; target=&quot;_blank&quot;&gt;Death by accidental complexity&lt;/a&gt; at&lt;span&gt; 4:30&lt;/span&gt; pm. &lt;br /&gt;&lt;br /&gt;Also, Francesco Cesarini (founder of Erlang Solutions) will be giving two tutorials: &quot;&lt;a href=&quot;http://qconlondon.com/london-2010/presentation/Practical+Erlang+Programming&quot; target=&quot;_blank&quot;&gt;Practical Erlang Programming&lt;/a&gt;&quot; on Monday, &lt;span&gt;8th March&lt;/span&gt; and &quot;&lt;a href=&quot;http://qconlondon.com/london-2010/presentation/Erlang%2FOTP+System+Principles&quot; target=&quot;_blank&quot;&gt;Erlang/OTP System Principles&lt;/a&gt;&quot; on Tuesday, &lt;span&gt;9th March&lt;/span&gt;. These are an all- day events,&amp;#160; will start at 9:00 and finish at 16:00.&amp;#160; &lt;br /&gt;&lt;br /&gt;A day before, on &lt;span&gt;11th March 2010 from 18:30 until 20:30&lt;/span&gt; Erlang Solutions organises special free &lt;a href=&quot;https://secure.trifork.com/london-2010/freeevent/register.m?eventOID=2344&quot; target=&quot;_blank&quot;&gt;London Erlang User Group Meeting&lt;/a&gt; at QCon. Everyone is welcome, even if you do not participate in QCon London 2010, just register &lt;a href=&quot;https://secure.trifork.com/london-2010/freeevent/register.m?eventOID=2344&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.There will be four talks:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;Francesco Cesarini&lt;/span&gt; presents &quot;Erlang community around the world&quot; &lt;/li&gt;
&lt;li&gt;&lt;span&gt;Ulf Wiger&lt;/span&gt; talks about &quot;Erlang in the Clouds&quot; &lt;/li&gt;
&lt;li&gt;&lt;span&gt;Justin Sheehy&lt;/span&gt; will present &quot;Introduction to RIAK&quot; &amp;#38; &lt;/li&gt;
&lt;li&gt;&lt;span&gt;Joe Armstrong&lt;/span&gt; talks about &quot;Erlang Libraries&quot;&lt;/li&gt;&lt;/ul&gt;QCON 2010 will be held in &lt;a href=&quot;http://www.qeiicc.co.uk/&quot; target=&quot;_blank&quot;&gt;The Queen Elizabeth II Conference Centre&lt;/a&gt;, in London from &lt;span&gt;8th until 12th March 2010.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&amp;#160;&lt;span&gt;See you there! &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;http://www.qconlondon.com/&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://www.erlang-consulting.com/../../upload/images/42/logo_qcon.gif&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;Tutorials: March 8-9, 2010&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;Conference:&amp;#160; March 10-12, 2010&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div&gt;&lt;span&gt;When registering for the QCon, use the Discount Code &quot;erlangug&quot; and save&amp;#160; &amp;#163;50 off the price!&lt;br /&gt;
 

&lt;/span&gt;&lt;/div&gt;








  


      &lt;br /&gt;</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-03-10T23:00:54+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">RabbitMQ-shovel: Message Relocation Equipment</title>
		<link href="http://www.lshift.net/blog/2010/02/01/rabbitmq-shovel-message-relocation-equipment"/>
		<id>http://www.lshift.net/blog/?p=478</id>
		<updated>2010-02-01T12:13:52+00:00</updated>
		<content type="html">&lt;p&gt;In several applications, it&amp;#8217;s very useful to be able to take messages out of one RabbitMQ broker, and insert them into another. Many people on our mailing list have being asking for such a shovel, and we&amp;#8217;ve recently been able to devote some time to writing one. This takes the form of a plugin for Rabbit, and whilst it hasn&amp;#8217;t been through QA just yet, we&amp;#8217;re announcing it so people who would like to play and even suggest further features for inclusion can do so sooner rather than later.&lt;/p&gt;

&lt;p&gt;The shovel is written on top of the Erlang client. It supports both direct and network connections to nodes, SSL support, the ability to declare resources on nodes it connects to, basic round-&lt;del datetime=&quot;2010-02-01T11:10:34+00:00&quot;&gt;robin&lt;/del&gt;rabbit balancing of both source and destination nodes, and allows you to configure many parameters controlling how messages are consumed from the source, and how they&amp;#8217;re published to the destination. Multiple shovels can be specified, their statuses queried, and shovels can repeatedly reconnect to nodes in the event of failure.&lt;/p&gt;

&lt;p&gt;The plugin is available from &lt;a href=&quot;http://hg.rabbitmq.com/rabbitmq-shovel/&quot;&gt;http://hg.rabbitmq.com/rabbitmq-shovel/&lt;/a&gt;, and is released under the MPL v1.1. There is a README included which contains full documentation. This is replicated below.&lt;span id=&quot;more-478&quot;&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;RabbitMQ-shovel&lt;/h1&gt;

&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;p&gt;This is a plug-in for RabbitMQ that shovels messages from a queue on
one broker to an exchange on another broker. The two brokers may be
the same. The plug-in allows several shovels to be specified at the
same time. Each shovel may have a number of source and destination
brokers specified, and one of each is chosen whenever the shovel
attempts to make a connection: this permits simple round-rabbit load
balancing.&lt;/p&gt;

&lt;p&gt;Resources can be declared upon connection to both the source and
destination brokers, and parameters can be specified for both the
reception and publishing of messages.&lt;/p&gt;

&lt;h2&gt;Requirements&lt;/h2&gt;

&lt;p&gt;Currently, you must build the server from source, under branch
bug16653. You must also have checked out the rabbitmq-public-umbrella
hg repository, and have the rabbitmq-erlang-client built. From
scratch, the following commands should build RabbitMQ with the shovel
plug-in:&lt;/p&gt;

&lt;pre&gt;
hg clone http://hg.rabbitmq.com/rabbitmq-public-umbrella
cd rabbitmq-public-umbrella
hg clone http://hg.rabbitmq.com/rabbitmq-codegen
hg clone http://hg.rabbitmq.com/rabbitmq-erlang-client
hg clone http://hg.rabbitmq.com/rabbitmq-server
hg clone http://hg.rabbitmq.com/rabbitmq-shovel
cd rabbitmq-server
hg up -C bug16653
make -j
mkdir -p plugins
cd plugins
ln -s ../../rabbitmq-erlang-client
ln -s ../../rabbitmq-shovel
cd ../../rabbitmq-erlang-client
make
cd ../rabbitmq-shovel
make
cd ../rabbitmq-server
./scripts/rabbitmq-activate-plugins
make cleandb run
&lt;/pre&gt;

&lt;h2&gt;Configuration&lt;/h2&gt;

&lt;p&gt;The RabbitMQ configuration file specifies the shovel
configurations. This exists by default, in
&lt;code&gt;/etc/rabbitmq/rabbitmq.config&lt;/code&gt; under Linux systems,
&lt;code&gt;%RABBITMQ_BASE%\rabbitmq.config&lt;/code&gt; under Windows or somewhere else under
OS X. This file configures both RabbitMQ-server and all the plugins
installed in it. It is an Erlang-syntax file of the form:&lt;/p&gt;

&lt;pre&gt;
[{section1, [section1-config]},
 {section2, [section2-config]},
 &amp;#8230;
 {sectionN, [sectionN-config]}
].
&lt;/pre&gt;

&lt;p&gt;thus a list of tuples, where the left element of each tuple names the
applications being configured. Don&amp;#8217;t forget the last element of the
list doesn&amp;#8217;t have a trailing comma, and don&amp;#8217;t forget the full-stop is
needed after closing the list. Hence if you configure RabbitMQ-server
and the RabbitMQ-shovel, then the configuration file may have a
structure like this:&lt;/p&gt;

&lt;pre&gt;
[{rabbit,        [configuration-for-RabbitMQ-server]},
 {rabbit-shovel, [configuration-for-RabbitMQ-shovel]}
].
&lt;/pre&gt;

&lt;p&gt;A full example of the shovel configuration is:&lt;/p&gt;

&lt;pre&gt;
{rabbit_shovel,
  [{shovels,
    [{my_first_shovel,
      [{sources,      [{brokers,
                          [&quot;amqp://fred:secret@host1.domain/my_vhost&quot;,
                           &quot;amqp://john:secret@host2.domain/my_vhost&quot;
                          ]},
                       {declarations,
                          ['queue.declare',
                           {'queue.bind',
                                  [{exchange, &quot;my_exchange&quot;&gt;&gt;},
                                   {queue,    &lt;pre&gt;&gt;}]}
                          ]}]},
       {destinations, [{broker, &quot;amqp://&quot;},
                       {declarations,
                          [{'exchange.declare',
                                  [{exchange, &quot;my_exchange&quot;&gt;&gt;},
                                   {type, &quot;direct&quot;&gt;&gt;},
                                   durable]}
                          ]}]},
       {queue, &lt;pre&gt;&gt;},
       {qos, 10},
       {auto_ack, false},
       {tx_size, 0},
       {delivery_mode, keep},
       {publish_fields, [{exchange, &quot;my_exchange&quot;&gt;&gt;},
                         {routing_key, &quot;from_shovel&quot;&gt;&gt;}]},
       {reconnect, 5}
      ]}
     ]
   }]
}
&lt;/pre&gt;

&lt;p&gt;Firstly, all shovels are named. Here we have one shovel, called
&amp;#8216;my_first_shovel&amp;#8217;. We can have multiple shovels if you wish. Every
shovel must have all sub-fields specified: sources, destinations, qos,
auto_ack, delivery_mode, publish_fields, reconnect.&lt;/p&gt;

&lt;h2&gt;Sources and Destinations&lt;/h2&gt;

&lt;p&gt;Sources and destinations specify respectively where messages are
fetched from and delivered too. One of &amp;#8216;broker&amp;#8217; and &amp;#8216;brokers&amp;#8217; must be
specified, and &amp;#8216;broker&amp;#8217; is simply shorthand for when only one broker
needs specifying. Using &amp;#8216;brokers&amp;#8217; allows a list of brokers to be
specified: whenever the connection to a broker is lost, another one is
chosen at random from the list and a connection attempt is made to
that. The syntax for broker URIs is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;amqp://username:password@host:port/vhost&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If username or password are omitted, the default values of guest and
guest are used. If the vhost is omitted, the default value of / is
used. If the host is omitted, then the plugin uses the &amp;#8220;direct&amp;#8221;
connection internally rather than a network connection: this means it
connects to the RabbitMQ-server node on which it is running without
going through the network stack. This is much more efficient. If port
is omitted then the default value is used (5672 or 5671 if SSL is
used).&lt;/p&gt;

&lt;p&gt;SSL is implemented, for which additional parameters are needed:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;amqps://username:password@host:port/vhost?cacertfile=/path/to/cacert.pem&amp;amp;certfile=/path/to/certfile.pem&amp;amp;keyfile=/path/to/keyfile.pem&amp;amp;verify=verifyOption&amp;amp;fail_if_no_peer_cert=failOption&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;(note, this is a single line)&lt;/p&gt;

&lt;p&gt;All five parameters (3 paths: cacertfile, certfile and keyfile; 2
options: verify, fail_if_no_peer_cert) must be specified. See the SSL
guide at http://www.rabbitmq.com/ssl.html#configure-erlang for details
of SSL in RabbitMQ in general and specifically for the Erlang client
(on which the shovel is built).&lt;/p&gt;

&lt;p&gt;Note that SSL cannot be used with the direct connection (i.e. a host
must be specified when using SSL), and that it is preferable to use
the non-SSL direct connection when connecting to the same node that&amp;#8217;s
running the shovel.&lt;/p&gt;

&lt;h2&gt;Resource Declarations&lt;/h2&gt;

&lt;p&gt;Both sources and destinations can have an optional &amp;#8216;declarations&amp;#8217;
clause. The value of this is a list, consisting of AMQP Methods. If
default values are sufficient, then the method name alone can be
specified - e.g. &amp;#8216;queue.declare&amp;#8217;. If parameters need to be set then
the method should be given as a tuple, with the right hand side a
proplist specifying which fields need altering from their default
values. E.g:&lt;/p&gt;

&lt;pre&gt;
    {'exchange.declare',[{exchange, &quot;my_exchange&quot;&gt;&gt;},
                         {type, &quot;direct&quot;&gt;&gt;},
                         durable]},
&lt;/pre&gt;

&lt;p&gt;One very useful feature here is the Most-Recently-Declared-Queue
feature, in which RabbitMQ remembers the name of the most recently
declared queue. This means that you can declare a private queue, and
then bind it to exchanges without ever needing to know its name.&lt;/p&gt;

&lt;h2&gt;queue :: binary&lt;/h2&gt;

&lt;p&gt;This parameter specifies the name of the queue on the source brokers
to consume from. This queue must exist. Use the resource declarations
to create the queue (or ensure it exists) first. Note again that the
Most-Recently-Declared-Queue feature can be used here, thus an
anonymous queue can be used: use &amp;lt;&amp;lt;&gt;&gt; to indicate the
Most-Recently-Declared-Queue.&lt;/p&gt;

&lt;h2&gt;qos :: non-negative-integer&lt;/h2&gt;

&lt;p&gt;The shovel consumes from a queue. The QoS controls how many messages
are sent to the shovel in advance of the message the shovel is
currently processing.&lt;/p&gt;

&lt;h2&gt;auto_ack :: boolean&lt;/h2&gt;

&lt;p&gt;Setting this to &amp;#8216;true&amp;#8217; turns on the no_ack flag when subscribing to
the source queue.&lt;/p&gt;

&lt;h2&gt;tx_size :: non-negative-integer&lt;/h2&gt;

&lt;p&gt;When set to 0, transactions are not used. Other values make publishes
transactional, with a commit every N messages. In lieu of the auto-ack
option, when transactions are not used, messages are acknowledged to
the source immediately after every publish. When transactions are
used, acks are only issued to the source on receipt of the commit-ok
message from the destination. This can thus be used to guarantee that
messages are only acknowledged (and thus forgotten about by the source
broker) when they are guaranteed to have been received by the
destination broker.&lt;/p&gt;

&lt;h2&gt;delivery_mode :: &amp;#8216;keep&amp;#8217; | 0 | 2&lt;/h2&gt;

&lt;p&gt;This affects the delivery_mode field when publishing to the
destination. A value of &amp;#8216;keep&amp;#8217; means that the same delivery_mode
should be used as when the message was originally published to the
source broker. 0 and 2 override the original setting.&lt;/p&gt;

&lt;h2&gt;publish_fields&lt;/h2&gt;

&lt;p&gt;This is a list of tuples which override fields in the publish method
when publishing to the destination. This can be used to direct
messages to a particular exchange on the destination, for example, or
change the routing key. By default, the routing key of the message as
it is received by the shovel is passed through, but this can be
overridden as necessary.&lt;/p&gt;

&lt;h2&gt;reconnect :: non-negative-integer&lt;/h2&gt;

&lt;p&gt;When an error occurs, the shovel will disconnect from both the source
and destination broker immediately. This will force uncommitted
transactions at the destination to be rolled back, and delivered but
unacknowledged messages from the source to be requeued. The shovel
will then try connecting again. If this is unsuccessful, then it&amp;#8217;s not
a good idea for the shovel to very quickly and repeatedly try to
reconnect. The value specified here is the number of seconds to wait
between each connection attempt.&lt;/p&gt;

&lt;p&gt;Note that if set to 0, the shovel will never try to reconnect: it&amp;#8217;ll
stop after the first error.&lt;/p&gt;

&lt;h2&gt;Obtaining shovel statuses&lt;/h2&gt;

&lt;p&gt;From the broker Erlang prompt, call
&lt;code&gt;rabbit_shovel_status:status().&lt;/code&gt; This will return a list, with one row
for each configured shovel. Each row has three fields: the shovel
name, the shovel status, and the timestamp (a local calendar time of
&lt;code&gt;{{YYYY,MM,DD},{HH,MM,SS}}&lt;/code&gt;). There are 3 possible statuses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&amp;#8217;starting&amp;#8217;: The shovel is starting up, connecting and creating
resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;#8216;running&amp;#8217;: The shovel is up and running, shovelling messages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;{&amp;#8217;terminated&amp;#8217;, Reason}: Something&amp;#8217;s gone wrong. The Reason should give
a further indication of where the fault lies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/pre&gt;&lt;/pre&gt;</content>
		<author>
			<name>LShift</name>
			<uri>http://www.lshift.net/blog</uri>
		</author>
		<source>
			<title type="html">LShift Ltd.</title>
			<subtitle type="html">What happens at LShift</subtitle>
			<link rel="self" href="http://www.lshift.net/blog/feed/"/>
			<id>http://www.lshift.net/blog/feed/</id>
			<updated>2010-03-05T16:30:50+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Erlang Factory SF Bay Area 2010</title>
		<link href="http://steve.vinoski.net/blog/2010/01/30/erlang-factory-sf-bay-area-2010/"/>
		<id>http://steve.vinoski.net/blog/?p=534</id>
		<updated>2010-01-30T21:29:40+00:00</updated>
		<content type="html">&lt;p&gt;Interested in Erlang? You might consider attending &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010&quot;&gt;Erlang Factory SF Bay Area 2010&lt;/a&gt;. Below is a &lt;a href=&quot;http://www.erlang.org/cgi-bin/ezmlm-cgi?4:mss:49168:201001:fcgfnebjjkebpbdcnmpd&quot;&gt;message&lt;/a&gt; that &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010/speakers/francescocesarini&quot;&gt;Francesco Cesarini&lt;/a&gt;, conference organizer and co-author of the most excellent book &lt;em&gt;&lt;a href=&quot;http://oreilly.com/catalog/9780596518189&quot;&gt;Erlang Programming&lt;/a&gt;&lt;/em&gt;, sent to the &lt;a href=&quot;http://groups.google.com/group/erlang-programming&quot;&gt;erlang-questions list&lt;/a&gt; yesterday providing more information about the conference, especially pointing out that the Very Early Bird registration deadline is &lt;em&gt;&lt;strong&gt;tomorrow (Sunday January 31)&lt;/strong&gt;&lt;/em&gt;. Hope to see you there!&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Hi All,&lt;/p&gt;
&lt;p&gt;a note to say that we are almost done with the programme for the 2010 SF Bay Area Erlang Factory. This year, we are lucky to have keynote speakers such as &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010/speakers/joearmstrong&quot;&gt;Joe Armstrong&lt;/a&gt;, &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010/speakers/BjarneDacker&quot;&gt;Bjarne Dacker&lt;/a&gt;, &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010/speakers/kennethlundin&quot;&gt;Kenneth Lundin&lt;/a&gt; and &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010/speakers/SteveVinoski&quot;&gt;Steve Vinoski&lt;/a&gt;. They will be giving four of the 35 scheduled talks on the 25th and 26th of March in the San Francisco Bay Area. The almost complete programme is available here:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://erlang-factory.com/conference/SFBay2010/programme&quot;&gt;http://erlang-factory.com/conference/SFBay2010/programme&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The conference will be preceded by three days of University courses taught by experts such as &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010/speakers/SimonThompson&quot;&gt;Simon Thompson&lt;/a&gt;, &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010/speakers/JohnHughes&quot;&gt;John Hughes&lt;/a&gt;, &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010/speakers/thomasarts&quot;&gt;Thomas Arts&lt;/a&gt;, &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010/speakers/janhenrynystrom&quot;&gt;Henry Nystrom&lt;/a&gt; and &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010/speakers/KevinSmith&quot;&gt;Kevin Smith&lt;/a&gt;. Come and learn Erlang, OTP, QuickCheck or Web Development with Erlang. More information on the courses are here:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://erlang-factory.com/conference/SFBay2010/university&quot;&gt;http://erlang-factory.com/conference/SFBay2010/university&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This *Sunday* (January 31st) is the deadline for the very early bird deadline. Register by Sunday night and save $400 on the on-site registration price.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The conference hotel and venue is the &lt;a href=&quot;http://www1.hilton.com/en_US/hi/hotel/SFOAPHF-Hilton-San-Francisco-Airport-California/index.do&quot;&gt;SF Airport Hilton&lt;/a&gt;, a short BART / Caltrain ride from SF and the Valley. We have secured a very competitive price of US$109 per room and night at the conference hotel, this being one of the reasons for us choosing it. The other is the lower price of the venue, allowing us to pass on the savings to the delegates through a higher very early bird discount. We are planning an ErlLounge open to everyone who can&amp;#8217;t make the two days on the 25th, and hope we will be able to surpass last year&amp;#8217;s success. If you have thoughts or questions, you are welcome to drop me a line.&lt;/p&gt;
&lt;p&gt;Hope to see you all there!&lt;/p&gt;
&lt;p&gt;Francesco&lt;br /&gt;
&amp;#8211;&lt;br /&gt;
&lt;a href=&quot;http://www.erlang-solutions.com/&quot;&gt;http://www.erlang-solutions.com&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;</content>
		<author>
			<name>steve</name>
			<uri>http://steve.vinoski.net/blog</uri>
		</author>
		<source>
			<title type="html">Steve Vinoski's Blog</title>
			<subtitle type="html">Ask forgiveness, not permission.</subtitle>
			<link rel="self" href="http://steve.vinoski.net/blog/feed/atom/"/>
			<id>http://steve.vinoski.net/blog/feed/atom/</id>
			<updated>2010-03-10T23:00:21+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Erlang Factory SF Bay 2010 &amp;#8211; Francesco Cesarini on the Conference and Old-School vs New-School Erlangers</title>
		<link href="http://erlanginside.com/erlang-factory-2010-san-francisco-francesco-cesarini-138"/>
		<id>http://erlanginside.com/?p=138</id>
		<updated>2010-01-30T20:03:58+00:00</updated>
		<content type="html">The Erlang Factory&amp;#8217;s 2010 conference is March 25th and 26th in San Francisco, with the university three days before, starting the 22nd.  The conference is at the Hilton San Francisco Airport, with three tracks, each on a different theme. The number of tracks gives attendees an unusually broad set of choices for talks. When attending [...]</content>
		<author>
			<name>Chad DePue</name>
			<uri>http://erlanginside.com</uri>
		</author>
		<source>
			<title type="html">Erlang Inside</title>
			<subtitle type="html">News and Information on Erlang and Concurrent Computing</subtitle>
			<link rel="self" href="http://erlanginside.com/feed/atom"/>
			<id>http://erlanginside.com/feed/atom</id>
			<updated>2010-03-09T21:00:48+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Plugin exchange types for RabbitMQ</title>
		<link href="http://www.lshift.net/blog/2010/01/22/plugin-exchange-types-for-rabbitmq"/>
		<id>http://www.lshift.net/blog/?p=473</id>
		<updated>2010-01-22T14:38:54+00:00</updated>
		<content type="html">&lt;p&gt;An obvious extension point for an AMQP broker is the addition of new types of exchange.  An exchange type essentially represents an algorithm for dispatching messages to queues, usually based on the message&amp;#8217;s routing key, given how the queues are bound to the exchange &amp;#8212; it&amp;#8217;s a message routing algorithm.&lt;/p&gt;

&lt;p&gt;At a minimum, supporting new exchange types requires only some scaffolding to plug in to (an exchange type registry) and a hook for routing messages.  However, this wouldn&amp;#8217;t support some more interesting use cases, and in particular it didn&amp;#8217;t support our &lt;a href=&quot;http://oceanobservatories.org/spaces/download/attachments/19432960/ooi-amqp-api-20091228.pdf?version=1&quot;&gt;motivating use case&lt;/a&gt;.  Exchange types that want to keep their own state need to be initialised, and be notified about other lifecycle events.
&lt;span id=&quot;more-473&quot;&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The &lt;del datetime=&quot;2010-03-04T16:21:12+00:00&quot;&gt;branch bug22169&lt;/del&gt; default branch of RabbitMQ supports plugin exchange types, by providing a behaviour for exchange type modules to implement, and an exchange type registry to map a module to a type (i.e., what the client supplies in the type field of exchange.declare).&lt;/p&gt;

&lt;p&gt;The behaviour requires exported hooks for validating exchange declarations, creating exchanges, recovering durable exchanges, publishing to an exchange (this is where the routing comes in), maintaining bindings, and deleting an exchange.  RabbitMQ continues to maintain the database of exchanges and bindings, and calls the hooks after it&amp;#8217;s done its own bookkeeping.&lt;/p&gt;

&lt;p&gt;For simplicity, the hooks are not called atomically with the bookkeeping; so, it is possible for instance to publish to a new exchange for which the hook has not completed.  However, provided there are no asynchronous operations in the hook implementation, the hook will have completed by the time the OK message is sent to the client.  This is no more racey than AMQP itself, with consistency at the channel level where operations follow a single thread of control.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s an example that simply &lt;code&gt;io:format&lt;/code&gt;s things as they happen:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;-module(rabbit_exchange_type_debug).
-include(&quot;rabbit.hrl&quot;).

-behaviour(rabbit_exchange_type).

-export([description/0, publish/2]).
-export([validate/1, create/1, recover/2, delete/2, add_binding/2, remove_bindings/2]).
-export([register_debug_types/0]).
-include(&amp;#8221;rabbit_exchange_type_spec.hrl&amp;#8221;).

-rabbit_boot_step({debug_exchange_types, 
                   [{description, &quot;debugging exchange types&quot;},
                    {mfa, {?MODULE, register_debug_types, []}},
                    {requires, rabbit_exchange_type_registry},
                    {enables, exchange_recovery}]}).

description() -&amp;gt;
    [{name, &amp;lt;&amp;lt;&quot;debug&quot;&amp;gt;&amp;gt;},
     {description, &amp;lt;&amp;lt;&quot;Debugging exchange&quot;&amp;gt;&amp;gt;}].

backing_module(#exchange{ type = Type }) -&amp;gt;
    %% Presume that Type is EITHER one of the standard types &amp;#8211;
    %% i.e,. that we have been registered this module as direct,
    %% topic, fanout or match &amp;#8212; or, for testing purposes, it&amp;#8217;s
    %% registered (as in the boot steps above) as debug_direct, etc.
    Type1 = case atom_to_list(Type) of
                &amp;#8220;x-debug-&amp;#8221; ++ T -&amp;gt; T; 
                              T -&amp;gt; T
            end,
    list_to_existing_atom(&amp;#8221;rabbit_exchange_type_&amp;#8221; ++ Type1).

publish(Exchange, Delivery) -&amp;gt;
    io:format(&amp;#8221;Publish ~p to ~p~n&amp;#8221;, [Delivery, Exchange]),
    Module = backing_module(Exchange),
    Module:publish(Exchange, Delivery).

validate(X) -&amp;gt;
    io:format(&amp;#8221;Validate ~p~n&amp;#8221;, [X]),
    (backing_module(X)):validate(X).

create(X) -&amp;gt;
    io:format(&amp;#8221;Create ~p~n&amp;#8221;, [X]),
    (backing_module(X)):create(X).

recover(X, Bs) -&amp;gt;
    io:format(&amp;#8221;Recover ~p with bindings ~p~n&amp;#8221;, [X, Bs]),
    (backing_module(X)):recover(X, Bs).

delete(X, Bs) -&amp;gt;
    io:format(&amp;#8221;Delete ~p with bindings ~p~n&amp;#8221;, [X, Bs]),
    (backing_module(X)):delete(X, Bs).

add_binding(X, B) -&amp;gt;
    io:format(&amp;#8221;Add binding ~p to ~p~n&amp;#8221;, [B, X]),
    (backing_module(X)):add_binding(X, B).

remove_bindings(X, Bs) -&amp;gt;
    io:format(&amp;#8221;Delete bindings ~p from ~p~n&amp;#8221;, [Bs, X]),
    (backing_module(X)):remove_bindings(X, B).

register_debug_types() -&amp;gt;
    lists:foreach(
      fun (T) -&amp;gt;
              rabbit_exchange_type_registry:register(T, ?MODULE)
      end,
      [&amp;lt;&amp;lt;&quot;x-debug-direct&quot;&amp;gt;&amp;gt;,
       &amp;lt;&amp;lt;&quot;x-debug-topic&quot;&amp;gt;&amp;gt;,
       &amp;lt;&amp;lt;&quot;x-debug-fanout&quot;&amp;gt;&amp;gt;,
       &amp;lt;&amp;lt;&quot;x-debug-headers&quot;&amp;gt;&amp;gt;]).
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Bit by important bit:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;-behaviour(rabbit_exchange_type).
-export([description/0, publish/2]).
-export([validate/1, create/1, recover/2, delete/2, add_binding/2, remove_bindings/2]).
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;rabbit_exchange_type&lt;/code&gt; specifies these exported callbacks.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;-include(&quot;rabbit_exchange_type_spec.hrl&quot;).
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This include has the specs for each of the exported functions, if you&amp;#8217;re using specs.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;-rabbit_boot_step({debug_exchange_types, 
                   [{description, &quot;debugging exchange types&quot;},
                    {mfa, {?MODULE, register_debug_types, []}},
                    {requires, rabbit_exchange_type_registry},
                    {enables, exchange_recovery}]}).
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This uses the new boot sequence mechanism to register the exchange type during boot.  The &amp;#8220;enables&amp;#8221; and &amp;#8220;requires&amp;#8221; say that the function given as mfa above must be run after the exchange type registry is available, but before any exchanges are recovered.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;publish(Exchange, Delivery) -&amp;gt;
    io:format(&quot;Publish ~p to ~p~n&quot;, [Delivery, Exchange]),
    Module = backing_module(Exchange),
    Module:publish(Exchange, Delivery).
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This exchange type simply delegates to a &amp;#8220;backing&amp;#8221; exchange type.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;register_debug_types() -&amp;gt;
    lists:foreach(
      fun (T) -&amp;gt;
              rabbit_exchange_type:register(T, ?MODULE)
      end,
      [&amp;lt;&amp;lt;&quot;x-debug-direct&quot;&amp;gt;&amp;gt;,
       &amp;lt;&amp;lt;&quot;x-debug-topic&quot;&amp;gt;&amp;gt;,
       &amp;lt;&amp;lt;&quot;x-debug-fanout&quot;&amp;gt;&amp;gt;,
       &amp;lt;&amp;lt;&quot;x-debug-headers&quot;&amp;gt;&amp;gt;]).
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;rabbit_exchange_type_registry&lt;/code&gt; maintains a registry of type to module; because of this indirection, we can register this module as many different types, then check the declared type of the exchange in our hook to see which type we&amp;#8217;re expected to be.  Note that the AMQP specification requires the &amp;#8220;x-&amp;#8221; prefix for non-standard exchange types.&lt;/p&gt;

&lt;p&gt;&lt;del datetime=&quot;2010-03-04T16:21:12+00:00&quot;&gt;This should reach default branch soon after RabbitMQ 1.7.1 is
released.&lt;/del&gt; This is in RabbitMQ&amp;#8217;s default branch, and should be in the next release (1.7.2).&lt;/p&gt;

&lt;p&gt;You can drop modules straight into &lt;code&gt;src&lt;/code&gt;, but they are better packaged
as plugins &amp;#8212; follow the drill at &lt;a href=&quot;http://www.rabbitmq.com/plugin-development.html](http://www.rabbitmq.com/plugin-development.html&quot;&gt;the plugin development
guide&lt;/a&gt;
(and note that your plugin may only need to be a library application).&lt;/p&gt;

&lt;p&gt;[EDITS: Updated sample code to keep up with name changes, and correct use of list_to_atom to list_to_existing_atom]
[Further EDITS: slight API change, now in default branch]&lt;/p&gt;</content>
		<author>
			<name>LShift</name>
			<uri>http://www.lshift.net/blog</uri>
		</author>
		<source>
			<title type="html">LShift Ltd.</title>
			<subtitle type="html">What happens at LShift</subtitle>
			<link rel="self" href="http://www.lshift.net/blog/feed/"/>
			<id>http://www.lshift.net/blog/feed/</id>
			<updated>2010-03-05T16:30:50+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">A new way to think of Data Storage for your Enterprise Application</title>
		<link href="http://debasishg.blogspot.com/2010/01/new-way-to-think-of-data-storage-for.html"/>
		<id>tag:blogger.com,1999:blog-22587889.post-2338077798145272024</id>
		<updated>2010-01-21T19:24:15+00:00</updated>
		<content type="html">A couple of posts earlier I had blogged about a &lt;a href=&quot;http://debasishg.blogspot.com/2009/12/case-for-hybrid-sql-nosql-stack.html&quot;&gt;real life case study&lt;/a&gt; of one of our projects where we are using a SQL store (Oracle) and a NoSQL store (MongoDB) in combination over a message based backbone. MongoDB was used to cater to a very specific subset of the application functionality, where we felt it made a better fit than a traditional RDBMS. This hybrid architecture of data organization is turning out to be an increasingly attractive option today with more and more specialized persistent storage structures being developed.&lt;br /&gt;&lt;br /&gt;In many applications we need to process graph data structures. &lt;a href=&quot;http://neo4j.org/&quot;&gt;Neo4J&lt;/a&gt; can be a viable option for this. You can have your mainstream data storage still in an RDBMS and use Neo4J only for the subset of functionalities for which you need to use graph data structures. If you need to sync back to your main storage, use messaging as the transport to talk back to your relational database.&lt;br /&gt;&lt;br /&gt;Multiple data storage use along with asynchronous messaging is one of the options that will looks very potent today. Drizzle has its entire replication based on a &lt;a href=&quot;http://developian.blogspot.com/2009/11/drizzle-replication-using-rabbitmq-as.html&quot;&gt;RabbitMQ based transport&lt;/a&gt;. And using AMQP messaging, Drizzle replicates data to a host of key/value stores like Voldemort, memcachedDB and Cassandra.&lt;br /&gt;&lt;br /&gt;If we agree that messaging is going to be one of the most dominant paradigms in shaping application architectures, why not try to go one level up and look at some higher level abstractions for message based programming? Erlang programmers have been using the actor model for many years now and have demonstrated all the good qualities that the model imbibes. Inspired by Erlang, Scala also offers a similar model on the JVM. In an earlier post I had discussed how we can use the actor model in Scala to &lt;a href=&quot;http://debasishg.blogspot.com/2008/07/scaling-out-messaging-applications-with.html&quot;&gt;scale out messaging applications&lt;/a&gt; using a RabbitMQ storage.&lt;br /&gt;&lt;br /&gt;Now with the developing ecosystem of polyglot storage, we can use the same model of actor based communication as the backbone for integrating multiple data storage options that you may plug in to your application. Have specific clients front end the storage that they need to work with and use messaging to sync that up with the main data storage backend to have a consistent system of record. Have a look at the following diagram that may not look that unreal today. You have a host of options that bring your data closer to the way you process them in your domain model, be it document oriented, graph based, key/value based or simple POJO based across a data grid like Terracotta.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://1.bp.blogspot.com/_r-NJO1NMiu4/S1hcZ9yv6xI/AAAAAAAAAGw/ESOwkNoyxAk/s1600-h/data_hybrid.png&quot;&gt;&lt;img src=&quot;http://1.bp.blogspot.com/_r-NJO1NMiu4/S1hcZ9yv6xI/AAAAAAAAAGw/ESOwkNoyxAk/s400/data_hybrid.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429190951949036306&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When we have a bunch of architectural components loosely connected through messaging infrastructure, you can have a world of options managing interactions between them. In fact your options open up more when you get to interact with data shaped the way you would like to be. You now can think in terms of having a data model aligned with the model of your domain. You know once your rule base gets updated in Neo4J, it will somehow be synced up with the backend storage through some other service that will make it eventually consistent.&lt;br /&gt;&lt;br /&gt;In a future post I will explore some of the options that a higher order middleware service like &lt;a href=&quot;http://akkasource.org&quot;&gt;Akka&lt;/a&gt; can add to your stack. With Akka providing abstractions like transactors, pluggable persistence and out of the box integration modules for AMQP, there's a number of ways you can think of modularizing your application's domain model and storage. You can use peer to peer distributed actor based communication model that sets up synchronization options with your databases or you can use AMQP based transport to do the same much like what Drizzle does for replication. But that's some food for thought for yet another future post.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/22587889-2338077798145272024?l=debasishg.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Debasish</name>
			<email>ghosh.debasish@gmail.com</email>
			<uri>http://debasishg.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Ruminations of a Programmer</title>
			<subtitle type="html">A programmer's blog - will deal with everything that relates to a programmer. Occasionally, it will contain some humour, some politics and some sport news.</subtitle>
			<link rel="self" href="http://debasishg.blogspot.com/feeds/posts/default?alt=rss"/>
			<id>tag:blogger.com,1999:blog-22587889</id>
			<updated>2010-03-04T07:15:02+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">[ANN] ejabberd 2.1.2 bugfix release</title>
		<link href="http://www.process-one.net/en/blogs/article/ann_ejabberd_2.1.2_bugfix_release/"/>
		<id>tag:process-one.net,2010:en/blogs/3.2247</id>
		<updated>2010-01-18T16:08:17+00:00</updated>
		<content type="html">&lt;p&gt;We are pleased to announce ejabberd 2.1.2, which contains several bugfixes over last month's maintenance release.&lt;br /&gt;&lt;br /&gt;Brief summary of changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix SASL PLAIN authentication message for RFC4616 compliance&lt;/li&gt;
&lt;li&gt;Fix support for old Erlang/OTP R10 and R11&lt;/li&gt;
&lt;li&gt;If server start fails due to config file problem, display some lines and stop node&lt;/li&gt;
&lt;li&gt;PubSub and PEP: several improvements and bugfixes&lt;/li&gt;
&lt;li&gt;WebAdmin: fix offline message displaying&lt;/li&gt;
&lt;li&gt;When server stops with new stop_kindly command: inform users, clients, MUC&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Check the Release Notes for a more complete list of changes:&lt;br /&gt; &lt;a href=&quot;http://www.process-one.net/en?URL=http%3A%2F%2Fwww.process-one.net%2Fen%2Fejabberd%2Frelease_notes%2Frelease_note_ejabberd_2.1.2&quot;&gt;http://www.process-one.net/en/ejabberd/release_notes/release_note_ejabberd_2.1.2&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; If you upgrade from ejabberd 2.0.5 or older, read carefully the release notes of ejabberd 2.1.0 too, because there were several changes in the installation path and the configuration options.&lt;br /&gt; &lt;br /&gt; The list of solved tickets since previous version is available on ProcessOne bug tracker:&lt;br /&gt; &lt;a href=&quot;http://www.process-one.net/en?URL=http%3A%2F%2Fredir.process-one.net%2Fejabberd-2.1.2&quot;&gt;http://redir.process-one.net/ejabberd-2.1.2&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; ejabberd 2.1.2 is available as source code package and binary installers for Linux 32 bits, 64 bits, Mac OS X Intel, and Windows:&lt;br /&gt; &lt;a href=&quot;http://www.process-one.net/en?URL=http%3A%2F%2Fwww.process-one.net%2Fen%2Fejabberd%2Fdownloads&quot;&gt;http://www.process-one.net/en/ejabberd/downloads&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>Jérôme Sautret</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:03:03</id>
			<updated>2010-03-04T09:46:36+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry>
		<title type="html">My First Arduino Hack</title>
		<link href="http://feedproxy.google.com/~r/curious-attempt-bunny/~3/rODUjM6gfqg/my-first-arduino-hack.html"/>
		<id>tag:blogger.com,1999:blog-3376508392331888241.post-1868760742325581210</id>
		<updated>2010-01-16T16:58:53+00:00</updated>
		<content type="html">Yay! I got an Arduino as a present! So what do you do with it? I'm at DorkBotPDX and I'd just got as far as turning on an LED with a push button, and &lt;a href=&quot;http://c2.com/~ward/&quot;&gt;Ward&lt;/a&gt; suggested I try getting it to echo back to my a rhythm of clicks. I got that working, and then starting looking around in my starter kit. I had a speaker! Here's my circuit diagram and the code to go with it:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://4.bp.blogspot.com/_AGVcmhlbFXA/S0K4e1wgTWI/AAAAAAAAAVg/qIaWnS6YMsU/s1600-h/buzzer+circuit.png&quot;&gt;&lt;img src=&quot;http://4.bp.blogspot.com/_AGVcmhlbFXA/S0K4e1wgTWI/AAAAAAAAAVg/qIaWnS6YMsU/s400/buzzer+circuit.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5423099741273607522&quot; /&gt;&lt;/a&gt;(The mystery component on the left is the buzzer - Fritzing didn't have a close match for that part)&lt;br /&gt;&lt;br /&gt;The code:&lt;code&gt;&lt;pre&gt;#define BUZZER 3&lt;br /&gt;#define BUTTON 7&lt;br /&gt;&lt;br /&gt;int val = 0;&lt;br /&gt;int old_val = 0;&lt;br /&gt;&lt;br /&gt;long times[50];&lt;br /&gt;long i = 0;&lt;br /&gt;&lt;br /&gt;void setup() {&lt;br /&gt;  pinMode(BUZZER, OUTPUT);&lt;br /&gt;  pinMode(BUTTON, INPUT); &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void loop() {&lt;br /&gt;  val = digitalRead(BUTTON);&lt;br /&gt;  if ((val == HIGH) &amp;amp;&amp;amp; (old_val == LOW)) {&lt;br /&gt;    times[i] = millis();&lt;br /&gt;    i++;&lt;br /&gt;    analogWrite(BUZZER, 64);&lt;br /&gt;    delay(10);&lt;br /&gt;  }  &lt;br /&gt;  if ((old_val == HIGH) &amp;amp;&amp;amp; (val == LOW)) {&lt;br /&gt;    times[i] = millis();&lt;br /&gt;    i++;&lt;br /&gt;    analogWrite(BUZZER, 0);&lt;br /&gt;    delay(10);&lt;br /&gt;  }  &lt;br /&gt;  &lt;br /&gt;  old_val = val;&lt;br /&gt;&lt;br /&gt;  if (i &gt; 0 &amp;amp;&amp;amp; millis() - times[i-1] &gt; 2000) {&lt;br /&gt;    delay(1000);&lt;br /&gt;    int state = 0;&lt;br /&gt;    for(int y=0; y&amp;lt;i; y++) {&lt;br /&gt;      state = 1 - state;&lt;br /&gt;      analogWrite(BUZZER, 64*state);&lt;br /&gt;      delay(times[y+1]-times[y]);&lt;br /&gt;    }&lt;br /&gt;    i = 0; // reset&lt;br /&gt;    analogWrite(BUZZER, 0);     &lt;br /&gt;  } &lt;br /&gt;}&lt;/pre&gt;&lt;/code&gt;Word to the wise: as with coding it pays to take small incremental steps!&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3376508392331888241-1868760742325581210?l=curious-attempt-bunny.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/curious-attempt-bunny/~4/rODUjM6gfqg&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>Curious Attempt Bunny</name>
			<email>noreply@blogger.com</email>
			<uri>http://curious-attempt-bunny.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">curious-attempt-bunny</title>
			<subtitle type="html">Inquisitive guinea pig =&gt;
neugieriges Versuchskaninschen =&gt; curious attemptbunny</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/curious-attempt-bunny"/>
			<id>tag:blogger.com,1999:blog-3376508392331888241</id>
			<updated>2010-03-06T03:45:26+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">The state of Haskell-Torrent</title>
		<link href="http://jlouisramblings.blogspot.com/2010/01/state-of-haskell-torrent.html"/>
		<id>tag:blogger.com,1999:blog-5411139659011156551.post-1770211370099302589</id>
		<updated>2010-01-16T10:31:46+00:00</updated>
		<content type="html">&lt;div id=&quot;implementing-processes&quot;&gt;&lt;h1&gt;Implementing processes&lt;/h1&gt;&lt;p&gt;The Haskell Bittorrent project is evolving at a steady state these days. In the last couple of days, we have implemented most of the code relevant for carrying out choking of peers. Choking is the process by which you only communicate to a few peers at a time. Thus TCP/IP congestion can be avoided which drives up the download and upload rates. This post is not on this part however, which must wait a bit.&lt;/p&gt;&lt;p&gt;A fellow dane, Thomas Christensen, heeded my call and did some hlint runs over the code. Hopefully, we’ll see more work from him (&lt;a href=&quot;http://github.com/thomaschrstnsn&quot;&gt;github&lt;/a&gt;). Alex Mason has added even more parsing stuff through Cereal to the code, fixed a number of bugs in the parser and improved its general state. His venture is described on his blog (&lt;a href=&quot;http://random.axman6.com/blog/&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;&lt;div id=&quot;processes&quot;&gt;&lt;h2&gt;Processes&lt;/h2&gt;&lt;p&gt;I will be talking about processes in this post. When haskell-torrent started, our processes were simply “things spawned in the IO monad”. The approach works, but it quickly becomes inadequate for several reasons. In Haskell and FP in general, a lot of power stems from the idea that we can write a large set of small building blocks and then compose them together to form increasingly larger and larger blocks as we go. When composing, we use a fairly small number of helpers — readily present in the standard libraries.&lt;/p&gt;&lt;p&gt;When running in IO, we quickly end up with a lot of state. This can of course be passed around by “hand” and tail-calls. Unfortunately, this means we will end up using a lot of our precious coding time doing just exactly that. To optimize, we need a way to reflect away configuration and state when we don’t need it, and reify the information at certain points in the program where it is necessary to know the state.&lt;/p&gt;&lt;p&gt;The ubiquitious tool in Haskell for this are Monads. Not a single monad like IO, but a for-the-case relevant monad built from monad transformers. A couple of days ago, I installed &lt;a href=&quot;http://xmonad.org/&quot;&gt;XMonad&lt;/a&gt; by Spencer Janssen, Don Stewart, Jason Creighton and many more. This is a window manager — but surprisingly, it needs to solve some problems similar to the one in haskell-torrent. By inspiration from XMonad, we define&lt;/p&gt;&lt;pre class=&quot;sourceCode haskell&quot;&gt;&lt;code&gt;&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt;newtype Process a b c = Process (ReaderT a (StateT b &lt;/span&gt;&lt;span class=&quot;DataType TypeConstructor&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt;) c)&lt;/span&gt;
&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;deriving&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;Keyword Class&quot;&gt;Functor&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;Keyword Class&quot;&gt;Monad&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt;, MonadIO, MonadState b, MonadReader a, Typeable)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That is, a &lt;em&gt;Process&lt;/em&gt; is a type. It contains some configuration data &lt;em&gt;a&lt;/em&gt;, an internal state &lt;em&gt;b&lt;/em&gt; and is in the process of evaluating to a value of type &lt;em&gt;c&lt;/em&gt;. We use a Reader transformer so we can &lt;em&gt;ask&lt;/em&gt; for configuration data when we need it. We do not expect this configuration data to be altered when the process runs. A State Transformer takes care of the internal state of the process. Finally, we let the underlying monad be IO. This gives us access to CML and the outside world.&lt;/p&gt;&lt;p&gt;We let GHC derive a large set of things automatically (using several extensions in the process). This gives an easier way to manipulate the state when the process is running.&lt;/p&gt;&lt;p&gt;Running a Process is easy:&lt;/p&gt;&lt;pre class=&quot;sourceCode haskell&quot;&gt;&lt;code&gt;&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Function FunctionDefinition&quot;&gt;runP ::&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; a -&amp;gt; b -&amp;gt; Process a b c -&amp;gt; &lt;/span&gt;&lt;span class=&quot;DataType TypeConstructor&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; (c, b)&lt;/span&gt;
&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt;runP c st (Process p) = runStateT (runReaderT p c) st&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which is exactly like in XMonad. Spawning a new process is also fairly easy:&lt;/p&gt;&lt;pre class=&quot;sourceCode haskell&quot;&gt;&lt;code&gt;&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Function FunctionDefinition&quot;&gt;spawnP ::&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; a -&amp;gt; b -&amp;gt; Process a b () -&amp;gt; &lt;/span&gt;&lt;span class=&quot;DataType TypeConstructor&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; ThreadId&lt;/span&gt;
&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt;spawnP c st p = spawn proc&lt;/span&gt;
&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; proc = &lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; runP c st p&lt;/span&gt;
&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt;                  &lt;/span&gt;&lt;span class=&quot;Function&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; ()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In general different processes will have different configurations &lt;em&gt;a&lt;/em&gt;. These will usually contain the channels on which the process can communicate. We then define a type class&lt;/p&gt;&lt;pre class=&quot;sourceCode haskell&quot;&gt;&lt;code&gt;&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; Logging a &lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;where&lt;/span&gt;
&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;Function FunctionDefinition&quot;&gt;getLogger ::&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; a -&amp;gt; LogChannel&lt;/span&gt;
&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;
&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; Logging LogChannel &lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;where&lt;/span&gt;
&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt;  getLogger = &lt;/span&gt;&lt;span class=&quot;Function&quot;&gt;id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;of types that contain a logger channel. This means we can define a generic log function like this:&lt;/p&gt;&lt;pre class=&quot;sourceCode haskell&quot;&gt;&lt;code&gt;&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; :: Logging a =&amp;gt; &lt;/span&gt;&lt;span class=&quot;DataType TypeConstructor&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; -&amp;gt; Process a b ()&lt;/span&gt;
&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt; msg = &lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt;    logC &amp;lt;- asks getLogger&lt;/span&gt;
&lt;span class=&quot;Special&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;Normal NormalText&quot;&gt;    liftIO $ logMsg logC msg&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Type classes are a magnificent tool when we want to coerce a general function on top of different types. Many of our configurations in the client will instance the &lt;em&gt;Logging&lt;/em&gt; class and then the log function knows how to access the logger in the Reader.&lt;/p&gt;&lt;/div&gt;&lt;div id=&quot;what-does-this-buy-us&quot;&gt;&lt;h2&gt;What does this buy us&lt;/h2&gt;&lt;p&gt;The advantage of doing this change on the code is twofold: First, the amount of parameter passing is considerably reduced. Reflection into the monad solves this problem. We are now able to compose easier. Function composition is considerably harder when there are many parameters abound. With the change, preliminary restructuring of the Peer process shows a much simpler flow. Also, there are now ample refactoring opportunities available with the change.&lt;/p&gt;&lt;p&gt;Second, the monad means we can use locality much more to our advantage. A common idiom is to modify the state of the process or to retrieve the current state for query. This now happens locally at the point where it is needed. Before, we might have needed to pass a parameter through several functions and then use it.&lt;/p&gt;&lt;/div&gt;&lt;div id=&quot;what-next&quot;&gt;&lt;h2&gt;What next?&lt;/h2&gt;&lt;p&gt;There are a small number of things that needs to be addressed before we can claim that the client is a full bittorrent client:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The client needs to correctly handle the concept of &lt;em&gt;interest&lt;/em&gt;. It must tell other clients if it is interested in the pieces they have at their disposal for transmission. I have some preliminary code for doing this.&lt;/li&gt;&lt;li&gt;The client needs to correctly tell the tracker how many bytes it uploaded and downloaded. This measure is needed on many private trackers as they require people to upload data back.&lt;/li&gt;&lt;li&gt;The client needs to be better at choosing the next eligible piece. Choosing one randomly is good enough.&lt;/li&gt;&lt;li&gt;The client needs to handle multi-file torrents. It is not as hard as it may sound — the only part of the system that needs to know about files is the code handling the file system. All other parts can just keep on transferring pieces.&lt;/li&gt;&lt;li&gt;For choking to work correctly, we must know how fast we are currently transferring to a peer. This is an interesting little problem if somebody feels their curiosity tickled :)&lt;/li&gt;&lt;li&gt;We currently take space proportional to torrent size due to our SHA1 calculation being slow and not use a file descriptor. Research into a faster SHA1 library would be really beneficial.&lt;/li&gt;&lt;li&gt;We need to accept incoming connections. The system only connects outward at the moment.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;And of course, it needs some testing in a non-lab setting. Currently it can seed and leech, but my setup is very simple: Opentracker and rtorrent on another computer.&lt;/p&gt;&lt;p&gt;The main github repository for haskell-torrent is &lt;a href=&quot;http://github.com/jlouis/haskell-torrent/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/5411139659011156551-1770211370099302589?l=jlouisramblings.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Jlouis</name>
			<email>noreply@blogger.com</email>
			<uri>http://jlouisramblings.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">JLOUIS Ramblings</title>
			<subtitle type="html">Musings of a mathematically oriented Computer Scientist. Anything that tickles my brain might go in here, be it Computer Science, mathematics, society, relationships, sex, 0xf00d, or pets.</subtitle>
			<link rel="self" href="http://jlouisramblings.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-5411139659011156551</id>
			<updated>2010-03-10T18:31:55+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Minor Erlang Interface Tricks</title>
		<link href="http://dukesoferl.blogspot.com/2010/01/minor-erlang-interface-tricks.html"/>
		<id>tag:blogger.com,1999:blog-6265608756663924839.post-6622961196913363729</id>
		<updated>2010-01-14T12:41:28+00:00</updated>
		<content type="html">erlrc requires that you drop a file whose name is your node name and whose contents is the node cookie into a particular directory so that the packaging system can find running Erlang VMs and ask them to do hot-code upgrades.  It's not that hard, but I figured I would put some shell scripts into the erlrc google code project demonstrating how to do this and other minor tricks that make it a little nicer to talk to an Erlang VM from the (non-Erlang) command line.&lt;br /&gt;All of these scripts are driven by a POSIX shell syntax configuration file describing an Erlang VM, which can be pretty short.  Here's one I'm using right now for my personal stuff:&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;% cat /usr/share/myerlnode/myerlnode.rc&lt;br /&gt;node_name_file='/etc/erlrc.d/nodes/erlang'&lt;br /&gt;&lt;br /&gt;run_extra_args='+A 64 -noshell -noinput -s crypto -s mnesia -eval &quot;case erlrc_boot:boot () of ok -&gt; ok; _ -&gt; init:stop () end&quot; &gt;erlang.out 2&gt;erlang.err &amp;amp;'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;node_name_file (the only required config setting) defines what the node name will be (via the basename).  This config file drives four scripts:&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/erlrc/source/browse/trunk/erlstart/bin/erlstart-run-erlang&quot;&gt;erlstart-run-erlang&lt;/a&gt;: starts an Erlang VM.  doesn't do that much, really: creates the node file for erlrc, and sets the heart command in case you want to use heart.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/erlrc/source/browse/trunk/erlstart/bin/erlstart-remsh&quot;&gt;erlstart-remsh&lt;/a&gt;: starts a remote shell on an Erlang VM.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/erlrc/source/browse/trunk/erlstart/bin/erlstart-eval&quot;&gt;erlstart-eval&lt;/a&gt;: takes the argument, evals it on an Erlang VM, and prints the result to standard out.  very useful shell script glue for maintenance scripts.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/erlrc/source/browse/trunk/erlstart/bin/erlstart-etop&quot;&gt;erlstart-etop&lt;/a&gt;: runs etop on an Erlang VM.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;If you put your config file in the default location (/etc/erlstart.rc) or export an environment variable indicating the location (ERLSTART_CONFIG_FILE) then things are pretty zero-configuration.  Doing this kind of thing at the (non-Erlang) shell gets very addictive:&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;brush:bash&quot;&gt;% erlstart-eval 'application:which_applications()'&lt;br /&gt;[{anwhereos,&quot;Rest API for time series persistence and retrieval.&quot;,&quot;0.1.0&quot;},&lt;br /&gt;{drurlyjsclientsrv,&quot;Serve the drurly jsclient from the drurly server.&quot;,&lt;br /&gt;                &quot;0.0.1&quot;},&lt;br /&gt;{drurly,&quot;Social sharing server.&quot;,&quot;2.2.0&quot;},&lt;br /&gt;{mcedemo,&quot;TinyMCE + Nitrogen demo.&quot;,&quot;1.3.0&quot;},&lt;br /&gt;{inets,&quot;INETS  CXC 138 49&quot;,&quot;5.0.12&quot;},&lt;br /&gt;{mochiweb,&quot;MochiWeb is an Erlang library for building lightweight HTTP servers.&quot;,&lt;br /&gt;       &quot;0.2009.05.26&quot;},&lt;br /&gt;{nitrogen,&quot;Nitrogen web framework for Erlang.&quot;,&quot;0.2009.05.12.3&quot;},&lt;br /&gt;{nitromce,&quot;A Nitrogen element which corresponds to a TinyMCE editor instance.&quot;,&lt;br /&gt;       &quot;4.0.1&quot;},&lt;br /&gt;{sgte,&quot;String template language for Erlang.&quot;,&quot;0.7.1&quot;},&lt;br /&gt;{signzor,&quot;Erlang library to generate signed printable encodings.&quot;,&quot;0.0.1&quot;},&lt;br /&gt;{tcerl,&quot;Erlang driver for tokyocabinet.&quot;,&quot;1.3.1h&quot;},&lt;br /&gt;{webmachine,&quot;An Erlang REST framework.&quot;,&quot;0.2009.09.24b&quot;},&lt;br /&gt;{erlrc,&quot;Extensible application management.&quot;,&quot;0.2.3&quot;},&lt;br /&gt;{mnesia,&quot;Mnesia storage API extensions.&quot;,&quot;4.4.7.6.1&quot;},&lt;br /&gt;{crypto,&quot;CRYPTO version 1&quot;,&quot;1.5.3&quot;},&lt;br /&gt;{sasl,&quot;SASL  CXC 138 11&quot;,&quot;2.1.5.4&quot;},&lt;br /&gt;{stdlib,&quot;ERTS  CXC 138 10&quot;,&quot;1.15.5&quot;},&lt;br /&gt;{kernel,&quot;ERTS  CXC 138 10&quot;,&quot;2.12.5&quot;}]&lt;/pre&gt;erlstart-run-erlang is fairly low level, so for an init script I would do something like the following: first, a little stub installed into /etc/rc.d&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;#! /bin/sh&lt;br /&gt;&lt;br /&gt;# chkconfig: 2345 20 80&lt;br /&gt;# description: Control my personal Erlang node.&lt;br /&gt;&lt;br /&gt;exec myerlnodectl &quot;$@&quot;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and then the actual guts installed as myerlnodectl&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;#! /bin/sh&lt;br /&gt;&lt;br /&gt;eval_with_main_node () \&lt;br /&gt;{&lt;br /&gt;  erl -name myerlnodetmp$$ \&lt;br /&gt;      -hidden \&lt;br /&gt;      -setcookie &quot;$cookie&quot; \&lt;br /&gt;      -noshell -noinput \&lt;br /&gt;      -eval &quot;MainNode = list_to_atom (\&quot;$1\&quot;), $2&quot; \&lt;br /&gt;      -s erlang halt&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;get_hostname () \&lt;br /&gt;{&lt;br /&gt;  erl -name myerlnodetmp$$ -setcookie $$ -noshell -noinput -eval '&lt;br /&gt;    [ Host ] = tl (string:tokens (atom_to_list (node ()), &quot;@&quot;)),&lt;br /&gt;    io:format (&quot;~s~n&quot;, [ Host ])&lt;br /&gt;  ' -s init stop&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;id=`basename &quot;$0&quot;`&lt;br /&gt;&lt;br /&gt;if test -d /root&lt;br /&gt;then&lt;br /&gt;  HOME=${HOME-/root}&lt;br /&gt;else if test -d /var/root&lt;br /&gt;  then&lt;br /&gt;    HOME=${HOME-/var/root}&lt;br /&gt;  fi&lt;br /&gt;fi&lt;br /&gt;export HOME&lt;br /&gt;&lt;br /&gt;ERLSTART_CONFIG_FILE=${ERLSTART_CONFIG_FILE-/usr/share/myerlnode/myerlnode.rc}&lt;br /&gt;export ERLSTART_CONFIG_FILE&lt;br /&gt;&lt;br /&gt;. &quot;$ERLSTART_CONFIG_FILE&quot;&lt;br /&gt;&lt;br /&gt;cookie=${cookie-turg}&lt;br /&gt;user=${user-erlang}&lt;br /&gt;hostname=${hostname-`get_hostname`}&lt;br /&gt;node_name=`basename &quot;$node_name_file&quot;`&lt;br /&gt;full_name=&quot;$node_name@$hostname&quot;&lt;br /&gt;shutdown_file=${shutdown_file-/var/run/myerlnode.shutting_down}&lt;br /&gt;&lt;br /&gt;ERL_CRASH_DUMP=${ERL_CRASH_DUMP-/dev/null}&lt;br /&gt;export ERL_CRASH_DUMP&lt;br /&gt;&lt;br /&gt;case ${1-&quot;status&quot;} in&lt;br /&gt;start)&lt;br /&gt;  test &quot;`id -u`&quot; -eq 0 || exec sudo $0 &quot;$@&quot;&lt;br /&gt;&lt;br /&gt;  printf &quot;Starting Erlang... &quot;&lt;br /&gt;&lt;br /&gt;  if test -f &quot;$node_name_file&quot; &amp;amp;&amp;amp;                                     \&lt;br /&gt;     test true = &quot;`erlstart-eval 'true' 2&gt;/dev/null`&quot; 2&gt;/dev/null&lt;br /&gt;    then&lt;br /&gt;      echo &quot;already started.&quot;&lt;br /&gt;      exit 0&lt;br /&gt;    fi&lt;br /&gt;&lt;br /&gt;  pid=`eval_with_main_node &quot;$full_name&quot; '&lt;br /&gt;         io:format (&quot;~p&quot;, [&lt;br /&gt;           case rpc:call (MainNode, os, getpid, []) of&lt;br /&gt;             { badrpc, _ } -&gt; undefined;&lt;br /&gt;             Pid -&gt; list_to_integer (Pid)&lt;br /&gt;           end ])'`&lt;br /&gt;&lt;br /&gt;  test &quot;$pid&quot; -gt 0 2&gt;/dev/null &amp;amp;&amp;amp; {&lt;br /&gt;    test -f &quot;$shutdown_file&quot; &amp;amp;&amp;amp; {&lt;br /&gt;      oldpid=`cat &quot;$shutdown_file&quot;`&lt;br /&gt;      test &quot;$pid&quot; -eq &quot;$oldpid&quot; &amp;amp;&amp;amp; {&lt;br /&gt;        echo &quot;shutdown in progress (pid = '$pid').&quot; 1&gt;&amp;amp;2&lt;br /&gt;        exit 1&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  rm -f &quot;$shutdown_file&quot;&lt;br /&gt;&lt;br /&gt;  # check for -s shell support&lt;br /&gt;  su -l -s /bin/sh $user -c true &gt;/dev/null 2&gt;/dev/null&lt;br /&gt;&lt;br /&gt;  if test $? = 0&lt;br /&gt;    then&lt;br /&gt;      dashs=&quot;-s /bin/sh&quot;&lt;br /&gt;    else&lt;br /&gt;      dashs=&quot;&quot;&lt;br /&gt;    fi&lt;br /&gt;&lt;br /&gt;  ${niceness+ nice -n $niceness}                                      \&lt;br /&gt;  su -l $dashs &quot;$user&quot; -c                                             \&lt;br /&gt;    &quot;env cookie=\&quot;$cookie\&quot; erlstart-run-erlang \&quot;$ERLSTART_CONFIG_FILE\&quot;&quot;&lt;br /&gt;&lt;br /&gt;  eval_with_main_node &quot;$full_name&quot;                                    \&lt;br /&gt;      &quot;Wait = fun (_, 0) -&gt;&lt;br /&gt;                    failed;&lt;br /&gt;                  (Cont, Max) -&gt;&lt;br /&gt;                    case net_adm:ping (MainNode) of&lt;br /&gt;                      pong -&gt;&lt;br /&gt;                        ok;&lt;br /&gt;                      pang -&gt;&lt;br /&gt;                        timer:sleep (100),&lt;br /&gt;                        Cont (Cont, Max - 1)&lt;br /&gt;                    end&lt;br /&gt;              end,&lt;br /&gt;       DontTellMe = 100,&lt;br /&gt;       ok = Wait (Wait, DontTellMe)&quot; || {&lt;br /&gt;    echo &quot;&quot; 1&gt;&amp;amp;2&lt;br /&gt;    echo &quot;$id: could not connect to node after 10 seconds&quot; 1&gt;&amp;amp;2&lt;br /&gt;    exit 1&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  eval_with_main_node &quot;$full_name&quot;                                    \&lt;br /&gt;      &quot;Wait = fun (_, 0) -&gt;&lt;br /&gt;                    failed;&lt;br /&gt;                  (Cont, Max) -&gt;&lt;br /&gt;                    case rpc:call (MainNode, init, get_status, []) of&lt;br /&gt;                      { started, _ } -&gt;&lt;br /&gt;                        ok;&lt;br /&gt;                      { starting, _ } -&gt;&lt;br /&gt;                        timer:sleep (100),&lt;br /&gt;                        Cont (Cont, Max - 1);&lt;br /&gt;                      { Status, _ } -&gt;&lt;br /&gt;                        { failed, Status }&lt;br /&gt;                    end&lt;br /&gt;              end,&lt;br /&gt;       DontTellMe = 100,&lt;br /&gt;       ok = Wait (Wait, DontTellMe)&quot; || {&lt;br /&gt;    echo &quot;&quot; 1&gt;&amp;amp;2&lt;br /&gt;    echo &quot;$id: node did not boot after 10 seconds&quot; 1&gt;&amp;amp;2&lt;br /&gt;    exit 1&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;echo &quot;done.&quot;&lt;br /&gt;;;&lt;br /&gt;&lt;br /&gt;stop)&lt;br /&gt;  test &quot;`id -u`&quot; -eq 0 || exec sudo $0 &quot;$@&quot;&lt;br /&gt;&lt;br /&gt;  printf &quot;Stopping Erlang... &quot;&lt;br /&gt;&lt;br /&gt;  if test ! -f &quot;$node_name_file&quot; ||                                   \&lt;br /&gt;     test true != &quot;`erlstart-eval 'true' 2&gt;/dev/null`&quot; 2&gt;/dev/null&lt;br /&gt;    then&lt;br /&gt;      echo &quot;not running.&quot;&lt;br /&gt;      exit 0&lt;br /&gt;    fi&lt;br /&gt;&lt;br /&gt;  pid=`erlstart-eval 'os:getpid ()' 2&gt;/dev/null`&lt;br /&gt;&lt;br /&gt;  test &quot;$pid&quot; -gt 0 2&gt;/dev/null &amp;amp;&amp;amp; {&lt;br /&gt;    printf '%s' $pid &gt; &quot;$shutdown_file&quot;&lt;br /&gt;    chown $user:$user &quot;$shutdown_file&quot;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  erlstart-eval 'init:stop ()' &gt;/dev/null 2&gt;/dev/null&lt;br /&gt;&lt;br /&gt;  eval_with_main_node &quot;$full_name&quot;                                    \&lt;br /&gt;      &quot;Wait = fun (_, 0) -&gt;&lt;br /&gt;                    failed;&lt;br /&gt;                  (Cont, Max) -&gt;&lt;br /&gt;                    case net_adm:ping (MainNode) of&lt;br /&gt;                      pong -&gt;&lt;br /&gt;                        timer:sleep (100),&lt;br /&gt;                        Cont (Cont, Max - 1);&lt;br /&gt;                      pang -&gt;&lt;br /&gt;                        ok&lt;br /&gt;                    end&lt;br /&gt;              end,&lt;br /&gt;       DontTellMe = 100,&lt;br /&gt;       ok = Wait (Wait, DontTellMe)&quot; || {&lt;br /&gt;    echo &quot;&quot; 1&gt;&amp;amp;2&lt;br /&gt;    echo &quot;$id: node still responsive after 100 seconds&quot; 1&gt;&amp;amp;2&lt;br /&gt;    exit 1&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  rm -f &quot;$node_name_file&quot;&lt;br /&gt;&lt;br /&gt;  echo &quot;done.&quot;&lt;br /&gt;  ;;&lt;br /&gt;&lt;br /&gt;status)&lt;br /&gt;  if test -f &quot;$node_name_file&quot; &amp;amp;&amp;amp;                                     \&lt;br /&gt;     test true = &quot;`erlstart-eval 'true' 2&gt;/dev/null`&quot; 2&gt;/dev/null&lt;br /&gt;    then&lt;br /&gt;      echo &quot;Erlang is running&quot;&lt;br /&gt;    else&lt;br /&gt;      echo &quot;Erlang is not running&quot;&lt;br /&gt;    fi&lt;br /&gt;&lt;br /&gt;  ;;&lt;br /&gt;&lt;br /&gt;*)&lt;br /&gt;  echo &quot;$id: unknown command $1&quot; 1&gt;&amp;amp;2&lt;br /&gt;  exit 1&lt;br /&gt;esac&lt;br /&gt;&lt;br /&gt;exit 0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Hopefully you found that inspirational.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/6265608756663924839-6622961196913363729?l=dukesoferl.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Paul Mineiro</name>
			<email>noreply@blogger.com</email>
			<uri>http://dukesoferl.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Dukes of Erl</title>
			<subtitle type="html">Someday the mountain might get &amp;rsquo;em, but the law never will.</subtitle>
			<link rel="self" href="http://dukesoferl.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-6265608756663924839</id>
			<updated>2010-03-09T15:45:26+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">WS-REST 2010 CfP</title>
		<link href="http://steve.vinoski.net/blog/2010/01/14/ws-rest-2010-cfp/"/>
		<id>http://steve.vinoski.net/blog/?p=520</id>
		<updated>2010-01-14T05:45:25+00:00</updated>
		<content type="html">&lt;p&gt;I&amp;#8217;m on the program committee for the WS-REST 2010 conference. Please consider submitting a paper, but note that the submission deadline is coming up quickly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WS-REST 2010&lt;br /&gt;
&lt;a href=&quot;http://ws-rest.org/&quot;&gt;http://ws-rest.org/&lt;/a&gt;&lt;br /&gt;
Paper Submission: February 8, 2010&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Call for Papers&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;http://ws-rest.org/&quot;&gt;First International Workshop on RESTful Design (WS-REST 2010)&lt;/a&gt; aims to provide a forum for discussion and dissemination of research on the emerging resource-oriented style of Web service design.&lt;/p&gt;
&lt;p&gt;Background&lt;/p&gt;
&lt;p&gt;Over the past few years, several discussions between advocates of the two major architectural styles for designing and implementing Web services (the RPC/ESB-oriented approach and the resource-oriented approach) have been mainly held outside of the research and academic community, within dedicated mailing lists, forums and practitioner communities. The RESTful approach to Web services has also received a significant amount of attention from industry as indicated by the numerous technical books being published on the topic.&lt;/p&gt;
&lt;p&gt;This first edition of WS-REST, co-located with the &lt;a href=&quot;http://www2010.org/&quot;&gt;WWW2010&lt;/a&gt; conference, aims at providing an academic forum for discussing current emerging research topics centered around the application of REST, as well as advanced application scenarios for building large scale distributed systems.&lt;/p&gt;
&lt;p&gt;In addition to presentations on novel applications of RESTful Web services technologies, the workshop program will also include discussions on the limits of the applicability of the REST architectural style, as well as recent advances in research that aim at tackling new problems that may require to extend the basic REST architectural style. The organizers are seeking novel and original, high quality paper submissions on research contributions focusing on the following topics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Applications of the REST architectural style to novel domains&lt;/li&gt;
&lt;li&gt;Design Patterns and Anti-Patterns for RESTful services&lt;/li&gt;
&lt;li&gt;RESTful service composition&lt;/li&gt;
&lt;li&gt;Inverted REST (REST for push events)&lt;/li&gt;
&lt;li&gt;Integration of Pub/Sub with REST&lt;/li&gt;
&lt;li&gt;Performance and QoS Evaluations of RESTful services&lt;/li&gt;
&lt;li&gt;REST compliant transaction models&lt;/li&gt;
&lt;li&gt;Mashups&lt;/li&gt;
&lt;li&gt;Frameworks and toolkits for RESTful service implementations&lt;/li&gt;
&lt;li&gt;Frameworks and toolkits for RESTful service consumption&lt;/li&gt;
&lt;li&gt;Modeling RESTful services&lt;/li&gt;
&lt;li&gt;Resource Design and Granularity&lt;/li&gt;
&lt;li&gt;Evolution of RESTful services&lt;/li&gt;
&lt;li&gt;Versioning and Extension of REST APIs&lt;/li&gt;
&lt;li&gt;HTTP extensions and replacements&lt;/li&gt;
&lt;li&gt;REST compliant protocols beyond HTTP&lt;/li&gt;
&lt;li&gt;Multi-Protocol REST (REST architectures across protocols)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All workshop papers are peer-reviewed and accepted papers will be published as part of the ACM Digital Library. Two kinds of contributions are sought: short position papers (not to exceed 4 pages in ACM style format) describing particular challenges or experiences relevant to the scope of the workshop, and full research papers (not to exceed 8 pages in the ACM style format) describing novel solutions to relevant problems. Technology demonstrations are particularly welcome, and we encourage authors to focus on &amp;#8220;lessons learned&amp;#8221; rather than describing an implementation.&lt;/p&gt;
&lt;p&gt;Papers must be submitted electronically in PDF format. Submit at the &lt;a href=&quot;http://www.easychair.org/conferences/?conf=WSREST2010&quot;&gt;WS-REST 2010 EasyChair installation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Important Dates&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Submission deadline: February 8, 2010, 23.59 Hawaii time&lt;/li&gt;
&lt;li&gt;Notification of acceptance: March 1, 2010&lt;/li&gt;
&lt;li&gt;Camera-ready versions of accepted papers: March 14, 2010&lt;/li&gt;
&lt;li&gt;WS-REST 2010 Workshop: April 26, 2010&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Program Committee Chairs&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.pautasso.info/&quot;&gt;Cesare Pautasso&lt;/a&gt;, Faculty of Informatics, USI Lugano, Switzerland&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://dret.net/netdret/&quot;&gt;Erik Wilde&lt;/a&gt;, School of Information, UC Berkeley, USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.eps.surrey.ac.uk/profiles?s_id=3235&quot;&gt;Alexandros Marinos&lt;/a&gt;, Faculty of Engineering &amp;#038; Physical Sciences, University of Surrey, UK&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Program Committee&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rosa Alarcon, Pontificia Universidad Catolica de Chile&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.subbu.org/&quot;&gt;Subbu Allamaraju&lt;/a&gt;, Yahoo Inc., USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.tbray.org/ongoing/&quot;&gt;Tim Bray&lt;/a&gt;, Sun Microsystems, USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://bill.burkecentral.com/&quot;&gt;Bill Burke&lt;/a&gt;, Red Hat, USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://soundadvice.id.au/blog/&quot;&gt;Benjamin Carlyle&lt;/a&gt;, Australia&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stucharlton.com/blog&quot;&gt;Stuart Charlton&lt;/a&gt;, Elastra, USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://bitworking.org/&quot;&gt;Joe Gregorio&lt;/a&gt;, Google, USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://sw-app.org/about.html&quot;&gt;Michael Hausenblas&lt;/a&gt;, DERI, Ireland&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.ics.uci.edu/~rohit/&quot;&gt;Rohit Khare&lt;/a&gt;, 4K Associates, USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.iaas.uni-stuttgart.de/institut/mitarbeiter/leymann/indexE.php&quot;&gt;Frank Leymann&lt;/a&gt;, University of Stuttgart, Germany&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.mnot.net/&quot;&gt;Mark Nottingham&lt;/a&gt;, Yahoo Inc., Australia&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://plasmasturm.org/&quot;&gt;Aristotle Pagaltzis&lt;/a&gt;, Germany&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://iansrobinson.com/&quot;&gt;Ian Robinson&lt;/a&gt;, Thoughtworks, USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.ics.uci.edu/~taylor/&quot;&gt;Richard Taylor&lt;/a&gt;, UC Irvine, USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.innoq.com/blog/st/&quot;&gt;Stefan Tilkov&lt;/a&gt;, innoQ, Germany&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://steve.vinoski.net/&quot;&gt;Steve Vinoski&lt;/a&gt;, Verivue, USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://jim.webber.name/&quot;&gt;Jim Webber&lt;/a&gt;, Thoughtworks, USA&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.zurich.ibm.com/~olz/&quot;&gt;Olaf Zimmermann&lt;/a&gt;, IBM Zurich Research Lab, Switzerland&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Contact&lt;/p&gt;
&lt;p&gt;WS-REST Web site: &lt;a href=&quot;http://ws-rest.org/&quot;&gt;http://ws-rest.org/&lt;/a&gt;&lt;br /&gt;
WS-REST Email: &lt;a href=&quot;mailto:chairs@ws-rest.org&quot;&gt;chairs@ws-rest.org&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>steve</name>
			<uri>http://steve.vinoski.net/blog</uri>
		</author>
		<source>
			<title type="html">Steve Vinoski's Blog</title>
			<subtitle type="html">Ask forgiveness, not permission.</subtitle>
			<link rel="self" href="http://steve.vinoski.net/blog/feed/atom/"/>
			<id>http://steve.vinoski.net/blog/feed/atom/</id>
			<updated>2010-03-10T23:00:21+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">14 December 2009: Erlang Training and Consulting's 10th Birthday – it's time to change our name!</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1125"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1125</id>
		<updated>2010-01-11T16:32:22+00:00</updated>
		<content type="html">2009 has been a huge year for us. Not only have we had an incredible
year assisting companies on six continents with their use of Erlang but
we have also organised 4 conferences, 10 Erlang User Group Meetings
and&amp;#160; started a KTP project in e-learning with the University
of Kent. To add to all that - it&amp;#8217;s also our 10th Birthday!
&lt;br /&gt;&lt;br /&gt;It all began 10 years ago on 13th December 1999,
when our founder Francesco Cesarini decided to set up the first
non-Scandinavian company to offer Erlang/OTP training and consultancy
services. At that time, Erlang wasn't known outside of the 'Ericsson
world'. Over the years the business grew dramatically. We have expanded
geographically, with offices now in London (UK), Uppsala (Sweden) and
Krakow (Poland) and now we employ 40 employees worldwide. The services
on offer have also expanded significantly. We are now a one-stop shop
for all Erlang needs, including:&lt;br /&gt; 
&lt;ul&gt;
&lt;li&gt;Erlang &lt;a href=&quot;http://www.erlang-consulting.com/training/&quot; target=&quot;_self&quot;&gt;training&lt;/a&gt; at all levels&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;http://www.erlang-consulting.com/section/14/certification&quot; target=&quot;_self&quot;&gt;Certification&lt;/a&gt; in Erlang&lt;/li&gt; 
&lt;li&gt;Provision of experienced Erlang &lt;a href=&quot;http://www.erlang-consulting.com/section/6/consulting&quot; target=&quot;_self&quot;&gt;contractors&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;Erlang &lt;a href=&quot;http://www.erlang-consulting.com/section/6/consulting&quot; target=&quot;_self&quot;&gt;consulting&lt;/a&gt; services&lt;/li&gt; 
&lt;li&gt;In-house &lt;a href=&quot;http://www.erlang-consulting.com/section/12/development&quot; target=&quot;_self&quot;&gt;systems development&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;24/7 &lt;a href=&quot;http://www.erlang-consulting.com/section/13/support&quot; target=&quot;_self&quot;&gt;support&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;Assistance
with building Erlang teams.&amp;#160; &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;A year ago we started running the &lt;a href=&quot;http://www.erlang-factory.com/&quot; target=&quot;_blank&quot;&gt;Erlang Factory&lt;/a&gt; conferences. These are
aimed at all levels of the development community including Architects,
Programmers, Project Managers, Software and Platform Innovators as well
as existing Erlang users. They are also designed to present Erlang to
prospective users, Erlang newbies and anyone else interested in making
use if the many strengths of the language. The Erlang Factory takes
place twice a year - in the San Francisco Bay Area in March/April and in London in June. In 2009 we also took over the organisation of the &lt;a href=&quot;http://www.erlang-factory.com/conference/ErlangUserConference2009&quot; target=&quot;_blank&quot;&gt;Erlang User Conference&lt;/a&gt; in Stockholm
&amp;#8211; the oldest Erlang conference in the world, which has been
held annually since 1994. Finally this year the first Erlang day in
Krakow (Poland) called &lt;a href=&quot;http://www.erlang-factory.com/conference/Krakow2009&quot; target=&quot;_blank&quot;&gt;Erlang Factory Lite&lt;/a&gt; was held to grow
interest in Erlang of the substantial technology Community in that
country.&lt;br /&gt;&lt;br /&gt;Great service, a customer-focus and
skilled and experienced staff have been the basis of our growth over
the past ten years. This will not change. However in 2010 we will do it
with a new name! In order to better describe the breadth of our service
offering, on &lt;span&gt;1st January 2010 we will become Erlang Solutions Ltd.&lt;/span&gt;</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-03-10T23:00:54+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">09 December 2009: Marcus Taylor at Strengthen Your Business</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1116"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1116</id>
		<updated>2010-01-11T16:32:22+00:00</updated>
		<content type="html">More than 50 representatives from the business world attended a special networking event at the University of Kent&amp;#8217;s Medway campus.&amp;#160; Called Strengthen Your Business, the free session on 25 November gave business leaders the chance to explore how their companies can team up with the University, and benefit from its commercial expertise and resources.&lt;br /&gt;&lt;br /&gt;A variety of business people who had successfully worked with the University on student placements or Knowledge Transfer Partnerships spoke of their experiences, while others outlined the opportunities for collaboration in graduate recruitment and continuing professional development schemes. There was also the chance for individuals to network after the main talks.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.erlang-consulting.com/../../section/38/board-of-directors&quot; target=&quot;_blank&quot;&gt;Marcus Taylor&lt;/a&gt;, Chief Executive for London-based Erlang Training and Consulting, spoke of the strategic help his company had received with Knowledge Transfer Partnerships &amp;#8211; a government-funded initiative that helps businesses develop their competitiveness, productivity and performance. &amp;#8216;I&amp;#8217;m not an experienced bid writer, but the University has a wealth of experience in this area and supported us wonderfully throughout the whole process &amp;#8211; so much so that we&amp;#8217;re thinking of applying for our fourth project,&amp;#8217; he said.&lt;br /&gt;&lt;br /&gt;
&lt;div&gt;&lt;img src=&quot;http://erlang-consulting.com/upload/images/40/Strengthen2small.jpg&quot; /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;img src=&quot;http://erlang-consulting.com/upload/images/41/Strengthen1small.jpg&quot; /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;James Corbin, Placement Officer for the University of Kent, said it was a golden opportunity for businesses to find out about the resources on their own doorstep. 'The University is host to a wealth of knowledge that can often provide businesses with the solutions they seek,&amp;#8217; he said. &amp;#8216;We&amp;#8217;re convinced that firms who work with the University can gain a competitive edge.&amp;#8217;&lt;br /&gt;&lt;br /&gt;The event followed hot on the heels of the launch of the University&amp;#8217;s ICE initiative, which took place at the Canterbury Innovation Centre on 17 November. ICE stands for innovation, creativity and enterprise, and is a project that aims to connect local, regional, national and international businesses to the University of Kent and to each other.&lt;br /&gt;&lt;br /&gt;The Strengthen Your Business event at Medway was run in partnership with Thames Gateway Chamber of Commerce.&lt;br /&gt;</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-03-10T23:00:54+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">07 December 2009: Erlang Factory 2010 Dates Announced!!</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1113"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1113</id>
		<updated>2010-01-11T16:32:22+00:00</updated>
		<content type="html">The dates of the Erlang Factory in the SF Bay Area and London have been announced.&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010&quot; target=&quot;_blank&quot;&gt;SF Bay Area&lt;/a&gt;: 25-26 March 2010&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.erlang-factory.com/conference/London2010&quot; target=&quot;_self&quot;&gt;London&lt;/a&gt;: 10-11 June 2010&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Registration will be opening soon and we are currently accepting talk proposals. If you want to give a presentation at the Erlang Factory, you can find more information how to do that, &lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010/submit_talk&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. Keep a look out and follow us on Twitter &lt;a href=&quot;http://twitter.com/erlangfactory&quot; target=&quot;_blank&quot;&gt;@erlangfactory&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;
&lt;div&gt;.&lt;a href=&quot;http://www.erlang-factory.com/conference/SFBay2010&quot;&gt; &lt;img src=&quot;http://www.erlang-factory.com/images/bay2010see.gif&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/div&gt;</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-03-10T23:00:54+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">30 November 2009: Erlang Training and Consulting soon Erlang Solutions will be present at ACCU 2010</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1112"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1112</id>
		<updated>2010-01-11T16:32:22+00:00</updated>
		<content type="html">&lt;a href=&quot;http://www.erlang-consulting.com/../../section/36/management&quot; target=&quot;_self&quot;&gt;Francesco Cesarini&lt;/a&gt; (founder of Erlang Training and Consulting, soon Erlang Solutions Ltd.) and &lt;a href=&quot;http://www.erlang-consulting.com/../../section/36/management&quot; target=&quot;_self&quot;&gt;Ulf Wiger&lt;/a&gt; (CTO of Erlang Training and Consulting, soon Erlang Solutions Ltd.) will be speaking&amp;#160; at &lt;a href=&quot;http://accu.org/index.php/conferences&quot; target=&quot;_blank&quot;&gt;ACCU 2010&lt;/a&gt;. Francesco's talk on &lt;span&gt;Styling your Architecture in an Evolving Concurrent World&lt;/span&gt; and Ulf's on &lt;span&gt;Message-Passing Concurrency in Erlang&lt;/span&gt;, have both been accepted by the conference committee.&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;&lt;img src=&quot;http://www.erlang-consulting.com/../../upload/images/39/accu2010web.png&quot; /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href=&quot;http://accu.org/index.php/conferences&quot; target=&quot;_blank&quot;&gt;ACCU 2010&lt;/a&gt; will take place from 14th to 17th April 2010&amp;#160; at the Barcelo Oxford Hotel, in Oxford, UK. The programme of the conference will feature a special track on software testing, and sessions on concurrent and distributed systems, C++, Java,agile development and Erlang! &lt;br /&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span&gt;&amp;#160;&amp;#160; Meet us at ACCU 2010!&amp;#160;&amp;#160; &lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
 
&lt;/div&gt;</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-03-10T23:00:54+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">23 November 2009: The Largest Erlang Open Source Project Directory!</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1109"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1109</id>
		<updated>2010-01-11T16:32:22+00:00</updated>
		<content type="html">&lt;a href=&quot;http://www.trapexit.org/&quot; target=&quot;_blank&quot;&gt;Trapexit&lt;/a&gt; has announced its own Erlang open source crawler. It will crawl the web, gathering searchable information on all open source Erlang projects from all the major repositories. Trapexit will allow discussing these projects in the forum, adding documentation in the Trapexit wiki or rating the various contributions. To view the project index repository, visit &lt;a href=&quot;http://projects.trapexit.org/&quot; target=&quot;_blank&quot;&gt;http://projects.trapexit.org&lt;/a&gt;.</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-03-10T23:00:54+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">19 November 2009: Learn Erlang from experts</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1108"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1108</id>
		<updated>2010-01-11T16:32:22+00:00</updated>
		<content type="html">Do you want to learn about&amp;#160; the basic, sequential and concurrent aspects of the Erlang programming language? And would you like to be taught by the expert, author of the '&lt;a href=&quot;http://oreilly.com/catalog/9780596518189&quot; target=&quot;_blank&quot;&gt;Erlang Programming&lt;/a&gt;' book?&lt;br /&gt;&lt;br /&gt;If the answer is yes, then we have something which may interest you:&lt;br /&gt;&lt;br /&gt;On Wednesday, &lt;span&gt;3rd February 2010&lt;/span&gt; in &lt;span&gt;London&lt;/span&gt;&amp;#160; &lt;a href=&quot;http://www.erlang-consulting.com/../../section/38/board-of-directors&quot; target=&quot;_blank&quot;&gt;Francesco Cesarini&lt;/a&gt;, the author of 'Erlang Programming'&amp;#160; also the founder and CSO of Erlang Training and Consulting Ltd. will give a tutorial on &lt;a href=&quot;http://www.ukuug.org/events/erlang/&quot; target=&quot;_blank&quot;&gt;Practical Erlang Programming&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You will learn the basics of how to read, write and structure Erlang programmes. The goal of tutorial is a hands-on introduction to the theory and concepts behind sequential and concurrent Erlang programming, explaining the Erlang syntax, semantics and concurrency model. We conclude with an overview of the error handling mechanisms used to build fault tolerant systems with five nines availability.&lt;br /&gt;&lt;br /&gt;The target audience are software developers and engineers with an interest in server side applications and massively concurrent systems. &lt;br /&gt;&lt;br /&gt;To learn more about the tutorial, please go &lt;a href=&quot;http://www.ukuug.org/events/erlang/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; and if you want to book it click &lt;a href=&quot;http://www.ukuug.org/events/erlang/booking/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The tutorial will take place in the Caesar Room, Imperial Hotel, Russell Square, London WC1B 5BB.&lt;br /&gt;&lt;br /&gt;See &lt;span&gt;you&lt;/span&gt; there!&lt;br /&gt;</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-03-10T23:00:54+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">19 November 2009: ETC at the 11th Symposium on Trends in Functional Programming</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1106"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1106</id>
		<updated>2010-01-11T16:32:22+00:00</updated>
		<content type="html">Erlang Training and Consulting Ltd. sponsors the &lt;a href=&quot;http://www.cs.ou.edu/tfp2010/index.html&quot; target=&quot;_blank&quot;&gt;11th Symposium on Trends in Functional Programming&lt;/a&gt; and sits on the programme committee.&lt;br /&gt;&lt;br /&gt;The symposium is an international forum for researchers with interests in all aspects of functional programming. It embraces a broad view of current and future trends in functional programming and aspires to be a lively environment for presenting the latest research and applications. &lt;br /&gt;&lt;br /&gt;The &lt;a href=&quot;http://www.cs.ou.edu/tfp2010/index.html&quot; target=&quot;_blank&quot;&gt;11th Symposium on Trends in Functional Programming&lt;/a&gt; will be held at the University of Oklahoma, on campus in Norman, &lt;span&gt;Oklahoma, May 17-19, 2010&lt;/span&gt;.&lt;br /&gt;</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-03-10T23:00:54+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">12 November 2009: Take our Erlang Certification Survey!</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1104"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1104</id>
		<updated>2010-01-11T16:32:22+00:00</updated>
		<content type="html">Erlang Training and Consulting Ltd in conjunction with the University of Kent intends to launch a pilot version of an e-certification platform for Erlang in the near future.&lt;br /&gt;&lt;br /&gt;To assist in this process, we have launched a survey on Erlang Certification. The objective of the study is to better understand the expectations of users, in order to ensure a well-focused product.&lt;br /&gt;&lt;br /&gt;We would appreciate a few minutes of your time in completing this survey. To take the survey, please go to:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://surveys.erlang-consulting.com/index.php?sid=21265&amp;lang=en&quot; target=&quot;_blank&quot;&gt;http://surveys.erlang-consulting.com/index.php?sid&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The results of the survey will be shared with third parties, in publications and as part of research into Certification. When doing so, all results will be completely anonymised and any individual-identifying information removed.&lt;br /&gt;&lt;br /&gt;Thank you for your time and cooperation!</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-03-10T23:00:54+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">28 October 2009: Erlang Web 1.4 has been released!</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1102"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1102</id>
		<updated>2010-01-11T16:32:22+00:00</updated>
		<content type="html">We are happy to announce the next official release of the &lt;a href=&quot;http://www.erlang-web.org/&quot; target=&quot;_blank&quot;&gt;Erlang Web&lt;/a&gt; framework. The latest &lt;span&gt;1.4 version&lt;/span&gt; is full of new features and enhancements, like integration with &lt;a href=&quot;http://wiki.erlang-web.org/&quot; target=&quot;_blank&quot;&gt;EWGI&lt;/a&gt;, new template language support: &lt;a href=&quot;http://code.google.com/p/erlydtl/&quot; target=&quot;_blank&quot;&gt;ErlyDTL&lt;/a&gt;, &lt;a href=&quot;http://wiki.erlang-web.org/EWTS&quot; target=&quot;_blank&quot;&gt;Erlang Web Test Suite&lt;/a&gt; application bundled, multiple level request dictionary support.&lt;br /&gt;&lt;br /&gt;Apart from the above, there are also some changes worth mentioning:&lt;br /&gt;* new wpart introduced: wpart:comment&lt;br /&gt;* embedding default values in wparts from templates (patch submitted by Elena Bobrova)&lt;br /&gt;* top-down template inclusion feature&lt;br /&gt;* experimental ejabberd-flavoured e_hook introduced&lt;br /&gt;* upgraded to Yaws 1.85&lt;br /&gt;&lt;br /&gt;
&lt;div&gt;Erlang Web 1.4 can be easily downloaded as a tarball from its &lt;a href=&quot;http://www.erlang-web.org/&quot; target=&quot;_self&quot;&gt;official website&lt;/a&gt; and checked out from the &lt;a href=&quot;http://bitbucket.org/etc/erlang-web/&quot; target=&quot;_blank&quot;&gt;bitbucket&lt;/a&gt; repository. The documentation can be found on &lt;a href=&quot;http://wiki.erlang-web.org/&quot; target=&quot;_blank&quot;&gt;Erlang Web's wiki&lt;/a&gt; page. &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div&gt;We do encourage everyone to try &lt;span&gt;Erlang Web 1.4 &lt;/span&gt;out, send us comments, contribute and enjoy the coding!
 
&lt;/div&gt;</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-03-10T23:00:54+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">13 October 2009: Ready for the Erlang courses in London?</title>
		<link href="http://www.erlang-solutions.com/news/1/entry/1101"/>
		<id>http://www.erlang-solutions.com/news/1/entry/1101</id>
		<updated>2010-01-11T16:32:22+00:00</updated>
		<content type="html">Have you always wanted to learn more about Erlang, but never knew how to get started?&lt;br /&gt;
&lt;p&gt;We have a special offer, which may encourage you. If you sign up &lt;span&gt;now&lt;/span&gt; for a five-day &lt;a href=&quot;http://erlang-consulting.com/training/course/4/erlang-by-example&quot; target=&quot;_blank&quot;&gt;Erlang By Example&lt;/a&gt; or &lt;a href=&quot;http://erlang-consulting.com/training/course/6/erlang-open-telecom-platform&quot; target=&quot;_blank&quot;&gt;Erlang Open Telecom Platform&lt;/a&gt; courses in London you will get the&lt;span&gt; Early-Bird Discount of &amp;#163;245 off the standard price!&lt;/span&gt; Don't miss out and register now. &lt;br /&gt;
&lt;/p&gt;
&lt;div&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;img src=&quot;http://erlang-consulting.com/upload/images/31/early-bird.png&quot; /&gt;&lt;br /&gt;&lt;/div&gt;To see the full list of our scheduled courses, please click &lt;a href=&quot;http://www.erlang-consulting.com/../../training/schedule&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;</content>
		<author>
			<name>Erlang Training and Consulting</name>
			<uri>http://www.erlang-solutions.com/news/1</uri>
		</author>
		<source>
			<title type="html">Erlang Solutions News Feed</title>
			<subtitle type="html">Erlang Solutions</subtitle>
			<link rel="self" href="http://www.erlang-consulting.com/news_rss.xml"/>
			<id>http://www.erlang-consulting.com/news_rss.xml</id>
			<updated>2010-03-10T23:00:54+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">A Case for Orthogonality in Design</title>
		<link href="http://debasishg.blogspot.com/2010/01/case-for-orthogonality-in-design.html"/>
		<id>tag:blogger.com,1999:blog-22587889.post-3369637833619650136</id>
		<updated>2010-01-11T12:46:07+00:00</updated>
		<content type="html">In &lt;a href=&quot;http://openlibrary.org/b/OL13802743M/Learning_using_and_designing_command_paradigms&quot;&gt;Learning, using and designing command paradigms&lt;/a&gt;, John M Carroll introduces the notion of lexical congruence. When you design a language, one of the things that you do is lexicalization of the domain. If we extrapolate the concept to software designs in general, we go through the same process with our domain model. We identify artifacts or lexemes and choose to name them appropriately so that the names are congruent with the semantics of the domain. This notion of lexical congruence is the essence of having a good mnemonics for your domain language. I found the reference to Carroll's work in &lt;a href=&quot;http://dx.doi.org/10.1207/s15327051hci0402_1&quot;&gt;Testing the principle of orthogonality in language design&lt;/a&gt;, which discusses the same issue of organizing your language around an optimal set of orthogonal semantic concepts. This blog post tries to relate the same concepts of orthogonality in designing domain models using the power that the newer languages of today offers.&lt;br /&gt;&lt;br /&gt;The complexity of a modeling language depends on the number of lexemes, their congruence with the domain concepts being modeled and the number of ways you can combine them to form higher order lexemes. The more decoupled each of these lower level lexemes are, the easier they are to compose. When you have overlapping concepts being modeled as part of lexemes, the mixing is not easy. You need to squeeze in some special boundary conditions as part of composition logic. Making your concepts independent yet composable makes your design orthogonal.&lt;br /&gt;&lt;br /&gt;The first time I came across the concept of orthogonality in design and consciously appreciated the power of unification that it brings on to your model, is through Andrei Alexandrescu's idea of &lt;a href=&quot;http://loki-lib.sourceforge.net/index.php?n=Main.Policy-basedDesign&quot;&gt;policy based design&lt;/a&gt; that he evangelized in his book &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/0201704315/modecdesi-20&quot;&gt;Modern C++ Design&lt;/a&gt; and in the making of the &lt;a href=&quot;http://loki-lib.sourceforge.net/index.php?n=Main.HomePage&quot;&gt;Loki&lt;/a&gt; library. You have orthogonal policies that are themselves reusable as independent abstractions. And at the same time you can use the language infrastructure to combine them when composing your higher order model. Consider this C++ example from Andrei's book ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;T&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;CheckingPolicy&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;ThreadingModel&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;SmartPtr&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;CheckingPolicy&lt;/code&gt; enforces constraints that need to be satisfied by the pointee object. The &lt;code&gt;ThreadingModel&lt;/code&gt; abstraction defines the concurrency semantics. These two concerns are not related in any way between themselves. But you can use the power of C++ templates to plug in appropriate behaviors of these concerns when composing your own custom type of &lt;code&gt;SmartPtr&lt;/code&gt; ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;SmartPtr&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Widget&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;NoChecking&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;SingleThreaded&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;WidgetPtr&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This is &lt;i&gt;orthogonal&lt;/i&gt; design where you have a minimal set of lexemes to model otherwise unrelated concerns. And use the power of C++ templates to evolve a larger abstraction by composing them together. The policies themselves are independent and can be applied to construct arbitrary families of abstraction.&lt;br /&gt;&lt;br /&gt;The crux of the idea is that you have m concepts that you can use with n types. There's no static relationship between the concepts and the types - that's what makes orthogonality an extensible concept. Consider Haskell typeclasses ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Eq&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;a&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;a&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;a&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The above typeclass defines the concept of equality. It's parameterized on the type and defines the constraint that the type as to define an equality operator in order to qualify itself as an instance of the &lt;code&gt;Eq&lt;/code&gt; typeclass. The actual type is left open which gives the typeclass an unbounded extensibility. &lt;br /&gt;&lt;br /&gt;For integers, we can do &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Eq&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;x&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;y&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;x&amp;nbsp;`integerEq`&amp;nbsp;y&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;For floats we can have ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Eq&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Float&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;x&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;y&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;x&amp;nbsp;`floatEq`&amp;nbsp;y&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;We can define &lt;code&gt;Eq&lt;/code&gt; even for any custom data type, even recursive types like &lt;code&gt;Tree&lt;/code&gt; ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Eq&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;a&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Eq&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;a&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Leaf&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;a&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Leaf&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;b&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;a&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;b&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Branch&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;l1&amp;nbsp;r1&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Branch&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;l2&amp;nbsp;r2&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;l1&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;l2&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;r1&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;r2&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;_&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;_&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Haskell typeclasses, like C++ templates help implement orthogonality in abstractions through a form of parametric polymorphism. Programming languages offer facilities to promote orthogonal modeling of abstractions. Of course the power varies depending on the power of abstraction that the language itself offers.&lt;br /&gt;&lt;br /&gt;Let's consider a real world scenario. We have an abstraction named &lt;code&gt;Address&lt;/code&gt; and modeled as a case class in Scala ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;street&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;city&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;state&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;zip&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;There can be many contexts in which you would like to use the &lt;code&gt;Address&lt;/code&gt; abstraction. Consider printing of labels for shipping that needs your address to be printed in some specific label format, as per the following trait ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;trait&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;LabelMaker&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;toLabel&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Note that printing addresses in the form of labels is not one of the primary concerns of your Address abstraction. Hence it makes no sense to model it as one of the methods of the class. It's only required that in some situations we may need to use the &lt;code&gt;Address&lt;/code&gt; to print itself in the form of a label as per the specification mandated by &lt;code&gt;LabelMaker&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;One other concern is sorting. You may need to have your addresses sorted based on zip code before submitting them to your Printer module for shpping. Sorting may be required in combination with label printing or as well as on its own - these two are orthogonal concerns that should never have any dependence amongst themselves within your abstraction.&lt;br /&gt;&lt;br /&gt;Depending on your use case, you can decide to compose your &lt;code&gt;Address&lt;/code&gt; abstraction as &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;houseNo&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;street&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;city&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;state&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;zip&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Ordered&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;LabelMaker&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//..&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;which makes your &lt;code&gt;Address&lt;/code&gt; abstraction statically coupled with the other two.&lt;br /&gt;&lt;br /&gt;Or you may like to make the composition based on individual objects which would keep the base abstraction independent of any static coupling.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;a&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(..)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;LabelMaker&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;override&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;toLabel&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_comment&quot;&gt;//..&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;As an alternative you can also choose to implement implicit conversions from &lt;code&gt;Address&lt;/code&gt; using Scala views ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&quot;java_keyword&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;implicit&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;AddressToLabelMaker&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_type&quot;&gt;LabelMaker&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_keyword&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;toLabel&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_literal&quot;&gt;&amp;quot;%d-%s,&amp;nbsp;%s,&amp;nbsp;%s-%s&amp;quot;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;addr&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;houseNo&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;addr&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;street&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;addr&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;addr&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;addr&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_separator&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;java_plain&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Whatever be the implementation, take note of the fact that we are not polluting the basic &lt;code&gt;Address&lt;/code&gt; abstraction with the concerns that are orthogonal to it. Our model, which is the design language treats orthogonal concerns as separate lexemes and encourages ways to compose them non invasively by the user.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/22587889-3369637833619650136?l=debasishg.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Debasish</name>
			<email>ghosh.debasish@gmail.com</email>
			<uri>http://debasishg.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Ruminations of a Programmer</title>
			<subtitle type="html">A programmer's blog - will deal with everything that relates to a programmer. Occasionally, it will contain some humour, some politics and some sport news.</subtitle>
			<link rel="self" href="http://debasishg.blogspot.com/feeds/posts/default?alt=rss"/>
			<id>tag:blogger.com,1999:blog-22587889</id>
			<updated>2010-03-04T07:15:02+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">pm</title>
		<link href="http://parijatmishra.wordpress.com/2010/01/08/188/"/>
		<id>http://parijatmishra.wordpress.com/?p=188</id>
		<updated>2010-01-07T18:46:35+00:00</updated>
		<content type="html">&lt;p&gt;Apparently there is going to be a revolution in the software development world, backed by some very illustrious names in the industry.  In the &lt;a href=&quot;http://ivarblog.com/2009/12/18/semat-software-engineering-method-and-theory-a-call-for-action-3/&quot;&gt;words of Ivar Jacobson&lt;/a&gt;, one of the people behind it:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;We are some people who have observed software engineering theory and practice of the past decades and have realized that it is now time to revitalize this discipline. We have been quietly planning a “revolution”.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;And here is the &amp;#8220;Call for Action&amp;#8221; statement for this revolution (&lt;a href=&quot;http://www.semat.org/bin/view&quot;&gt;called SEMAT &amp;#8212; Software Engineering Method and Theory&lt;/a&gt;):&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Software engineering is gravely hampered today by immature practices. Specific problems include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The prevalence of fads more typical of fashion industry than of an engineering discipline.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The lack of a sound, widely accepted theoretical basis.&lt;/li&gt;
&lt;li&gt;The huge number of methods and method variants, with differences little understood and artificially magnified.&lt;/li&gt;
&lt;li&gt;The lack of credible experimental evaluation and validation.&lt;/li&gt;
&lt;li&gt;The split between industry practice and academic research.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We support a process to refound software engineering based on a solid theory, proven principles and best practices that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Include a kernel of widely-agreed elements, extensible for specific uses&lt;/li&gt;
&lt;li&gt;Addresses both technology and people issues&lt;/li&gt;
&lt;li&gt;Are supported by industry, academia, researchers and users&lt;/li&gt;
&lt;li&gt;Support extension in the face of changing requirements and technology&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;The list of signatories to the &amp;#8220;revolution&amp;#8221; is quite impressive. See for your self on their web page. Sounds good? But not everyone agrees, as you can see &lt;a href=&quot;http://catenary.wordpress.com/2009/11/29/against-semat/&quot;&gt;on this blog&lt;/a&gt;. The author of the blog has an issue with the very framing of the problem:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;But this is an entirely misguided movement. Let’s analyze the call for action, bit by bit. It begins:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;Software engineering&lt;/em&gt; is gravely hampered today by immature practices. [...]&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;[...]&lt;/p&gt;
&lt;p&gt;Never mind that people in the community (most prominently Tom DeMarco) have spoken against this paradigm, or that software development has little to do with most established engineering disciplines: the people behind SEMAT have chosen to ignore these criticisms and move on.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Fair enough. This critique reminds me of this &lt;a href=&quot;http://www.bobbemer.com/DAVINCI.HTM&quot;&gt;really old paper, called &amp;#8220;Masterpiece Engineering&amp;#8221;&lt;/a&gt; that you might have heard of. Apparently, there were people doubting whether software development is really engineering even when the term was &lt;a href=&quot;http://homepages.cs.ncl.ac.uk/brian.randell/NATO/NATOReports/index.html&quot;&gt;first coined circa 1968&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But what interests me is this statement by SEMAT:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;The prevalence of fads more typical of fashion industry than of an engineering discipline.&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;So if Software Engineering is not engineering, could it be &lt;em&gt;fashion&lt;/em&gt;? Let&amp;#8217;s see. Here are my observations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Formal study&lt;/strong&gt;: (a) Electrical Engineer: formal degree required; (b) Software Engineer: formal degree not required; (c) Fashion Designer: formal degree not required&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Work&lt;/strong&gt;: Engineers: work hard; (b) Software developers: work harder; (c) Fashion Designers: while they are apprentices, work their ass off; as soon as they &amp;#8220;become&amp;#8221; a designer, stop calling it work and start calling it art; the amount of work/art that needs to be done everyday is inversely proportional to how good you are considered&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Respect&lt;/strong&gt;: (a) Electrical Engineer: gets some respect from the people who work for him, for his knowledge; gets respect from people he works for (the &amp;#8220;business folks&amp;#8221;) only if he can keep the cost low; (b) Software Engineer: gets no respect from anyone, including the janitor services, unless he accidentally makes some money from a dot.com IPO; (c) Fashion Designer: gets respected both by people who work for him, and people who he works for, directly proportional to how much he/she is exploiting them&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fame&lt;/strong&gt;: (a) Electrical Engineer: not famous, with rare exceptions of people who have managed to make something that has the astonishing capability of being really appealing to customers and their company&amp;#8217;s marketing department at the same time; (b) Software Engineer: not famous as long as they are doing the right thing; you need to write a worm that brings down the &amp;#8216;net to be famous and maybe not even then (c) Fashion Designer: often famous, especially if the product simultaneously manages to be feckless (you don&amp;#8217;t know whether its a skirt or a bandanna) and useless (does not cover the body)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Discipline&lt;/strong&gt;: (a) Electrical Engineer: practices great discipline in work; (b) Software Engineer: is expected to work with discipline during office hours and continue to work with passion until midnight; (c) Fashion Designer: discipline is death!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Creativity&lt;/strong&gt;: (a) Electrical Engineer: as his experience grows, tries his hand at more creative things; (b) Software Engineer: to start with, because he does not know much yet, everyone around is too busy to teach, there is no training budget, and anyway the product has to ship by month end with no time to learn anything, &lt;em&gt;has to be creative by using the only tool he know to do everything&lt;/em&gt;; only after gaining much experience can he stop being creative and actually do thing properly; (c) Fashion Designer: your creativity is defined to be inversely proportional to how many people can afford your clothes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, from the above, it is clear, fad or no fad, a Software Engineer&amp;#8217;s life is nothing like a Fashion Designer&amp;#8217;s.  It is also not like an Electrical Engineer&amp;#8217;s.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt;: while I have a Bachelors and Master degree in Electrical Engineering, and I have been developing software professionally for some time now, my profound knowledge of the fashion industry is gained entirely from the movie &lt;em&gt;The Devil Wears Prada&lt;/em&gt;.&lt;/p&gt;
&lt;br /&gt; Tagged: controversy &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/parijatmishra.wordpress.com/188/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/parijatmishra.wordpress.com/188/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/parijatmishra.wordpress.com/188/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/parijatmishra.wordpress.com/188/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/parijatmishra.wordpress.com/188/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/parijatmishra.wordpress.com/188/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/parijatmishra.wordpress.com/188/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/parijatmishra.wordpress.com/188/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/parijatmishra.wordpress.com/188/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/parijatmishra.wordpress.com/188/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=parijatmishra.wordpress.com&amp;blog=3282491&amp;post=188&amp;subd=parijatmishra&amp;ref=&amp;feed=1&quot; /&gt;</content>
		<author>
			<name>Parijat's Weblog</name>
			<uri>http://parijatmishra.wordpress.com</uri>
		</author>
		<source>
			<title type="html">Parijat's Weblog</title>
			<subtitle type="html">of cabbages and kings</subtitle>
			<link rel="self" href="http://parijatmishra.wordpress.com/feed/"/>
			<id>http://parijatmishra.wordpress.com/feed/</id>
			<updated>2010-03-03T04:01:16+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Thoughts on process hierarchies in Haskell.</title>
		<link href="http://jlouisramblings.blogspot.com/2010/01/thoughts-on-process-hierarchies-in.html"/>
		<id>tag:blogger.com,1999:blog-5411139659011156551.post-621239437930874200</id>
		<updated>2010-01-05T12:50:22+00:00</updated>
		<content type="html">&lt;div id=&quot;on-process-hierachies&quot;&gt;&lt;h1&gt;On Process Hierachies&lt;/h1&gt;&lt;p&gt;I have been in thinking mode the last couple of days. It all started when I decided to look at the problem of &lt;em&gt;wrong&lt;/em&gt; in haskell-torrent. What will happen when something fails? Joe Armstrong has part of the answer by arguing that we must proactively expect a process to fail and then let some other process clean it up (paraphrased a lot by me, these are not his exact words).&lt;/p&gt;&lt;p&gt;Take a look at this image,&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://4.bp.blogspot.com/_ZmTZzIup5tY/S0OkTpVs7TI/AAAAAAAAACA/h9WjWJahvMI/s1600-h/PHierachy.png&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;http://4.bp.blogspot.com/_ZmTZzIup5tY/S0OkTUntJBI/AAAAAAAAAB4/lXdYFk27S4s/s1600-h/processes.png&quot;&gt;&lt;img src=&quot;http://4.bp.blogspot.com/_ZmTZzIup5tY/S0OkTUntJBI/AAAAAAAAAB4/lXdYFk27S4s/s320/processes.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5423359028143924242&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;It is a &lt;a href=&quot;http://en.wikipedia.org/wiki/Hypergraph&quot;&gt;hypergraph&lt;/a&gt; where each vertex corresponds to a process and each edge corresponds to an channel. The graph is undirected because in principle each process can both send and receive on the channel in question. In practice however, one can limit the communication as some processes will only transmit on a channel, and others will only receive (and some will do both).&lt;/p&gt;&lt;p&gt;To simplify the graph, I omit local RPC channels. It is customary to implement RPC by creating a local channel and transmitting that channel over one of the hypergraph edges. Response can then work directly on the local channel, simplifying the problem of giving &lt;em&gt;identity&lt;/em&gt; to processes in many cases.&lt;/p&gt;&lt;div id=&quot;termination&quot;&gt;&lt;h2&gt;Termination&lt;/h2&gt;&lt;p&gt;A somewhat scary part of such a network is what happens when we want to terminate it or if something goes wrong in one of the processes. In particular, we have the problem that while Haskell is a pure, nice, protected Nirvana — the real world inside IO is a dank, dark place of twisted little passages (all alike). Thus it might very well be that we get to experience an exception first-hand in one of the above processes.&lt;/p&gt;&lt;p&gt;I have toyed with the idea of copying the excellent CHP library by Neil Brown. Neil defines a concept of &lt;em&gt;poison&lt;/em&gt; for channels. A channel that has been poisoned will always transmit poison. Poison thus propagates through the hypergraph and slowly but surely kills off each process. Neil has a description of the process &lt;a href=&quot;http://chplib.wordpress.com/2009/09/30/poison-concurrent-termination/&quot;&gt;on his blog&lt;/a&gt;. I like the idea because it uses the existing infrastructure of the hypergraph. It would be fairly easy to add support for writing poison handlers at each node.&lt;/p&gt;&lt;/div&gt;&lt;div id=&quot;process-hierachies&quot;&gt;&lt;h2&gt;Process Hierarchies&lt;/h2&gt;&lt;p&gt;I have pondered on a different scheme for the last couple of days however. We can impose a &lt;em&gt;location graph&lt;/em&gt; on the hypergraph above:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://4.bp.blogspot.com/_ZmTZzIup5tY/S0OkTpVs7TI/AAAAAAAAACA/h9WjWJahvMI/s1600-h/PHierachy.png&quot;&gt;&lt;img src=&quot;http://4.bp.blogspot.com/_ZmTZzIup5tY/S0OkTpVs7TI/AAAAAAAAACA/h9WjWJahvMI/s320/PHierachy.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5423359033705557298&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This graph, a tree, describes the location or hierarchy of the processes in question. The processes named S0, S1, … and so forth are &lt;em&gt;supervisors&lt;/em&gt;. Their responsibility is only one: Keep their children running according to a &lt;em&gt;policy&lt;/em&gt;. Erlang programmers fluent in the OTP high level libraries present in the Erlang distribution will recognize the supervisor term.&lt;/p&gt;&lt;p&gt;A normal (&lt;em&gt;worker&lt;/em&gt;) process has two rules:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If the process terminates, it must inform its supervisor.&lt;/li&gt;&lt;li&gt;If the process gets an asynchronous KillThread exception, it &lt;em&gt;must&lt;/em&gt; die.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;A supervisor process needs to obey the following scheme:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;If a process under its supervision dies it must take affair according to its policy. This may mean that it kills off all other children and reports back to its supervisor for instance. Or it may mean that it simply restarts the process that got killed. What happens is dependent on the policy we configured the supervisor with.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;If a supervisor is asked to shutdown by a KillThread exception, it must first kill all of its children.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Note that with these rules, termination is almost free: Terminate the tree. Because everything is linked to the tree, termination will happen. We will terminate by asynchronous exceptions aggressively.&lt;/p&gt;&lt;p&gt;An interesting difference from Erlang is that of communication, which is a certain sense is Dual in Haskell+CML: In Erlang, the process id is what you need to hold in order to transmit an (async.) message to the process. In our CML-based system the &lt;em&gt;channel&lt;/em&gt; is the name you must hold in order to communicate. In other words, this lets us, in some circumstances, replace the process with a new one but keeping the channel. Note, though, that the interface is not completely clean: if the Haskell runtime figures out a thread is indefinitely blocked, it will in general throw an exception — but I have not yet read the CML code in detail so I do not know if this will happen. It depends on what MVar references a channel hold.&lt;/p&gt;&lt;/div&gt;&lt;div id=&quot;another-view&quot;&gt;&lt;h2&gt;Another view&lt;/h2&gt;&lt;p&gt;The hypergraph and location graph constitutes what is sometimes called a &lt;em&gt;Bigraph&lt;/em&gt;. This is not to be confused with the term Bi&lt;em&gt;partite&lt;/em&gt; graph which is a completely different term but sometimes also called a bigraph unfortunately. I somewhat resist the idea to use the same term for different concepts, but &lt;a href=&quot;http://www.itu.dk/~mikkelbu/research/bigraphsbib/index.html&quot;&gt;work&lt;/a&gt; done in this twi-graph concept presented in this post on &lt;a href=&quot;http://www.itu.dk/research/pls/wiki/index.php/A_Brief_Introduction_To_Bigraphs&quot;&gt;bigraphs&lt;/a&gt; suggests that the term is quite used in this respect.&lt;/p&gt;&lt;p&gt;The research seems different from what I need however. &lt;a href=&quot;http://www.itu.dk/&quot;&gt;ITU&lt;/a&gt; has done extensive research in bigraphical programming languages, letting them describe various known calculi (Lambda, Pi, etc.). I just want to use the descriptive power of the bigraphs to discriminate &lt;em&gt;location&lt;/em&gt; from &lt;em&gt;communication&lt;/em&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;So to conclude: Does that give anybody out there a brilliant idea or does my design have an inherent flaw I should be aware of? If not, I'll probably try to sketch some code in Haskell for the Supervisor tree and processes.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/5411139659011156551-621239437930874200?l=jlouisramblings.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Jlouis</name>
			<email>noreply@blogger.com</email>
			<uri>http://jlouisramblings.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">JLOUIS Ramblings</title>
			<subtitle type="html">Musings of a mathematically oriented Computer Scientist. Anything that tickles my brain might go in here, be it Computer Science, mathematics, society, relationships, sex, 0xf00d, or pets.</subtitle>
			<link rel="self" href="http://jlouisramblings.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-5411139659011156551</id>
			<updated>2010-03-10T18:31:55+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">ProcessOne, a year in review</title>
		<link href="http://www.process-one.net/en/blogs/article/processone_a_year_in_review/"/>
		<id>tag:process-one.net,2010:en/blogs/3.2151</id>
		<updated>2010-01-04T14:24:13+00:00</updated>
		<content type="html">&lt;p&gt;At ProcessOne, we wanted to wish you all a very happy 2010 year. To give you a good sense of all what has been accomplished, we have written this small review of the 2009 year at ProcessOne. We hope you will enjoy the reading.&lt;/p&gt; &lt;h2&gt;Software&lt;/h2&gt;
&lt;p&gt;First, we have released &lt;a href=&quot;http://www.process-one.net/en/ejabberd/&quot;&gt;ejabberd&lt;/a&gt; 2.0.3 to 2.0.5, and we finally made it with ejabberd 2.1 (with its bugfix 2.1.1). It has received much scalability improvements, as well as a big PubSub boost. Even more changes have made it an even more rock-solid and featureful real-time server. A STUN server has been added in ejabberd, for multimedia purposes. The version 3.0 is in the works, based on the opensource exmpp library, freshly released this year also.&lt;/p&gt;
&lt;p&gt;On the desktop, &lt;a href=&quot;http://www.process-one.net/en/blogs/article/onechannel_a_desktop_publish_subscribe_client_for_instant_news_delivery/&quot;&gt;OneChannel&lt;/a&gt;, the PubSub client working on AIR, has been released, optionally using the &lt;a href=&quot;http://xmpp-sandbox.org/&quot;&gt;xmpp-sandbox.org&lt;/a&gt; preconfigured real-time feeds.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.process-one.net/en/solutions/imgateways/&quot;&gt;Our gateway packaging&lt;/a&gt; is stable, scalable and works pretty well, covering Microsoft Live Messenger, Yahoo! IM, AIM and ICQ, XMPP, and also non-IM systems, like Twitter and Wave gateway.&lt;/p&gt;
&lt;p&gt;On the mobile front, &lt;a href=&quot;http://www.process-one.net/en/solutions/oneteam_iphone/&quot;&gt;OneTeam for iPhone&lt;/a&gt;, the mobile XMPP client, has been released in versions 2.1, 3.0, 3.1, and 3.2, and we believe it is the best XMPP client out there, with room for improvements and innovations in the coming year.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.process-one.net/en/blogs/article/oneweb_demonstrates_the_power_of_xmpp_inside_the_browser/&quot;&gt;OneWeb&lt;/a&gt;, the extension for Firefox, has been released as an alpha product, &lt;a href=&quot;http://www.process-one.net/en/blogs/article/oneweb_works_on_firefox_mobile/&quot;&gt;with a Fennec port&lt;/a&gt; (Firefox mobile). It basically adds data sync and remote control between browsers, demoing the power of XMPP in the browser.&lt;/p&gt;
&lt;p&gt;Our supervision console &lt;a href=&quot;http://www.process-one.net/fr/solutions/teamleader/&quot;&gt;TeamLeader&lt;/a&gt; has had many improvements in 2009 and is now clean and efficient, being deployed on large customer projets.&lt;/p&gt;
&lt;p&gt;Our XMPP desktop client &lt;a href=&quot;http://www.process-one.net/fr/solutions/oneteam/&quot;&gt;OneTeam&lt;/a&gt; for Firefox has become a strong client and should become a major component in our offering in 2010.&lt;/p&gt;
&lt;p&gt;We also are offering a module for the APNS, or Apple Push Notifications Service, for the iPhones.&lt;/p&gt;
&lt;h2&gt;Announced&lt;/h2&gt;
&lt;p&gt;We have announced and demoed the OneTeam Media Server, our Flash server implementation, acting as a media relay and much more, for multimedia applications.&lt;/p&gt;
&lt;p&gt;The ProcessOne Wave Server is in the work, gaining features and improving fast. A demo on Tkabber has been done, showing very basic client/server interactions, like create a wavelet, join and edit it, the basics of collaborative real-time editing of a text document.&lt;/p&gt;
&lt;p&gt;Our OCS Bridge enables a real federation of ejabberd servers with the Microsoft's IM+VoIP corporate servers, while this one only painfully offers gateways to XMPP since this year.&lt;/p&gt;
&lt;h2&gt;Services&lt;/h2&gt;
&lt;p&gt;We have given birth to a number of services:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We have opened the &lt;a href=&quot;http://www.process-one.net/en/labs/&quot;&gt;ProcessOne Labs&lt;/a&gt;, showing all our non-production ready, but promising products.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://hosted.im/&quot;&gt;Hosted.IM&lt;/a&gt; offers for XMPP hosting services for small businesses.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.process-one.net/en/imstore/&quot;&gt;IMstore&lt;/a&gt; enables customers to buy products and services, the fast and easy way, on the web via a simple form.&lt;/li&gt;
&lt;li&gt;The APNS, or Apple Push Notifications Services, runs on our infrastructure for OneTeam for iPhone clients using our &lt;a href=&quot;http://oneteam.im/&quot;&gt;OneTeam.IM&lt;/a&gt; and &lt;a href=&quot;http://talkr.im/&quot;&gt;Talkr.IM&lt;/a&gt; services.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://tweet.im/&quot;&gt;Tweet.IM&lt;/a&gt; is a XMPP to Twitter gateway, offering nice features like delivery modes.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://xmpp-sandbox.org/&quot;&gt;xmpp-sandbox.org&lt;/a&gt; is the XMPP service for developers.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://talkr.im/&quot;&gt;Talkr.IM&lt;/a&gt; is our XMPP service for the masses.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Events, Talks &amp;amp; Articles&lt;/h2&gt;
&lt;p&gt;Here are the places where we have been, and what has been said about us:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In December, we have organized the &lt;a href=&quot;http://www.process-one.net/seabeyond/&quot;&gt;Sea Beyond&lt;/a&gt; event, for real-time communications.&lt;/li&gt;
&lt;li&gt;The concept of &lt;a href=&quot;http://www.process-one.net/en/blogs/article/real-time_web_real-time_search_no_it_is_war/&quot;&gt;&quot;Web Augmented Reality&quot;&lt;/a&gt; came to birth.&lt;/li&gt;
&lt;li&gt;A &lt;a href=&quot;http://www.process-one.net/en/imtrends/article/strategic_guide_instant_messaging_and_security/&quot;&gt;Strategic Guide to Instant Messaging and Security&lt;/a&gt; has been published.&lt;/li&gt;
&lt;li&gt;Facebook has been caught &lt;a href=&quot;http://www.process-one.net/en/blogs/article/facebook_chat_supports_xmpp_with_ejabberd/&quot;&gt;working on XMPP with ejabberd&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;id Software's QuakeLive online game is using &lt;a href=&quot;http://www.process-one.net/en/blogs/article/idsoftware_quakelive_service_uses_xmpp/&quot;&gt;ejabberd for its ingame chat infrastructure&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Micka&amp;euml;l R&amp;eacute;mond went to Mobile World Congress, Erlang Factory in San Jose and London, XMPP Summit in Brussel and Palo Alto, Erlang User Conference in Stockholm, Le Web in Paris.&lt;/li&gt;
&lt;li&gt;We have been covered by &lt;a href=&quot;http://www.process-one.net/en/blogs/article/datamonitor_coverage/&quot;&gt;Datamonitor&lt;/a&gt; and &lt;a href=&quot;http://gigaom.com/2009/11/05/facebook-xmpp-adium-chat/&quot;&gt;Giga OM&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The series &quot;Scalable XMPP bots&quot; has been published, promoting the use of exmpp (&lt;a href=&quot;http://www.process-one.net/en/blogs/article/scalable_xmpp_bots_with_erlang_and_exmpp_part_i/&quot;&gt;I&lt;/a&gt;, &lt;a href=&quot;http://www.process-one.net/en/blogs/article/scalable_xmpp_bots_with_erlang_and_exmpp_part_ii/&quot;&gt;II&lt;/a&gt;, &lt;a href=&quot;http://www.process-one.net/en/blogs/article/scalable_xmpp_bots_with_erlang_and_exmpp_part_iii/&quot;&gt;III&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Roadmap 2010&lt;/h2&gt;
&lt;p&gt;In 2010, our focus will be mainly on the following points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://hosted.im/&quot;&gt;Hosted.IM&lt;/a&gt; will be offering new simple and extendable services.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.process-one.net/fr/solutions/oneteam/&quot;&gt;OneTeam&lt;/a&gt; for Firefox will be released, with WAR (Web Augmented Reality), and much more innovative features.&lt;/li&gt;
&lt;li&gt;ejabberd will become more industrial, with 3.0 getting to production ready state, better TeamLeader support, good test suite coverage and more modules on the IMstore.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://talkr.im/&quot;&gt;Talkr.IM&lt;/a&gt; will offer the seamless migration from/to another XMPP service.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;It has been a busy year, with many achievements, much of which we cannot talk about, or we have just forgotten. But the coming year 2010 will be even more exciting.&lt;/p&gt;</content>
		<author>
			<name>Nicolas Vérité</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:03:03</id>
			<updated>2010-03-04T09:46:36+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry>
		<title type="html">Pragmatics of Impurity</title>
		<link href="http://debasishg.blogspot.com/2010/01/pragmatics-of-impurity.html"/>
		<id>tag:blogger.com,1999:blog-22587889.post-1620983432336061847</id>
		<updated>2010-01-04T11:51:59+00:00</updated>
		<content type="html">James Hague, a long time Erlanger, drives home a point or two regarding purity of paradigms in a couple of his latest &lt;a href=&quot;http://prog21.dadgum.com/54.html&quot;&gt;blog&lt;/a&gt; &lt;a href=&quot;http://prog21.dadgum.com/55.html&quot;&gt;posts&lt;/a&gt;. Here's his take on being effective with &lt;i&gt;pure&lt;/i&gt; functional languages ..&lt;br /&gt;&lt;br /&gt;&lt;cite&gt;&quot;My real position is this: 100% pure functional programing doesn't work. Even 98% pure functional programming doesn't work. But if the slider between functional purity and 1980s BASIC-style imperative messiness is kicked down a few notches--say to 85%--then it really does work. You get all the advantages of functional programming, but without the extreme mental effort and unmaintainability that increases as you get closer and closer to perfectly pure.&quot;&lt;/cite&gt;&lt;br /&gt;&lt;br /&gt;Purity is not necessarily pragmatic. In my last blog &lt;a href=&quot;http://link.com&quot;&gt;post&lt;/a&gt; I also tangentially touched upon the notion of purity while discussing how a *hybrid* model of SQL-NoSQL database stack can be effective for large application deployments. Be it with programming languages or with databases or any other paradigms of computation, we need to have the right balance of purity and pragmatism.&lt;br /&gt;&lt;br /&gt;Clojure introduced &lt;a href=&quot;http://clojure.org/transients&quot;&gt;transients&lt;/a&gt;. Rich Hickey says in the rationale .. &lt;cite&gt;&quot;If a pure function mutates some local data in order to produce an immutable return value, is that ok?&quot;&lt;/cite&gt;. Transients in Clojure allow localized mutation in initializing or transforming a large persistent data structure. This mutation will only be seen by the code that does the transformation - the client gets back a version for immutable use that can be shared. In no way does this invalidate the benefits that immutability brings in reasoning of Clojure programs. It's good to see Rich Hickey being flexible and pragmatic at the expense of injecting that little impurity into his creation.&lt;br /&gt;&lt;br /&gt;Just like the little compromise (and big pragmatism) with the purity of persistent data structures, Clojure also made a similar compromise with laziness by introducing &lt;a href=&quot;http://www.infoq.com/news/2009/12/clojure-11-rc1-transients&quot;&gt;chunked sequences&lt;/a&gt; that optimize the overhead associated with lazy sequences. These are design decisions that have been taken consciously by the creator of the language that values pragmatism over purity.&lt;br /&gt;&lt;br /&gt;Enough has already been said about the virtues of purity in functional languages. Believe me, 99% of the programming world does not even care for purity. They do what works best for them and hybrid languages are mostly the ones that find the sweetest spots. Clojure is as impure as Scala is, considering the fact that both allow side-effecting with mutable references and uncontrolled IO. Even Erlang has uncontrolled IO and a mutable process dictionary, though its use is often frowned upon within the community. The important point is that all of them have proved to be useful to programmers at large.&lt;br /&gt;&lt;br /&gt;Why do creators infuse impurity into their languages ? Why aren't every language created as pure as Haskell is ? Well, it's mostly related to a larger thought that the language often targets to. Lisp started as an incarnation of the lambda calculus under the tutelage of John McCarthy and became the first significant language promoting the purely applicative model of programming without side-effects. Later on it added the impurities of mutation constructs based on the von Neumann architecture of the machines where Lisp was implemented. The obvious reason was to get an improved performance over purely functional constructs. Scala and Clojure both decided to go for the JVM as the primary runtime platform - hence both languages are susceptible to the pitfalls of impurity that JVM offers. Both of them decided to inherit all the impurities that Java has.&lt;br /&gt;&lt;br /&gt;Consider the module system of Scala. You can compose modules using traits with deferred concrete definitions of types and objects. You can even compose mutually recursive modules using lazy vals, somewhat similar to what Newspeak and some dialects of ML offer. But because you have decided to bite the Java pill, you can also wreak havoc through shared mutable state at the top level object that you compose. In his post titled &lt;a href=&quot;http://gbracha.blogspot.com/2009/06/ban-on-imports.html&quot;&gt;A Ban on Imports&lt;/a&gt; Gilad Bracha discusses all evil effects that an accessible global namespace can bring to the modularity aspects of your code. Newspeak is being designed as &lt;i&gt;pure&lt;/i&gt; in this respect, with all dependencies being abstract and need to be plugged together explicitly as part of configuring the module. Scala is impure in this respect, allows imports to bring in the world on to your module definitions, but at the same time opens up all possibilities of sharing the huge ecosystem that the Java community has built over the years. You can rightfully choose to be pure in Scala, but that's not enforced by the language.&lt;br /&gt;&lt;br /&gt;When we talk about impurity in languages, it's mostly related to how it handles side-effects and mutable state. And Haskell has a completely different take on this aspect than what we discussed with Lisp, Scala or Clojure. You have to use monads in Haskell towards any side-effecting operation. And people with a taste for finer things in life are absolutely fine with that. You cannot just stick in a printf to your program for debugging. You need to return the whole stuff within an IO monad and then do a print. The Haskell philosophy looks at a program as a model of mathematical functions where side-effects are also implemented in a functional way. This makes reasoning and optimization by the compiler much easier - you can make your pure Haskell code run as fast as C code. But you need to think differently. Pragmatic ? What do you think ?&lt;br /&gt;&lt;br /&gt;Gilad Bracha is &lt;a href=&quot;http://gbracha.blogspot.com/2010/01/avarice-and-sloth.html&quot;&gt;planning&lt;/a&gt; to implement pure subsets of Newspeak. It will be really exciting to get to see languages which are pure, functional (note: not purely functional) and object-oriented at the same time. He observes in his post that &lt;cite&gt;(t)he world is slowly digesting the idea that object-oriented and functional programming are not contradictory concepts. They are orthogonal, and can be arranged to be rather complementary&lt;/cite&gt;. This is an interesting trend where we can see families of languages built around the same philosophy but differing in aspects of purity. You need to be pragmatic to choose and even mix them depending on your requirements.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/22587889-1620983432336061847?l=debasishg.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Debasish</name>
			<email>ghosh.debasish@gmail.com</email>
			<uri>http://debasishg.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Ruminations of a Programmer</title>
			<subtitle type="html">A programmer's blog - will deal with everything that relates to a programmer. Occasionally, it will contain some humour, some politics and some sport news.</subtitle>
			<link rel="self" href="http://debasishg.blogspot.com/feeds/posts/default?alt=rss"/>
			<id>tag:blogger.com,1999:blog-22587889</id>
			<updated>2010-03-04T07:15:02+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Erlang Quick Tip: The user_default module</title>
		<link href="http://medevyoujane.com/blog/2010/1/3/erlang-quick-tip-the-user_default-module.html"/>
		<id>http://medevyoujane.com/blog/2010/1/3/erlang-quick-tip-the-user_default-module.html</id>
		<updated>2010-01-03T15:09:38+00:00</updated>
		<content type="html" xml:lang="en-US">&lt;p&gt;If you are anything like me you spend a lot of your time in the erlang shell debuging and testing your code. And some commands are used more than others but they may be a bit on the long side and you may make regular errors while typing it. One of these wonderful functions is &lt;code&gt;make:all([load]).&lt;/code&gt; that will compile using your Emakefile and then magically reload the newly compiled modules into the running shell. What I reglarly do is to type &lt;em&gt;load&lt;/em&gt; instead of &lt;em&gt;[load]&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Enter the &lt;em&gt;user_default&lt;/em&gt; module. Any function defined in the user defined &lt;em&gt;user_default&lt;/em&gt; module or in the Erlang defined &lt;em&gt;shell_default&lt;/em&gt; module will be allowed to run without typing in the module name. One of these functions that you may use often is the &lt;code&gt;c(module\_name).&lt;/code&gt; function. First start by creating a directory for your utility modules. I like having it in the &lt;em&gt;~/.ebin/&lt;/em&gt; diretory. Now add that direcory to the code path by opening or creating the file &lt;em&gt;~/.erlang&lt;/em&gt; and inserting this line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;code:add_pathz(&quot;/Users/username/.ebin&quot;).
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create your &lt;em&gt;user_default.erl&lt;/em&gt; file and but in the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;-module (user_default).
-export ([sync/0]).

%% Compiles all files in Emakefile and load into current shell.
sync() -&amp;gt;
  make:all([load]).
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then compile it with &lt;code&gt;erlc user_default.erl&lt;/code&gt; and start an Erlang shell. Now inside a project you can run &lt;code&gt;sync().&lt;/code&gt; and it will recompile and load you project.&lt;/p&gt;

&lt;p&gt;For those interested I will put up my &lt;em&gt;~/.ebin&lt;/em&gt; code up at &lt;a href=&quot;http://github.com/JonGretar/erlang_user_utilities&quot;&gt;github.com/JonGretar/erlang_user_utilities&lt;/a&gt;. Please fork and make your own changes and share with the world.&lt;/p&gt;</content>
		<author>
			<name>Jón Grétar Borgþórsson</name>
			<uri>http://medevyoujane.com/blog/</uri>
		</author>
		<source>
			<title type="html">Me Dev, You Jane - Erlang</title>
			<subtitle type="html">Blog</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/MeDevYouJane/Erlang"/>
			<id>http://medevyoujane.com/blog/</id>
			<updated>2010-03-10T20:45:37+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Fun with the CouchDB _changes feed and RabbitMQ.</title>
		<link href="http://www.joeandmotorboat.com/2010/01/01/fun-with-the-couchdb-_changes-feed-and-rabbitmq/"/>
		<id>http://www.joeandmotorboat.com/?p=962</id>
		<updated>2010-01-01T23:14:01+00:00</updated>
		<content type="html">&lt;p&gt;I was recently &lt;a href=&quot;http://ozmm.org/posts/2009_open_source_top_ten.html&quot;&gt;introduced&lt;/a&gt; to &lt;a href=&quot;http://github.com/brianmario/yajl-ruby&quot;&gt;yajl-ruby&lt;/a&gt;, ruby bindings to the C based yajl json parsing/encoding libraries. After discovering that it can parse HTTP streams it seemed like it would be a perfect fit for use with &lt;a href=&quot;http://couchdb.apache.org/&quot;&gt;CouchDB&lt;/a&gt;. A while back I wrote &lt;a href=&quot;http://www.joeandmotorboat.com/2009/06/05/sending-couchdb-update-notifications-to-rabbitmq/&quot;&gt;some code to push update notifications&lt;/a&gt; to RabbitMQ and a commenter mentioned using the &lt;a href=&quot;http://books.couchdb.org/relax/reference/change-notifications&quot;&gt;_changes feed&lt;/a&gt; instead. Combining the _changes feed and yajl-ruby&amp;#8217;s HttpStream seemed like a good way to do it.&lt;/p&gt;
&lt;p&gt;The _changes feed is a running list of all the documents that have changed in a database listed in order by sequence number. This is similar to update notifications but gives more information such as the document IDs and is HTTP based (with multiple feed styles) rather than stdout. Additionally you can create design document filters which can be specified as a query parameter to give you only the parts of the feed you want. All in all _changes is a pretty powerful feature.&lt;/p&gt;
&lt;p&gt;Now for the fun stuff, the code. There are a few dependencies I used to do this, specifically focused on making it fast. As such I used EventMachine based libraries for &lt;a href=&quot;http://github.com/tmm1/amqp/&quot;&gt;AMQP&lt;/a&gt; and &lt;a href=&quot;http://github.com/igrigorik/em-http-request/&quot;&gt;HTTP requests&lt;/a&gt;. The first bit of code takes the _changes feed for the &amp;#8220;test&amp;#8221; database, parses the feed, uses the document ID to request that document and publish it to the queue. One key item to note is that this code &lt;strong&gt;requires the latest yajl-ruby&lt;/strong&gt; from github to run properly. Additionally, this works nicely with &lt;em&gt;feed=continuous&lt;/em&gt; so it grabs the documents as they are changed without a need for polling.&lt;/p&gt;
&lt;p&gt; Note that there is a variable for &lt;em&gt;since&lt;/em&gt;, this allows you to start from a specific sequence number so you can skip over old changes.&lt;/p&gt;
&lt;p&gt;The next bit of code works from the other side of the queue. It subscribes to the queue, parses the JSON, performs some operations on it and puts the results back into another CouchDB database called &amp;#8220;results&amp;#8221;.  &lt;/p&gt;
&lt;p&gt;What could it be used for? My first thought is some sort of parallel computation, boot up a few dozen EC2 nodes and start dumping data into CouchDB. Have all those nodes pop messages off the queue, process them and dump the results back into Couch. Legitimately one could chain these together to process the results again. The queue ends up being a simple job management system with the EC2 nodes popping new messages as they finish processing them. With a little bit of work, features and the right use case I think could be a pretty powerful system.&lt;/p&gt;
&lt;p&gt;Check out the &lt;a href=&quot;http://gist.github.com/266991&quot;&gt;code&lt;/a&gt;, &lt;a href=&quot;http://github.com/joewilliams&quot;&gt;my other projects&lt;/a&gt; and follow me on twitter &lt;a href=&quot;http://twitter.com/williamsjoe&quot;&gt;@williamsjoe&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[edit: made a slight improvement to changes_sub.rb on 20100107]&lt;/em&gt;&lt;/p&gt;</content>
		<author>
			<name>Joe's blog</name>
			<uri>http://www.joeandmotorboat.com</uri>
		</author>
		<source>
			<title type="html">Joe's Blog!</title>
			<link rel="self" href="http://www.joeandmotorboat.com/feed/"/>
			<id>http://www.joeandmotorboat.com/feed/</id>
			<updated>2010-03-10T23:00:23+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Network server programming with SML/NJ and CML</title>
		<link href="http://www.lshift.net/blog/2010/01/01/network-server-programming-with-smlnj-and-cml"/>
		<id>http://www.lshift.net/blog/?p=471</id>
		<updated>2010-01-01T15:30:32+00:00</updated>
		<content type="html">&lt;p&gt;My experience with &lt;a href=&quot;http://www.smlnj.org/&quot;&gt;SML/NJ&lt;/a&gt; has been almost uniformly positive, over the years. We used it extensively in a previous project to write a compiler (targeting the .NET CLR) for a pi-calculus-based language, and it was fantastic. One drawback with it, though, is the lack of documentation. Finding out how to (a) compile for and (b) use &lt;a href=&quot;http://cml.cs.uchicago.edu/&quot;&gt;CML&lt;/a&gt; takes real stamina. I&amp;#8217;ve only just now, after several hours poring over webpages, mailing lists, and library source code, gotten to the point where I have a running socket server.&lt;/p&gt;

&lt;h2&gt;Download source code, building, and running&lt;/h2&gt;

&lt;p&gt;The following example is comprised of a &lt;code&gt;.cm&lt;/code&gt; file for building the program, and the &lt;code&gt;.sml&lt;/code&gt; file itself. The complete sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://dev.lshift.net/tonyg/test.cm&quot;&gt;&lt;code&gt;test.cm&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://dev.lshift.net/tonyg/test.sml&quot;&gt;&lt;code&gt;test.sml&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Running the following command compiles the project:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ml-build test.cm Testprog.main
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;ml-build&lt;/code&gt; output is a heap file, with a file extension dependent on your architecture and operating system. For me, right now, it produces &lt;code&gt;test.x86-darwin&lt;/code&gt;. To run the program:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sml @SMLload=test.x86-darwin
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;substituting the name of your &lt;code&gt;ml-build&lt;/code&gt;-produced heap file as necessary.&lt;/p&gt;

&lt;p&gt;On Ubuntu, you will need to have run &lt;code&gt;apt-get install smlnj libcml-smlnj libcmlutil-smlnj&lt;/code&gt; to ensure both SML/NJ and CML are present on your system.&lt;/p&gt;

&lt;h2&gt;The build control file&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;http://dev.lshift.net/tonyg/test.cm&quot;&gt;&lt;code&gt;test.cm&lt;/code&gt;&lt;/a&gt; file contains&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Group is
    $cml/basis.cm
    $cml/cml.cm
    $cml-lib/smlnj-lib.cm
    test.sml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which instructs the build system to use the CML variants of the basis and the standard SML/NJ library, as well as the core CML library itself and the source code of our program. For more information about the SML CM build control system, see &lt;a href=&quot;http://www.smlnj.org/doc/CM/index.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;The example source code&lt;/h2&gt;

&lt;p&gt;Turning to &lt;a href=&quot;http://dev.lshift.net/tonyg/test.sml&quot;&gt;&lt;code&gt;test.sml&lt;/code&gt;&lt;/a&gt; now, we first declare the ML structure (module) we&amp;#8217;ll be constructing. The structure name is also part of one of the command-line arguments to &lt;code&gt;ml-build&lt;/code&gt; above, telling it which function to use as the main function for the program.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;structure Testprog = struct
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next, we bring the contents of the &lt;code&gt;TextIO&lt;/code&gt; module into scope. This is necessary in order to use the &lt;code&gt;print&lt;/code&gt; function with CML; if we use the standard version of &lt;code&gt;print&lt;/code&gt;, the output is unreliable. The special CML variant is needed. We also declare a local alias &lt;code&gt;SU&lt;/code&gt; for the global &lt;code&gt;SockUtil&lt;/code&gt; structure.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;open TextIO
structure SU = SockUtil
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ML programs end up being written upside down, in a sense, because function definitions need to precede their use (unless mutually-recursive definitions are used). For this reason, the next chunk is &lt;code&gt;connMain&lt;/code&gt;, the function called in a new lightweight thread when an inbound TCP connection has been accepted. Here, it simply prints out a countdown from 10 over the course of the next five seconds or so, before closing the socket. Multiple connections end up running connMain in independent threads of control, leading automatically to the natural and obvious interleaving of outputs on concurrent connections.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fun connMain s =
    let fun count 0 = SU.sendStr (s, &quot;Bye!\r\n&quot;)
          | count n = (SU.sendStr (s, &quot;Hello &quot; ^ (Int.toString n) ^ &quot;\r\n&quot;);
                       CML.sync (CML.timeOutEvt (Time.fromReal 0.5));
                       count (n - 1))
    in
        count 10;
        print &quot;Closing the connection.\n&quot;;
        Socket.close s
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The function that depends on &lt;code&gt;connMain&lt;/code&gt; is the accept loop, which repeatedly accepts a connection and spawns a connection thread for it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fun acceptLoop server_sock =
    let val (s, _) = Socket.accept server_sock
    in
        print &quot;Accepted a connection.\n&quot;;
        CML.spawn (fn () =&amp;gt; connMain(s));
        acceptLoop server_sock
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The next function is the primordial CML thread, responsible for creating the TCP server socket and entering the accept loop. We set &lt;code&gt;SO_REUSEADDR&lt;/code&gt; on the socket, listen on port 8989 with a connection backlog of 5, and enter the accept loop.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fun cml_main (program_name, arglist) =
    let val s = INetSock.TCP.socket()
    in
        Socket.Ctl.setREUSEADDR (s, true);
        Socket.bind(s, INetSock.any 8989);
        Socket.listen(s, 5);
        print &quot;Entering accept loop...\n&quot;;
        acceptLoop s
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, the function we told &lt;code&gt;ml-build&lt;/code&gt; to use as the main entry point of the program. The only thing we do here is disable SIGPIPE (otherwise we get rudely killed if a remote client&amp;#8217;s socket closes!) and start CML&amp;#8217;s scheduler running with a primordial thread function. When the scheduler decides that everything is over and the program is complete, it returns control to us. (The lone &lt;code&gt;end&lt;/code&gt; closes the &lt;code&gt;struct&lt;/code&gt; definition way back at the top of the file.)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fun main (program_name, arglist) =
    (UnixSignals.setHandler (UnixSignals.sigPIPE, UnixSignals.IGNORE);
     RunCML.doit (fn () =&amp;gt; cml_main(program_name, arglist), NONE);
     OS.Process.success)

end
&lt;/code&gt;&lt;/pre&gt;</content>
		<author>
			<name>LShift</name>
			<uri>http://www.lshift.net/blog</uri>
		</author>
		<source>
			<title type="html">LShift Ltd.</title>
			<subtitle type="html">What happens at LShift</subtitle>
			<link rel="self" href="http://www.lshift.net/blog/feed/"/>
			<id>http://www.lshift.net/blog/feed/</id>
			<updated>2010-03-05T16:30:50+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Mustache &amp;#8211; GitHub&amp;#8217;s framework agnostic templating ported to Erlang</title>
		<link href="http://erlanginside.com/mustache-githubs-framework-agnostic-templating-ported-to-erlang-135"/>
		<id>http://erlanginside.com/?p=135</id>
		<updated>2009-12-30T14:00:29+00:00</updated>
		<content type="html">Mustache is an Erlang port of the Ruby framework of the same name, originally written by Chris Wanstrath, one of the founders of GitHub. A powerful feature of this type of framework is the ability to write a &amp;#8216;template&amp;#8217; that you could use in a Rails application and then reuse in an Erlang application with [...]</content>
		<author>
			<name>Chad DePue</name>
			<uri>http://erlanginside.com</uri>
		</author>
		<source>
			<title type="html">Erlang Inside</title>
			<subtitle type="html">News and Information on Erlang and Concurrent Computing</subtitle>
			<link rel="self" href="http://erlanginside.com/feed/atom"/>
			<id>http://erlanginside.com/feed/atom</id>
			<updated>2010-03-09T21:00:48+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Yay!</title>
		<link href="http://feedproxy.google.com/~r/curious-attempt-bunny/~3/zbwsesZyAbo/yay.html"/>
		<id>tag:blogger.com,1999:blog-3376508392331888241.post-3078570778687373368</id>
		<updated>2009-12-29T08:20:55+00:00</updated>
		<content type="html">&lt;code&gt;&lt;pre&gt;def groovyPomUrl =&lt;br /&gt;    &quot;http://svn.codehaus.org/groovy/trunk/groovy/groovy-core/pom.xml&quot;&lt;br /&gt;def contributors = new XmlSlurper().parse(groovyPomUrl).contributors&lt;br /&gt;def me = &quot;Merlyn Albery-Speyer&quot;&lt;br /&gt;assert me in contributors.contributor.collect {&lt;br /&gt;    contributor -&gt; contributor.name.text() }&lt;/pre&gt;&lt;/code&gt;Features:&lt;br /&gt;[&lt;a href=&quot;http://jira.codehaus.org/browse/GROOVY-3897&quot;&gt;GROOVY-3897&lt;/a&gt;] [&lt;a href=&quot;http://docs.codehaus.org/display/GROOVY/Groovy+1.7+release+notes#Groovy1.7releasenotes-Grape&quot;&gt;1.7 release notes&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;Improvements:&lt;br /&gt;[&lt;a href=&quot;http://jira.codehaus.org/browse/GROOVY-3958&quot;&gt;GROOVY-3958&lt;/a&gt;]&lt;br /&gt;[&lt;a href=&quot;http://jira.codehaus.org/browse/GROOVY-3910&quot;&gt;GROOVY-3910&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;Bug fixes:&lt;br /&gt;[&lt;a href=&quot;http://jira.codehaus.org/browse/GROOVY-3954&quot;&gt;GROOVY-3954&lt;/a&gt;]&lt;br /&gt;[&lt;a href=&quot;http://jira.codehaus.org/browse/GROOVY-3820&quot;&gt;GROOVY-3820&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;Failing test submissions:&lt;br /&gt;[&lt;a href=&quot;http://jira.codehaus.org/browse/GROOVY-3867&quot;&gt;GROOVY-3867&lt;/a&gt;]&lt;br /&gt;[&lt;a href=&quot;http://jira.codehaus.org/browse/GROOVY-3870&quot;&gt;GROOVY-3870&lt;/a&gt;]&lt;br /&gt;[&lt;a href=&quot;http://jira.codehaus.org/browse/GROOVY-3708&quot;&gt;GROOVY-3708&lt;/a&gt;]&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3376508392331888241-3078570778687373368?l=curious-attempt-bunny.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/curious-attempt-bunny/~4/zbwsesZyAbo&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>Curious Attempt Bunny</name>
			<email>noreply@blogger.com</email>
			<uri>http://curious-attempt-bunny.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">curious-attempt-bunny</title>
			<subtitle type="html">Inquisitive guinea pig =&gt;
neugieriges Versuchskaninschen =&gt; curious attemptbunny</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/curious-attempt-bunny"/>
			<id>tag:blogger.com,1999:blog-3376508392331888241</id>
			<updated>2010-03-06T03:45:26+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">The State of Erlang Web Middleware &amp;#8211; EWGI and SimpleBridge</title>
		<link href="http://erlanginside.com/the-state-of-erlang-web-middleware-simplebridge-ewgi-127"/>
		<id>http://erlanginside.com/?p=127</id>
		<updated>2009-12-28T15:34:31+00:00</updated>
		<content type="html">&lt;p&gt;In the interest of publishing more often and covering smaller topics, lets review web-server-agnostic middleware for Erlang.&lt;/p&gt;
&lt;p&gt;The current standard for Erlang web application middleware is &lt;a href=&quot;http://github.com/skarab/ewgi&quot;&gt;EWGI&lt;/a&gt;,  inspired by Python&amp;#8217;s &lt;a href=&quot;http://www.python.org/dev/peps/pep-0333/&quot;&gt;PEP 333&lt;/a&gt; and providing similar functionality as Ruby&amp;#8217;s &lt;a href=&quot;http://rack.rubyforge.org/&quot;&gt;Rack&lt;/a&gt;. All major Erlang web servers support EWGI, and most web frameworks. &lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Created by Rusty Klophaus, &lt;a href=&quot;http://github.com/rklophaus/SimpleBridge&quot;&gt;SimpleBridge&lt;/a&gt; &amp;#8220;takes the pain out of coding to multiple Erlang web servers by creating a standardized interface.&amp;#8221; It is used by the soon to be released new version of &lt;a href=&quot;http://nitrogenproject.com/&quot;&gt;The Nitrogen Web Framework&lt;/a&gt;. According to Rusty, SimpleBridge has some improvements over &lt;a href=&quot;http://github.com/skarab/ewgi&quot;&gt;EWGI&lt;/a&gt;, such as a smaller code base;  more easily extendable (Takes about 150 lines to add support for a new HTTP server, vs. ~350 for EWGI; support for multipart file uploads, with size limits and handle-able errors; static file support; more specific interface functions for getting and setting cookies.&lt;/p&gt;
&lt;p&gt;However, based on my experience with &lt;a href=&quot;http://rack.rubyforge.org/&quot;&gt;Rack&lt;/a&gt;, Multipart file uploads, static file support, and anything but basic cookie manipulation are all best handled by a web server such as nginx or a reverse proxy like HAProxy anyway. Perhaps it is better that EWGI tries to do less in this case&amp;#8230;&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s look at a simple EWGI example with MochiWeb (&lt;em&gt;shamelessly pulled from the docs&lt;/em&gt;)&amp;#8230;&lt;/p&gt;
&lt;p&gt;First we startup mochiweb calling the loop/1 function. Mochiweb will call our loop/1 function whenever a request is received.&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;alignleft size-full wp-image-129&quot; title=&quot;Picture 7&quot; src=&quot;http://erlanginside.com/wp-content/uploads/2009/12/Picture-7.png&quot; alt=&quot;Picture 7&quot; width=&quot;598&quot; height=&quot;82&quot; /&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;
&lt;p&gt;In loop/1 we setup a call to our simple implementation of the EWGI interface.&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;size-full wp-image-130 alignleft&quot; title=&quot;loop&quot; src=&quot;http://erlanginside.com/wp-content/uploads/2009/12/Picture-9.png&quot; alt=&quot;Picture 9&quot; width=&quot;588&quot; height=&quot;79&quot; /&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;
&lt;p&gt;Now the EWGI implementation is called with a tuple that aways starts with ewgi_context, and contains a Request and a Response. This code returns a 5-tuple response (further details in the &lt;a href=&quot;http://github.com/skarab/ewgi/blob/master/doc/SPEC.rst&quot;&gt;documentation&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;alignleft size-full wp-image-131&quot; title=&quot;ewgi implementation&quot; src=&quot;http://erlanginside.com/wp-content/uploads/2009/12/Picture-12.png&quot; alt=&quot;ewgi implementation&quot; width=&quot;584&quot; height=&quot;116&quot; /&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;
&lt;p&gt;
&lt;p&gt;EWGI solves the problem of creating a standard interface to middleware components. It has become the standard, &lt;em&gt;and the power of such standards lies in their implementations&amp;#8217; ubiquity&lt;/em&gt;. Making your own hit web framework at home in your spare time has never been easier.&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;</content>
		<author>
			<name>Chad DePue</name>
			<uri>http://erlanginside.com</uri>
		</author>
		<source>
			<title type="html">Erlang Inside</title>
			<subtitle type="html">News and Information on Erlang and Concurrent Computing</subtitle>
			<link rel="self" href="http://erlanginside.com/feed/atom"/>
			<id>http://erlanginside.com/feed/atom</id>
			<updated>2010-03-09T21:00:48+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Integrating Heman into CalendERL About Nothing</title>
		<link href="http://blog.socklabs.com/2009/12/28/integrating_heman_into_calenderl_about_nothing.html"/>
		<id>http://blog.socklabs.com/2009/12/28/integrating_heman_into_calenderl_about_nothing</id>
		<updated>2009-12-28T08:00:00+00:00</updated>
		<content type="html">&lt;p&gt;A while ago I started a project called &lt;a href=&quot;http://github.com/ngerakines/heman&quot;&gt;Heman&lt;/a&gt;. The goal was to create a way to use Erlang to measure and assess application health. Application health is a score used to determine how your application is doing. This could be as general as it's immediate resource consumption or it's general activities but can also be embed to give you detailed information on it's internals and inner workings.&lt;/p&gt;

&lt;p&gt;This evening I started integrating heman into &lt;a href=&quot;http://www.calenderlaboutnothing.com/&quot;&gt;calenderl about nothing&lt;/a&gt;. It is a good way to put it to practical use and also flesh out some use cases and conditions. You can see the updated &lt;a href=&quot;http://github.com/ngerakines/cerlan&quot;&gt;cerlan code base&lt;/a&gt; as well as the stats system on &lt;a href=&quot;http://calenderlaboutnothing.com:7816/&quot;&gt;calenderlaboutnothing.com&lt;/a&gt;.&lt;/p&gt;</content>
		<author>
			<name>Nick Gerakines</name>
			<email>nick@gerakines.net</email>
			<uri>http://blog.socklabs.com/</uri>
		</author>
		<source>
			<title type="html">Socklabs</title>
			<subtitle type="html">&lt;div class=&quot;center&quot;&gt;
			&lt;p&gt;Woops! The page you want isn't here.&lt;/p&gt;
			&lt;p&gt;If you are looking for Fence, KeywordExtractor, CloudNine or another project, check out &lt;a href=&quot;http://ngerakines.github.com/&quot;&gt;ngerakines.github.com&lt;/a&gt; to see all of my open source projects and contributions.&lt;/p&gt;
			&lt;form action=&quot;http://www.google.com/cse&quot; id=&quot;cse-search-box&quot;&gt;
			  &lt;div&gt;
			    &lt;input type=&quot;hidden&quot; name=&quot;cx&quot; value=&quot;013481155136750519573:2nno9r59bps&quot; /&gt;
			    &lt;input type=&quot;hidden&quot; name=&quot;ie&quot; value=&quot;UTF-8&quot; /&gt;
			    &lt;input type=&quot;text&quot; name=&quot;q&quot; size=&quot;31&quot; /&gt;
			    &lt;input type=&quot;submit&quot; name=&quot;sa&quot; value=&quot;Search&quot; /&gt;
			  &lt;/div&gt;
			&lt;/form&gt;
			
		&lt;/div&gt;</subtitle>
			<link rel="self" href="http://blog.socklabs.com/atom.xml"/>
			<id>http://blog.socklabs.com/</id>
			<updated>2010-02-21T04:45:11+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">On Peer Processes</title>
		<link href="http://jlouisramblings.blogspot.com/2009/12/on-peer-processes.html"/>
		<id>tag:blogger.com,1999:blog-5411139659011156551.post-3715563760340949096</id>
		<updated>2009-12-27T16:58:08+00:00</updated>
		<content type="html">&lt;a href=&quot;http://2.bp.blogspot.com/_ZmTZzIup5tY/Szf9-9KdJnI/AAAAAAAAABo/a6Hbosydy_w/s1600-h/Peer.png&quot;&gt;&lt;img src=&quot;http://2.bp.blogspot.com/_ZmTZzIup5tY/Szf9-9KdJnI/AAAAAAAAABo/a6Hbosydy_w/s320/Peer.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5420079934575814258&quot; /&gt;&lt;/a&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;On Peer Processes&lt;/span&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;The diagram above is the control-flow in the Peer Process as it stands right now. This process is responsible for communicating with another Peer in haskell-bittorrent. This post is not about the details of the inner workings. Rather it serves to document the legend of the diagram.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;All the ellipses that are blue signifies other processes. The inbound process waits on the socket for incoming messages and sends them into the Peer process. The outbound process is a queue which dequeues messages as fast as possible to the peer in the other end. Peer Manager is the process which manages a set of peers -- we have one Peer process for each peer. Finally, Piece Manager is responsible for managing the state of the torrent: what subsets of pieces do we have and what is missing before we have the full file?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;A little bit of terminology: a &lt;i&gt;piece&lt;/i&gt; is the smallest array of bytes we can SHA1 check for correctness. A &lt;i&gt;block&lt;/i&gt; is a subset of a piece which is transferred by the wire protocol. In practice these are always 16K although the protocol provisions for alternative sizes. The reason for this split is that the 16K blocks means we can interleave other messages in between. Further, we can get a hunch on how fast we transfer to a peer by looking at the amount of bytes we can dequeue and smaller blocks means a better granularity.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;The diagram depicts the control flow of the client. Black arrows designate how control transfers from one function to the next (usually by tail-calling this &lt;i&gt;is &lt;/i&gt;functional programming after all). The blue dotted arrows specifies synchronization points with external processes. If a blue dotted arrow &lt;i&gt;enters&lt;/i&gt; a box it usually means that control can only transfer to this point if the corresponding event tied to the arrow fires. The Piece Mgr and &quot;Grab up to ...&quot; is the exception from the rule however: when arrows are back and forth, it is a rpc call.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;If a blue dotted arrow leaves towards an external process it means we will wait for a synchronization towards that process before continuing out of the box.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;The current state&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;Modulo some work in the debugging and QA department, the client should be able to leech in a laboratory setting. We cheat by having no Peer Manager yet and we can essentially not really support many Peers properly yet. When the client portion stabilizes it should be fairly easy to add proper Peer managent. I hope to support leeching in the coming days.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;Wanna help?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;If you want to help out, there is plenty to do. I am still, deliberately, leaving many things open so it should be fairly easy to pick up the code from github and then do some of the simpler stuff. I've not run the excellent hlint by Neil Mitchell - so there should be an opportunity there. There is also an amortized queue implementation which could do with some documentation. Finally, the TODO list is littered with what needs to be done.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;On github: &lt;a href=&quot;http://github.com/jlouis/haskell-torrent&quot;&gt;haskell-torrent&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/5411139659011156551-3715563760340949096?l=jlouisramblings.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Jlouis</name>
			<email>noreply@blogger.com</email>
			<uri>http://jlouisramblings.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">JLOUIS Ramblings</title>
			<subtitle type="html">Musings of a mathematically oriented Computer Scientist. Anything that tickles my brain might go in here, be it Computer Science, mathematics, society, relationships, sex, 0xf00d, or pets.</subtitle>
			<link rel="self" href="http://jlouisramblings.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-5411139659011156551</id>
			<updated>2010-03-10T18:31:55+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">A case for hybrid SQL - NoSQL stack</title>
		<link href="http://debasishg.blogspot.com/2009/12/case-for-hybrid-sql-nosql-stack.html"/>
		<id>tag:blogger.com,1999:blog-22587889.post-71561688376531071</id>
		<updated>2009-12-24T11:31:22+00:00</updated>
		<content type="html">Alex Popescu talks about &lt;a href=&quot;http://nosql.mypopescu.com/post/296876437/drizzle-replication-nosql-hybrid-solutions&quot;&gt;Drizzle replication&lt;/a&gt; in his MyNoSql column. He makes a very interesting observation in his post regarding Drizzle's replication capabilities into a host of NoSQL storage backends .. &lt;br /&gt;&lt;br /&gt;&lt;cite&gt;&quot;Leaving aside the technical details — which are definitely interesting .., the solution using the Erlang AMQP .. implementation RabbitMQ .. — I think this replication layer could represent a good basis for SQL-NoSQL hybrid solutions&quot;.&lt;br /&gt;&lt;/cite&gt;&lt;br /&gt;We are going to see more and more of such hybrid solutions in the days to come. &lt;a href=&quot;http://drizzle.org/&quot;&gt;Drizzle&lt;/a&gt; does it at the product level. Using RabbitMQ as the transport, Drizzle can replicate data as serialized Java objects to Voldemort, as JSON marshalled objects to Memcached or as a hashmap to column family based Cassandra.&lt;br /&gt;&lt;br /&gt;Custom implementation projects have also started using the hybrid stack of persistent stores. When you are dealing with real high volumes and patterns of access where you cannot use joins, anyway you need to denormalize. ORMs cease to be a part of your solution toolset. Data access patterns vary widely across the profile of clients using your system. If you are running an ecommerce suite and your product is launched you may have an explosive use of the shopping cart module. It makes every sense to move your shopping cart from the single relational data store where it was lying around and have it served through a more appropriate data store that lives up to the scalability requirements. It's not that you need to throw away your relational database that has served you so long. Like Alex mentioned, you can always go along with a hybrid model.&lt;br /&gt;&lt;br /&gt;In one of our recent projects, we were using Oracle as the main relational database for a securities trading back office solution implementation. The database load was computed based on all calculations that were done initially. In a very late stage of the project a new requirement came up that needed heavy processing and storage of semi-structured data and meta-data from an external feed. Both the data and the meta-data were extensible which meant that it was difficult to model them with a fixed schema. &lt;br /&gt;&lt;br /&gt;We could not afford frequent schema changes since it would entail long downtime of the production database. But there also was the requirement that after processing of these semi-structured data lots of them will have to be made available in the production database. We could have modeled it following the key/value paradigm in Oracle itself, which we were using anyway as the primary database. But that's again going down the age old saying of the hammer and nail story. &lt;br /&gt;&lt;br /&gt;We decided to supplement the stack with another data store that fits the bill for this specific use case. We used &lt;a href=&quot;http://mongodb.org&quot;&gt;MongoDB&lt;/a&gt;, that gave us phenomenal performance for our requirements. We were getting the feed from external data sources and loaded our MongoDB database with all the semi-structured data and meta-data. All necessary processing was done in MongoDB on those data and relevant information from MongoDB were pushed to JMS based queues for consumption by appropriate services that copied data &lt;i&gt;asynchrnously&lt;/i&gt; to our Oracle servers.&lt;br /&gt;&lt;br /&gt;What did we achieve with the above architecture ?&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;  &lt;li&gt;Kept Oracle free to do what it does the best.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Took away unnecessary load from production database servers.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Introduced a document database for serving a requirement tailor made for its use - semi structured data, mainly reads, no constraints, no overhead of ORM ceremony. MongoDB supports a very clean programming model, a very decent query interface, simple to use and easy to convince your client.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Used message based mapping to sync up data ASYNCHRONOUSLY between the nosql MongoDB and sql based Oracle. Each of the data stores were doing what they do the best, keeping us away from the blames of the hammer-nail paradigm.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;With more and more of the nosql stores coming up, &lt;i&gt;message based replication&lt;/i&gt; is going to play a very important role. Even within the nosql datastore, we are seeing choices of sql based storage backends being offered. &lt;a href=&quot;http://project-voldemort.com/design.php&quot;&gt;Voldemort&lt;/a&gt; offers MySql as one of the storage backends - so the hybrid model starts right up there. It's always advisable to use multiple storage that fits your use case than trying to force-fit everything into a single paradigm.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/22587889-71561688376531071?l=debasishg.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Debasish</name>
			<email>ghosh.debasish@gmail.com</email>
			<uri>http://debasishg.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Ruminations of a Programmer</title>
			<subtitle type="html">A programmer's blog - will deal with everything that relates to a programmer. Occasionally, it will contain some humour, some politics and some sport news.</subtitle>
			<link rel="self" href="http://debasishg.blogspot.com/feeds/posts/default?alt=rss"/>
			<id>tag:blogger.com,1999:blog-22587889</id>
			<updated>2010-03-04T07:15:02+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">erlrc and rpm</title>
		<link href="http://dukesoferl.blogspot.com/2009/12/erlrc-and-rpm.html"/>
		<id>tag:blogger.com,1999:blog-6265608756663924839.post-3617401259151213935</id>
		<updated>2009-12-23T15:12:51+00:00</updated>
		<content type="html">Two of the Dukes now work at &lt;a href=&quot;http://www.openx.org/&quot;&gt;OpenX&lt;/a&gt;, which is starting to dip its toe into the Erlang waters.  They use &lt;a href=&quot;http://www.centos.org/&quot;&gt;CentOS &lt;/a&gt;so they agreed to fund porting &lt;a href=&quot;http://code.google.com/p/fwtemplates/&quot;&gt;framewerk&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/p/erlrc/&quot;&gt;erlrc&lt;/a&gt; to rpm; previously I'd only used them with deb.&lt;br /&gt;&lt;br /&gt;A bit of background: erlrc is a set of Erlang modules and shell scripts that are designed to be integrated into packaging hooks so that installation, upgrade, or removal of a package causes corresponding hot-code activity to happen inside registered Erlang VMs on the box.  Since erlrc was designed to easily integrate with multiple package managers, getting it to work with rpm was mostly about me understanding rpm's package hooks model.  The result is an experience like this,&lt;br /&gt;&lt;pre class=&quot;brush:bash&quot;&gt;&lt;br /&gt;% sudo yum -q -y install lyet&lt;br /&gt;erlrc-start: Starting 'lyet': (erlang) started&lt;br /&gt;% sudo yum -q -y remove lyet&lt;br /&gt;erlrc-stop: Stopping 'lyet': (erlang) unloaded&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;i.e., installing an rpm causes a running Erlang VM on the box to hot-code load the new modules and start the associated application, and removing the rpm causes the associated application to be stopped and the corresponding modules to be hot-code unloaded.&lt;br /&gt;&lt;br /&gt;If you use &lt;a href=&quot;http://code.google.com/p/fwtemplates/wiki/FwTemplateErlangWalkthrough&quot;&gt;fw-template-erlang&lt;/a&gt; than the appropriate packaging hooks are added for you automatically, both for deb and now rpm.  However even manual creation of rpm spec files is pretty easy:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;erlrc-stop is called in %preun if the installation count indicates removal&lt;/li&gt;&lt;li&gt;erlrc-upgrade is called in %preun if the installation count indicates upgrade&lt;/li&gt;&lt;li&gt;erlrc-start is called in %posttrans&lt;/li&gt;&lt;/ul&gt;Also, the erlrc shell scripts want to know the previously installed version, so I call &lt;span&gt;rpm -q&lt;/span&gt; in a %pretrans hook and save the result.  Longer term, erlrc should probably ask the Erlang VM it is talking to what version is running to eliminate the need for this argument (I was a bit surprised that rpm doesn't provide this argument to the package hook like debian does; it seems very useful for creating version-specific upgrade fixes).&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/6265608756663924839-3617401259151213935?l=dukesoferl.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Paul Mineiro</name>
			<email>noreply@blogger.com</email>
			<uri>http://dukesoferl.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Dukes of Erl</title>
			<subtitle type="html">Someday the mountain might get &amp;rsquo;em, but the law never will.</subtitle>
			<link rel="self" href="http://dukesoferl.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-6265608756663924839</id>
			<updated>2010-03-09T15:45:26+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">[ANN] exmpp 0.9.2 new release</title>
		<link href="http://www.process-one.net/en/blogs/article/ann_exmpp_0.9.2_new_release/"/>
		<id>tag:process-one.net,2009:en/blogs/3.2136</id>
		<updated>2009-12-23T14:59:25+00:00</updated>
		<content type="html">&lt;p&gt;We are pleased to announce a new release of exmpp.&lt;br /&gt;&lt;br /&gt;exmpp is a XMPP library written in Erlang and released under the Erlang Public License. It helps the development of XMPP entities by providing functions to build and interpret XML stanzas. Once compiled, check the generated HTML documentation.&lt;/p&gt; &lt;p&gt;List of main changes since the previous release six months ago:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adding support for stream error stanzas in exmpp_session when logged in&lt;/li&gt;
&lt;li&gt;Autodetect compilation parameters for Mac OS X Snow Leopard&lt;/li&gt;
&lt;li&gt;Component support for exmpp, and some fixes&lt;/li&gt;
&lt;li&gt;Fix segmentation fault with exmpp and expat&lt;/li&gt;
&lt;li&gt;New functions exmpp_client_pubsub:discover_nodes/1 and 2&lt;/li&gt;
&lt;li&gt;Stringprep Bidi checking doesn't reject strings with RandALCat and LCat characters&lt;/li&gt;
&lt;li&gt;queryns was not defined for IQ packets in received_packet record&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;The API of exmpp 0.9.2 is considered to be stable, so there aren't any&lt;br /&gt;major changes expected in the API before reaching 1.0.0.&lt;br /&gt;&lt;br /&gt;exmpp home page:&lt;br /&gt;&lt;a href=&quot;http://support.process-one.net/doc/display/EXMPP/&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://exmpp.org/&quot;&gt;http://exmpp.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Download exmpp 0.9.2 source code package from:&lt;br /&gt;&lt;a href=&quot;http://download.process-one.net/exmpp/&quot;&gt;http://download.process-one.net/exmpp/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can also check the ProcessOne Labs page:&lt;br /&gt;&lt;a href=&quot;http://www.process-one.net/en/labs/&quot;&gt;http://www.process-one.net/en/labs/&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>Jérôme Sautret</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:03:03</id>
			<updated>2010-03-04T09:46:36+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">[ANN] ejabberd 2.1.1 bugfix release</title>
		<link href="http://www.process-one.net/en/blogs/article/ann_ejabberd_2.1.1_bugfix_release/"/>
		<id>tag:process-one.net,2009:en/blogs/3.2135</id>
		<updated>2009-12-23T14:54:42+00:00</updated>
		<content type="html">&lt;p&gt;We are pleased to announce the bugfix release ejabberd 2.1.1, which was published on the 17th of December. ejabberd 2.1.1 contains several important bugfixes over last month's major release.&amp;nbsp; None of the fixes is critical, but you are encouraged to update if you are running ejabberd 2.1.0.&lt;/p&gt; &lt;p&gt;Short list of bugfixes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix connection if starttls_required and zlib are set&lt;/li&gt;
&lt;li&gt;S2S: fix allow_host/2 on subdomains. added hook s2s_allow_host&lt;/li&gt;
&lt;li&gt;MUC: Add support for serving a Unique Room Name&lt;/li&gt;
&lt;li&gt;MUC: Route vCard request to the occupant bare JID&lt;/li&gt;
&lt;li&gt;MUC: Support converting one-to-one chat to MUC&lt;/li&gt;
&lt;li&gt;PubSub: Receive same last published PEP items at reconnect if several resources online&lt;/li&gt;
&lt;li&gt;PubSub: Typo in mod_pubsub_odbc breaks Service Discovery and more&lt;/li&gt;
&lt;li&gt;Web: Fix memory and port leak when TLS is enabled in HTTP&lt;/li&gt;
&lt;li&gt;WebAdmin: report correct last activity with odbc backends&lt;/li&gt;
&lt;li&gt;Change captcha.sh to not depend on bash&lt;/li&gt;
&lt;li&gt;Generate main XML file also when exporting only a vhost&lt;/li&gt;
&lt;li&gt;Fix last newline in ejabberdctl result&lt;/li&gt;
&lt;li&gt;Guide: fix -setcookie, mod_pubsub_odbc host, content_types&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;Check the Release Notes for a more complete list of changes:&lt;br /&gt;&lt;a href=&quot;http://www.process-one.net/en/ejabberd/release_notes/release_note_ejabberd_2.1.1&quot;&gt;http://www.process-one.net/en/ejabberd/release_notes/release_note_ejabberd_2.1.1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you upgrade from ejabberd 2.0.5 or older, read carefully the release notes, because there were several changes in the installation path and the configuration options.&lt;br /&gt;&lt;br /&gt;The list of solved tickets since 2.1.0 is available on ProcessOne bug tracker:&lt;br /&gt;&lt;a href=&quot;http://redir.process-one.net/ejabberd-2.1.1&quot;&gt;http://redir.process-one.net/ejabberd-2.1.1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ejabberd 2.1.1 is available as source code package and binary installers for Linux 32 bits, 64 bits, Mac OS X Intel, and Windows:&lt;br /&gt;&lt;a href=&quot;http://www.process-one.net/en/ejabberd/downloads&quot;&gt;http://www.process-one.net/en/ejabberd/downloads&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>Jérôme Sautret</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:03:03</id>
			<updated>2010-03-04T09:46:36+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">ProcessOne launches Talkr.IM: a new open, free public XMPP service</title>
		<link href="http://www.process-one.net/en/blogs/article/processone_launches_talkr.im_a_new_open_free_public_xmpp_service/"/>
		<id>tag:process-one.net,2009:en/blogs/3.2068</id>
		<updated>2009-12-23T11:19:58+00:00</updated>
		<content type="html">&lt;p&gt;Talkr.IM is the new XMPP service provided by ProcessOne. It is an open and free service for all audiences worldwide.&lt;/p&gt; &lt;h2&gt;What is talkr.IM?&lt;/h2&gt;
&lt;p&gt;In a few words, Talkr.IM offers scalable and robust presence and chat services for all standard XMPP clients of your choice. Just create an account now, by filling the registration form, and you will be able to login and start chats. It is fully interoperable with XMPP services such as Google Talk, Nokia Ovi, LiveJournal, Yandex Online, jabber.org, jabber.ru, jabbim.cz, jabberes.org, and jabber.fr for example.&lt;/p&gt;
&lt;h2&gt;Why talkr.IM?&lt;/h2&gt;
&lt;p&gt;Although this is a plain good XMPP service like others are providing, we want to provide a service that is professionally managed on a daily basis, with a &lt;strong&gt;strong service level&lt;/strong&gt;, responsiveness and uptime.&lt;/p&gt;
&lt;p&gt;We also emphasize on &lt;strong&gt;privacy and freedom&lt;/strong&gt;. Privacy is there to ensure that your data are safe with us and will not be abused or transfered. We would like the service to be as much as a safe as possible. Freedom put the emphasize on using as much as free software as possible and ensure data portability. The service runs on free software and the data are yours. We plan to provide a migration feature. You will be able to import your data from another server, but we are also working on the reverse, so that you are able to export them and take them to another server, maybe your own server at some point. That's your data, that's your life and its important for you to keep the control on it.&lt;/p&gt;
&lt;p&gt;Instant messaging conveys the value of the pionneer of Internet. One of the first simple messaging client was &lt;em&gt;talk&lt;/em&gt; on various Unix flavour in the 1970's. It was free software and was a new way to communicate. Jabber and XMPP after that has been the heir of this tradition of freedom. Talkr.IM wants, like many other XMPP public servers to be a testimonial to this spirit: be free and open minded.&lt;/p&gt;
&lt;h2&gt;Why another XMPP hosting service ?&lt;/h2&gt;
&lt;p&gt;There are XMPP services backed by big companies like Google Talk, Nokia Ovi, LiveJournal or Yandex Online. There are also the valuable and much respected XMPP services administered by groups of volunteers and enthusiats, like jabber.org, jabber.ru, jabbim.cz, jabberes.org, and jabber.fr.&lt;/p&gt;
&lt;p&gt;In none of these services, we had the opportunity to fully help, as much as we could, and really be implicated into the service administration and optimization.&lt;/p&gt;
&lt;p&gt;With Talkr.IM, it is intended to provide a strong service to all users, which we can fully support. It is not intended to compete with any of the above mentionned XMPP services, as it is fully compliant and interoperated, in the pure tradition of the fair-play of the open Internet.&lt;/p&gt;
&lt;p&gt;We believe we can achieve these goals since we are the makers of ejabberd. This work will of course benefit the product, in terms even more robustness, features, scalability and security.&lt;/p&gt;
&lt;h2&gt;Services&lt;/h2&gt;
&lt;p&gt;That said, besides the simple presence and IM, we also offer more services:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;conference&lt;/em&gt; will let you create and join multi-party chats with friends, family and colleagues (Multi user chat)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;irc&lt;/em&gt; is the gateway to the IRC networks that will enable you to join channels you wish from your XMPP client&lt;/li&gt;
&lt;li&gt;&lt;em&gt;pubsub&lt;/em&gt; and &lt;em&gt;PEP&lt;/em&gt; enables you to publish information for yourself and receive information from your contacts such as your mood, activity, geolocation, or the titles of the music you are listening to&lt;/li&gt;
&lt;li&gt;&lt;em&gt;users&lt;/em&gt; is the directory that enables you to search for friends&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Talkr.IM service will also enhance the user experience in the future, by adding more services.&lt;/p&gt;
&lt;h2&gt;Feedback&lt;/h2&gt;
&lt;p&gt;Please feel free to express your needs for the Talkr.IM service and its evolution, as we are listening to and value your feedback.&lt;/p&gt;
&lt;p&gt;Please join &lt;a href=&quot;http://Talkr.IM&quot;&gt;Talkr.IM&lt;/a&gt;, and contribute to the &lt;a href=&quot;http://www.process-one.net/en/forum/viewforum/23/&quot;&gt;forums&lt;/a&gt;.&lt;/p&gt;</content>
		<author>
			<name>Nicolas Vérité</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:03:03</id>
			<updated>2010-03-04T09:46:36+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Merry Christmas: Toke — Tokyo Cabinet driver for Erlang</title>
		<link href="http://www.lshift.net/blog/2009/12/21/merry-christmas-toke-tokyo-cabinet-driver-for-erlang"/>
		<id>http://www.lshift.net/blog/?p=468</id>
		<updated>2009-12-21T17:01:01+00:00</updated>
		<content type="html">&lt;p&gt;&lt;a href=&quot;http://1978th.net/tokyocabinet/&quot;&gt;Tokyo Cabinet&lt;/a&gt; is a rather excellent key-value store, with the ability to write to disk in a sane way (i.e. not just repeatedly dumping the same data over and over again), operate in bounded memory, and go &lt;em&gt;really&lt;/em&gt; fast. I like it a lot, and there&amp;#8217;s a likelihood that there&amp;#8217;ll be a RabbitMQ plugin fairly soon that&amp;#8217;ll use Tokyo Cabinet to improve the new persister yet further. &lt;a href=&quot;http://hg.opensource.lshift.net/toke/&quot;&gt;Toke&lt;/a&gt; is an Erlang linked-in driver that allows you to use Tokyo Cabinet from Erlang.&lt;span id=&quot;more-468&quot;&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;There is already a Tokyo Cabinet driver for Erlang, &lt;a href=&quot;http://code.google.com/p/tcerl/&quot;&gt;tcerl&lt;/a&gt;, however, I couldn&amp;#8217;t make it work: even after fixing the C so that it compiles (I hit &lt;a href=&quot;http://code.google.com/p/tcerl/issues/detail?id=5&quot;&gt;this bug&lt;/a&gt;), I still couldn&amp;#8217;t make it work. Inspecting the code, I get the feeling it&amp;#8217;s bit-rotted - the Tokyo Cabinet API has moved on, and tcerl hasn&amp;#8217;t kept up.&lt;/p&gt;

&lt;p&gt;The other issue with tcerl is that it&amp;#8217;s not a &lt;em&gt;linked-in driver&lt;/em&gt;. Erlang allows two different types of drivers: the first are external C programs &amp;#8212; these have a &lt;code&gt;main()&lt;/code&gt; and run in their own process. Communication is done by stdin/stdout. These are a bit safer because if they crash they don&amp;#8217;t take out the Erlang VM, but they&amp;#8217;re never going to be blazingly fast. Toke, on the other hand, is a fully linked-in driver. It dynamically links with the Erlang VM, exists in the same address space and goes as fast as it possibly can (using the Erlang driver callbacks which avoid all copying of data passed from the Erlang). My tests show it&amp;#8217;s about three times slower driving Tokyo Cabinet from Erlang via Toke, than driving it natively through C (which is quite good: some googling suggests both the Ruby and Python bindings to Tokyo Cabinet are rather slower). Toke is also about twice as slow as the Erlang &lt;a href=&quot;http://erlang.org/doc/man/ets.html&quot;&gt;ets&lt;/a&gt; module, which is in-memory only.&lt;/p&gt;

&lt;p&gt;Toke only implements the Tokyo Cabinet hash table (tchdb*) functions, and doesn&amp;#8217;t even support all of those: I only wrapped exactly what I needed. You&amp;#8217;ll want to read the &lt;a href=&quot;http://1978th.net/tokyocabinet/spex-en.html#tchdbapi&quot;&gt;documentation&lt;/a&gt; for Tokyo Cabinet for these. The functions implemented are as follows (refer to the Tokyo Cabinet documentation to explain these further):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;toke_drv:new/1 &amp;#8212; Set up the driver with a new TCHDB object.&lt;/li&gt;
&lt;li&gt;toke_drv:delete/1 &amp;#8212; Destroy the driver&amp;#8217;s TCHDB object.&lt;/li&gt;
&lt;li&gt;toke_drv:tune/5 &amp;#8212; Tune the driver&amp;#8217;s TCHDB Object.&lt;/li&gt;
&lt;li&gt;toke_drv:set_cache/2 &amp;#8212; Set the number of records to cache.&lt;/li&gt;
&lt;li&gt;toke_drv:set_xm_size/2 &amp;#8212; Set the extra amount of memory mapped in.&lt;/li&gt;
&lt;li&gt;toke_drv:set_df_unit/2 &amp;#8212; Set the steps between auto defrag.&lt;/li&gt;
&lt;li&gt;toke_drv:open/3 &amp;#8212; Open a db.&lt;/li&gt;
&lt;li&gt;toke_drv:close/1 &amp;#8212; Close an open db.&lt;/li&gt;
&lt;li&gt;toke_drv:insert/3 &amp;#8212; Insert. If the key already exists, value is updated.&lt;/li&gt;
&lt;li&gt;toke_drv:insert_new/3 &amp;#8212; Insert new. If the key already exists, the old value is silently kept.&lt;/li&gt;
&lt;li&gt;toke_drv:insert_concat/3 &amp;#8212; Concatenate the supplied value with an existing value for this key.&lt;/li&gt;
&lt;li&gt;toke_drv:insert_async/3 &amp;#8212; Asynchronously insert. If the key already exists, value is updated.&lt;/li&gt;
&lt;li&gt;toke_drv:delete/2 &amp;#8212; Delete a key from the db.&lt;/li&gt;
&lt;li&gt;toke_drv:get/2 &amp;#8212;  Fetch a key from the db. Returns &amp;#8216;not_found&amp;#8217; on occasion.&lt;/li&gt;
&lt;li&gt;toke_drv:fold/3 &amp;#8212; Fold over every value in the db. This internally uses the iteration functions. It&amp;#8217;s just wrapped up as a fold to make it appear more functional.&lt;/li&gt;
&lt;li&gt;toke_drv:stop/1 &amp;#8212; Stop the driver and close the port.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should be able to use Mercurial to clone it:&lt;/p&gt;

&lt;pre&gt;# hg clone http://hg.opensource.lshift.net/toke/&lt;/pre&gt;
Make sure you have Tokyo Cabinet installed (ideally from source. If you&amp;#8217;re using a package, make sure you have the development headers available. If you do compile from source, make sure you &lt;code&gt;ldconfig&lt;/code&gt; to make your system pick up the new library once it&amp;#8217;s installed.). Then it should just be a case of &lt;code&gt;make&lt;/code&gt;. There&amp;#8217;s also a &lt;code&gt;make run&lt;/code&gt; target that starts up an Erlang shell with the paths set up correctly for testing Toke:

&lt;pre&gt;toke# make run
erl -pa ebin +K true +A30
Erlang R13B03 (erts-5.7.4) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:30] [hipe] [kernel-poll:true]

Eshell V5.7.4  (abort with ^G)
1&gt; toke_test:test().
passed
2&gt;
&lt;/pre&gt;

&lt;p&gt;Toke is licensed under the MPL. As ever, feedback is very welcome, as are patches!&lt;/p&gt;</content>
		<author>
			<name>LShift</name>
			<uri>http://www.lshift.net/blog</uri>
		</author>
		<source>
			<title type="html">LShift Ltd.</title>
			<subtitle type="html">What happens at LShift</subtitle>
			<link rel="self" href="http://www.lshift.net/blog/feed/"/>
			<id>http://www.lshift.net/blog/feed/</id>
			<updated>2010-03-05T16:30:50+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Concurrency, Bittorrent clients, and Haskell</title>
		<link href="http://jlouisramblings.blogspot.com/2009/12/concurrency-bittorrent-clients-and.html"/>
		<id>tag:blogger.com,1999:blog-5411139659011156551.post-2010312872044288604</id>
		<updated>2009-12-19T16:05:15+00:00</updated>
		<content type="html">&lt;a href=&quot;http://2.bp.blogspot.com/_ZmTZzIup5tY/Sy1kCETyF4I/AAAAAAAAABg/VdLD7gU3vpE/s1600-h/processes.png&quot;&gt;&lt;img src=&quot;http://2.bp.blogspot.com/_ZmTZzIup5tY/Sy1kCETyF4I/AAAAAAAAABg/VdLD7gU3vpE/s320/processes.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5417095913475807106&quot; /&gt;&lt;/a&gt;
I have been writing code lately on a BitTorrent client in Haskell. Here is the grand old history of that effort. Many years ago, I attempted to start a client, Conjure, written in Haskell. Sadly, it really did not make it to the point where it was really usable, for me at least.

Then a couple of years passed, I became involved with programming in Erlang. Erlang has a really nice Actor-based concurrency model. Since BitTorrent is highly concurrent and event-driven it was easy to start another implementation effort in Erlang. Thus etorrent was born. Sadly, I lost interest in etorrent - partially because I am partial to statically typed languages of which Erlang is not one.

Thus, we come to this december, where I decided to figure out the state of concurrency in Haskell. To really give GHC a whirl, we need to implement something which is fairly complex. Some people implement ray tracers when toying with programming languages, some solve &lt;a href=&quot;http://projecteuler.net/&quot;&gt;projecteuler&lt;/a&gt; problems. I ... write BitTorrent clients.&lt;a href=&quot;http://projecteuler.net/&quot;&gt;&lt;/a&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;BitTorrent is a good maturity check. First, you need decent Disk I/O, decent network I/O and a fairly complete HTTP client. Second, the protocols are easy, but still requires some nontrivial parsing to occur. Finally, the system is fairly concurrent, so it fits nicely into concurrency models if the language has one.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;Initial Thougths:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;Initally, there is the choice of a concurrency framework. In Haskell, there are several such. The built-in &lt;b&gt;Control.Concurrent&lt;/b&gt; is fairly low level and fairly simple. At the CS department at Copenhagen University, DIKU, there is currently a course running in CSP and some students decided to use &lt;b&gt;Control.Concurrent.CHP&lt;/b&gt; by Neil Brown. I think it will suit them well for the course, but it irritated me that it mapped so weakly to the etorrent model. So &lt;b&gt;Control.Concurrent.CML&lt;/b&gt; became the basic library for concurrency. This concurrency model is not entirely unfamiliar to me: it is written by John Reppy for ML.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;The CML model is somewhat reminiscent of the Pi-calculus. In particular, we can transmit channels on channels. This gives a neat method for doing RPC-style operations. Send off a message together with a responder channel and then wait for a response on that channel. This means we are easily able to emulate most of what the Actor model has if needed.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;Haskell-torrent design:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;Haskell-torrent uses a basic design, where a fairly large number of processes communicate with each other to solve the problem of uploading and downloading files. We have a limitation of one single torrent right now, but that should be fixable in time. The process diagram at the header describes the basic layout. Each box is a single process, apart from the &quot;Peer&quot; box, which is multiple processes. The diamond-shapes describes external communication over the network.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;b&gt;Console: &lt;/b&gt;A process responsible for User communication. The idea is to have a simple console-interface on which to log messages (it is heavily used for debugging). The Console can in time also be used for parsing user input and affecting the system. It only responds to a &quot;quit&quot; command at the moment. Logging is done with a LogChannel on which the Console process syncs and prints out information.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;b&gt;Main: &lt;/b&gt;Initial program entry point. Spawns everything else and is the last thing that closes again.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;b&gt;Status: &lt;/b&gt;Keeps track of various torrent-specific statuses. How much is left to download? How many seeders are there? How fast is the torrent currently? The intention is to keep this kind of information around in that process.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;b&gt;Tracker: &lt;/b&gt;Communicates with the tracker. Is a specialized HTTP client. It talks to the &lt;b&gt;Timer&lt;/b&gt; so it won't continually request the tracker for information. In due time, it should also be able to do UDP tracking. It is using &lt;i&gt;bencoded &lt;/i&gt;documents as per the tracker spec. These bcoded documents are handled as in Conjure with the monadic parser generator Parsec.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;b&gt;PeerMgr: &lt;/b&gt;Handles a set of peers. Gets lists of other peers via the Tracker process and spawns a pool of them. In due time, this process will handle choking/unchoking of peers so we don't clog the TCP/IP stack by trying to talk to everybody at once.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;b&gt;Listener: &lt;/b&gt;Listens on a TCP port and spawns off Peers when they try to connect. Not implemented at all yet, but is fairly easy to get to work.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;b&gt;OMBox: &lt;/b&gt;A very simple implementation on top of &lt;b&gt;CML&lt;/b&gt; of what is present in &lt;b&gt;Control.Concurrent.SampleVar. &lt;/b&gt;This will let the PeerMgr be able to place things for the Peer to read later and it avoids a deadlock between those two which otherwise would occur. OMBox is currently not cleaned up properly. We need some mechanism for poisoning the communication channel so it closes down again gracefully.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;b&gt;Peer: &lt;/b&gt;The system contains zero or more peers. Each peer is really four processes. One controls the state of the peer and reacts on the events from the peer. Two are responsible for sending messages to the peer: one as a queue, and one blocks on the socket. Finally, a process receives messages on the socket and then sends them to the controller, blocking in the process.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;b&gt;PieceMgr: &lt;/b&gt;Keeps track of the current piece-state. It knows what pieces we have, what we are missing and what to request next. Peers will be using it for asking what to download next.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;b&gt;FS: &lt;/b&gt;Abstracts away the file system for the rest of the client. Is implemented as a communication process which peers ask for blocks to send.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;Current State:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;Currently, the client is pretty flaky. It is able to seed in a controlled lab-setting, but needs much work to be able to leech data from other clients. The TODO-list is fairly long and some of the things on it are pretty hard. But there are also many things which are fairly simple to fix. Feel free to grab anything and help out if it sounds interesting. I am deliberately keeping things simple and leaving doors open. It is my hope that even aspiring Haskell programmers might stand a chance at solving some of the things on the TODO list. I'll happily take any help I can get as in the long run, this is fairly hard to carry out as a single person. The code is on github in my &lt;a href=&quot;http://github.com/jlouis/haskell-torrent&quot;&gt;haskell-torrent&lt;/a&gt; repository if this should indulge you.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/5411139659011156551-2010312872044288604?l=jlouisramblings.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</content>
		<author>
			<name>Jlouis</name>
			<email>noreply@blogger.com</email>
			<uri>http://jlouisramblings.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">JLOUIS Ramblings</title>
			<subtitle type="html">Musings of a mathematically oriented Computer Scientist. Anything that tickles my brain might go in here, be it Computer Science, mathematics, society, relationships, sex, 0xf00d, or pets.</subtitle>
			<link rel="self" href="http://jlouisramblings.blogspot.com/feeds/posts/default"/>
			<id>tag:blogger.com,1999:blog-5411139659011156551</id>
			<updated>2010-03-10T18:31:55+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Sea Beyond event summary</title>
		<link href="http://www.process-one.net/en/blogs/article/sea_beyond_event_summary/"/>
		<id>tag:process-one.net,2009:en/blogs/3.2116</id>
		<updated>2009-12-18T15:58:19+00:00</updated>
		<content type="html">&lt;p&gt;This thursday 17th of December, ProcessOne has held an event in Paris, France, around real-time communications. Here are the bits.&lt;/p&gt; &lt;p&gt;As &lt;a href=&quot;http://www.process-one.net/en/blogs/article/processone_sea_beyond_event_realtime_communications/&quot;&gt;announced&lt;/a&gt; and &lt;a href=&quot;http://www.process-one.net/en/blogs/article/sea_beyond_event_programme/&quot;&gt;programmed&lt;/a&gt;, we held our event &quot;&lt;a href=&quot;http://www.process-one.net/seabeyond/&quot;&gt;Sea Beyond&lt;/a&gt;&quot;, on this thursday 17th of december. It took place at Le Before, an art gallery in the center of Paris. Usually, we have snow on the french capital only once a year... And the weather chose that special day, to cover the streets with the white jacket.&lt;/p&gt;
&lt;p&gt;We had almost 40 attendants during the whole day, either for the XMPP Sandbox part for developpers, or the Lighthouse part for presentations.&lt;/p&gt;
&lt;p&gt;We had a wide range of people, from pure players to operators, including manufacturers and freelancers, and even the press. Let's quote a few, like Nokia, Erlang Consulting, Yoono, af83, Ohm Force, StudiVZ, Meetic, Tandberg, Mozilla Foundation Europe, Orange, INRIA, Yoono, ...&lt;/p&gt;
&lt;p&gt;During this real-time communications event, there has been a real sandbox as well as a real (tiny) lighthouse. There was also real pizzas for lunch, as well as real Champagne at the end of the day.&lt;/p&gt;
&lt;p&gt;The first part of the day should have been a hacking session, at least this was what we had planned. But people took a lot of interest into workshops about PubSub and the Jingle Nodes. People then talked to each other about real-time technologies, and the future of internet and telecom. We have demoed our products, like the OneTeam client that we hope to release soon, also our supervision console &lt;a href=&quot;http://www.process-one.net/en/solutions/teamleader/&quot;&gt;TeamLeader&lt;/a&gt;. Mathieu Barcikowski also demonstrated Yoono to some people.&lt;/p&gt;
&lt;p&gt;Then we reorganized the room for the presentations. We started with the lightning talks, with Philippe Sultan from INRIA, Asterisk developer and book author, who has presented the Asterisk module for Jingle.  Nicolas V&amp;eacute;rit&amp;eacute; from ProcessOne Project Manager, then presented the Talkr.IM XMPP service soon to be launched. J&amp;eacute;r&amp;ocirc;me Sautret, ProcessOne CTO, did a summary of Sea Beyond XMPP sandbox. And  Mathieu Barcikowski from Yoono, finished the session by demonstrating to the whole audience this time, the Yoono Firefox extension.&lt;/p&gt;
&lt;ul&gt;
&lt;/ul&gt;
&lt;p&gt;The presentations started with Thiago Camargo from Nimbuzz, who introduced his concept of Jingle Nodes, a network of XMPP peers for relay and relay discovery. This presentation has impressed quite a lot of people: the technology, as well as the ease of the Thiago on these subjects. Christophe Romain from ProcessOne the detailed the PubSub use at BBC, for their LiveText over IP in their radios channels in the browser. The session has been closed by Micka&amp;euml;l R&amp;eacute;mond from ProcessOne, who talked and demoed our alpha products implementing the Wave real-time communication system from Google.&lt;/p&gt;
&lt;p&gt;Then we had a cocktail to conclude the day, with once again ver interesting and enriching talks.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;We believe people enjoyed the all day. We hope they enjoyed it as much as we did!&lt;/p&gt;
&lt;p&gt;Thank you to everyone who joined and helped made this event a big success!&lt;/p&gt;</content>
		<author>
			<name>Nicolas Vérité</name>
			<uri>http://www.process-one.net/en/blogs/</uri>
		</author>
		<source>
			<title type="html">ProcessOne Blogs</title>
			<subtitle type="html">ProcessOne Blogs:ProcessOne Blogs</subtitle>
			<link rel="self" href="http://www.process-one.net/en/blogs/atom/"/>
			<id>tag:process-one.net,2010:03:03</id>
			<updated>2010-03-04T09:46:36+00:00</updated>
			<rights type="html">Copyright (c) 2010, ProcessOne</rights>
		</source>
	</entry>

</feed>
