<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4348519741358344123</id><updated>2012-01-01T20:10:28.492-05:00</updated><category term='ruby'/><category term='silly'/><category term='asynchronous'/><category term='twisted'/><category term='clojure'/><category term='chaos theory'/><category term='erlang'/><category term='debugging'/><category term='ec2'/><category term='google talk'/><category term='lyse'/><category term='unicorn'/><category term='chua circuit'/><category term='complexity'/><category term='type theory'/><category term='scoping'/><category term='pointers'/><category term='dart'/><category term='lorenz attractor'/><category term='node'/><category term='f#'/><category term='biology'/><category term='python'/><category term='contravariance'/><category term='rails'/><category term='haskell'/><category term='functional'/><category term='type systems'/><category term='nodejs'/><category term='video'/><category term='c++'/><category term='credit suisse'/><category term='rant'/><category term='covariance'/><category term='friday links'/><category term='distributed'/><category term='wrong'/><category term='scala'/><category term='jane street'/><category term='java'/><category term='ajax'/><category term='programming'/><category term='meebo'/><category term='r'/><category term='cufp'/><category term='links'/><category term='concurrency'/><category term='ml'/><category term='harvard'/><category term='c'/><category term='comet'/><category term='server-push'/><category term='complaining'/><category term='cell biology'/><category term='functional programming'/><category term='history'/><category term='parallelism'/><category term='microsoft'/><category term='ocaml'/><category term='lyss'/><category term='webapp'/><category term='cufp2010'/><category term='journal club'/><category term='gotcha'/><category term='serious bzns'/><title type='text'>functional orbitz</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>50</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-4493597070842707635</id><published>2011-10-29T12:48:00.000-04:00</published><updated>2011-10-29T12:48:49.085-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='dart'/><category scheme='http://www.blogger.com/atom/ns#' term='covariance'/><category scheme='http://www.blogger.com/atom/ns#' term='type theory'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><category scheme='http://www.blogger.com/atom/ns#' term='type systems'/><category scheme='http://www.blogger.com/atom/ns#' term='contravariance'/><title type='text'>What is Covariance and Contravariance Anyways?</title><content type='html'>&lt;p&gt;If you have been following the talk around Google's latest language, &lt;a href="http://www.dartlang.org/"&gt;Dart&lt;/a&gt;, then you might have heard things like "covariant arrays are widely regarded as a mistake"(&lt;a href="http://www.reddit.com/r/programming/comments/lkpil/wrapping_my_head_around_optional_typing/c2tixy6"&gt;src&lt;/a&gt;).  But what is covariance?  Why are covariant arrays considered a mistake?  Who has covariant arrays?  Why? &lt;/p&gt;&lt;h3&gt;What is Covariance and Contravariance All About?&lt;/h3&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; X&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;pass&lt;/font&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;Y&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;X&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;zoom&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;self&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;        &lt;b&gt;&lt;font color="#0000FF"&gt;print&lt;/font&gt;&lt;/b&gt; &lt;font color="#FF0000"&gt;'Y.zoom'&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; A&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;    &lt;i&gt;&lt;font color="#9A1900"&gt;# Returns a value of type Y&lt;/font&gt;&lt;/i&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;self&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;        &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;Y&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;B&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;A&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;    &lt;i&gt;&lt;font color="#9A1900"&gt;# Returns a value of type X&lt;/font&gt;&lt;/i&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;self&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;        &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;X&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Takes a value of type A&lt;/font&gt;&lt;/i&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;bar&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;a&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;    y &lt;font color="#990000"&gt;=&lt;/font&gt; a&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;br /&gt;    y&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;zoom&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;font color="#9A1900"&gt;# Call bar with a B&lt;/font&gt;&lt;/i&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#000000"&gt;bar&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;B&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;())&lt;/font&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Is this code safe?  Often, in an OO language, inheritance is used to create a type that looks just like another type, and pass values of this new type to functions that expect the other type and without breaking anything.  So one might expect, looking at this code, that passing a &lt;code&gt;B&lt;/code&gt; to &lt;code&gt;bar&lt;/code&gt; would be safe.  But it isn't.  The problem is &lt;code&gt;B.foo&lt;/code&gt; returns an &lt;code&gt;X&lt;/code&gt; where &lt;code&gt;A.foo&lt;/code&gt; returns a &lt;code&gt;Y&lt;/code&gt;.  &lt;code&gt;bar&lt;/code&gt; then goes on to try to call a member function that only exists in &lt;code&gt;Y&lt;/code&gt;, so the code will fail at runtime.  &lt;code&gt;B&lt;/code&gt; has violated the interface that &lt;code&gt;A&lt;/code&gt; established.  Python doesn't give us any tools to discover this error without executing the code, but statically typed languages like C++ and Java do.  These languages can define the types that member functions of a subclass can take, and return, in order to be valid through covariant and contravariant properties.  The concepts are larger than member functions but it's a good place to start.&lt;/p&gt;&lt;h3&gt;Definitions&lt;/h3&gt;&lt;p&gt;Before we can talk about covariance and contravariance we need to know what subtyping is.  I'll restrict this to classes in an object-orientated language because that's what my knowledge is limited to, but these concepts go beyond that.  An example of a subtype in an OO language would be a class that extends or inherits from another class, for example in C++ you would do &lt;code&gt;class S : public T&lt;/code&gt; for &lt;code&gt;S&lt;/code&gt; to extend &lt;code&gt;T&lt;/code&gt;.  The common way type theorists write this is &lt;code&gt;S &amp;lt;: T&lt;/code&gt;.  This can be read in a few ways: "any term of type &lt;code&gt;S&lt;/code&gt; can safely be used in a context where a term of type &lt;code&gt;T&lt;/code&gt; is expected" or "every value described by &lt;code&gt;S&lt;/code&gt; is also described by &lt;code&gt;T&lt;/code&gt;" (&lt;a href="http://www.amazon.com/Types-Programming-Languages-Benjamin-Pierce/dp/0262162091/ref=sr_1_1?ie=UTF8&amp;qid=1319515999&amp;sr=8-1"&gt;Pierce&lt;/a&gt;, 182).  Thus, &lt;code&gt;S&lt;/code&gt; is a more specific type than &lt;code&gt;T&lt;/code&gt;, and conversely &lt;code&gt;T&lt;/code&gt; is a more generic type than &lt;code&gt;S&lt;/code&gt;.  Given this, covariance and contravariance define when a more specific or more generic type is acceptable in a particular context.&lt;/p&gt;&lt;p&gt;The definition from the wiki &lt;a href="http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Overview_of_covariance.2Fcontravariance_in_some_programming_languages"/&gt;article&lt;/a&gt;:&lt;blockquote&gt;covariance and contravariance refers to the ordering of types from narrower to wider and their interchangeability or equivalence in certain situations&lt;/blockquote&gt;And their definitions:&lt;ul&gt;&lt;li&gt;&lt;b&gt;Covariant&lt;/b&gt; - Given the types &lt;code&gt;S&lt;/code&gt; and &lt;code&gt;T&lt;/code&gt; specified above, covariance is when a more specific type, &lt;code&gt;S&lt;/code&gt;, can be used when a more generic type, &lt;code&gt;T&lt;/code&gt;, is specified.  This applies to functions, a function that returns &lt;code&gt;S&lt;/code&gt; can be used in the same context as a function that returns &lt;code&gt;T&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Contravariant&lt;/b&gt; - When the more generic type, &lt;code&gt;T&lt;/code&gt;, can be used where the more specific type, &lt;code&gt;S&lt;/code&gt;, is specified.  A function that takes a &lt;code&gt;T&lt;/code&gt; can be used in the same context as a function that takes a &lt;code&gt;S&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Invariant&lt;/b&gt; - The type specified is the only type that can be used.&lt;/li&gt;&lt;/ul&gt;My method for remembering the distinction is contravariant is larger than covariant, so it means narrower to wider.&lt;/p&gt;&lt;h3&gt;Covariant Example&lt;/h3&gt;&lt;p&gt;Consider this example from C++:&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;X&lt;/font&gt; &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Y&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; X &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Z&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; Y &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;A&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;  &lt;b&gt;&lt;font color="#0000FF"&gt;virtual&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Y&lt;/font&gt; &lt;font color="#990000"&gt;*&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;Y&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;B&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; A &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;  &lt;b&gt;&lt;font color="#0000FF"&gt;virtual&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Z&lt;/font&gt; &lt;font color="#990000"&gt;*&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;Z&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Here we have three classes &lt;code&gt;X&lt;/code&gt;, &lt;code&gt;Y&lt;/code&gt;, and &lt;code&gt;Z&lt;/code&gt; which we will return from a virtual function in classes &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt;.  This code is valid because &lt;code&gt;B::foo&lt;/code&gt; is returning a narrower type than &lt;code&gt;A::foo&lt;/code&gt; because &lt;code&gt;Z&lt;/code&gt; is a subtype of &lt;code&gt;Y&lt;/code&gt;.  But what happens if we make &lt;code&gt;B::foo&lt;/code&gt; return a wider type?&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;X&lt;/font&gt; &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Y&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; X &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Z&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; Y &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;A&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;  &lt;b&gt;&lt;font color="#0000FF"&gt;virtual&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Y&lt;/font&gt; &lt;font color="#990000"&gt;*&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;Y&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;B&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; A &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;  &lt;b&gt;&lt;font color="#0000FF"&gt;virtual&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;X&lt;/font&gt; &lt;font color="#990000"&gt;*&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;X&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;blockquote&gt;$ g++ -W -Wall -ansi -pedantic -c foo.cc&lt;br /&gt;foo.cc:12: error: invalid covariant return type for ‘virtual X* B::foo()'&lt;br /&gt;foo.cc:7: error:   overriding ‘virtual Y* A::foo()’&lt;/blockquote&gt;&lt;/pre&gt;&lt;/p&gt;&lt;h3&gt;Contravariant Example&lt;/h3&gt;&lt;p&gt;As we saw above, one can be covariant on return types, but what about on parameters to a member function?  One has to be the opposite actually: contravariant.  Unfortunately, gcc (or the version I'm using at least) doesn't give us an error about contravariance, instead we have to add a little bit of code using &lt;code&gt;B::foo&lt;/code&gt; to see the problem:&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;X&lt;/font&gt; &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Y&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; X &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Z&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; Y &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;A&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;  &lt;b&gt;&lt;font color="#0000FF"&gt;virtual&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;void&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#008080"&gt;Y&lt;/font&gt; &lt;font color="#990000"&gt;&amp;amp;&lt;/font&gt;y&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{ }&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;B&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; A &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;  &lt;b&gt;&lt;font color="#0000FF"&gt;virtual&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;void&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#008080"&gt;X&lt;/font&gt; &lt;font color="#990000"&gt;&amp;amp;&lt;/font&gt;x&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{ }&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#009900"&gt;int&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;main&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;  &lt;font color="#008080"&gt;B&lt;/font&gt; b&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;  &lt;font color="#008080"&gt;Y&lt;/font&gt; y&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;  &lt;font color="#008080"&gt;Z&lt;/font&gt; z&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;  &lt;br /&gt;  b&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;y&lt;font color="#990000"&gt;);&lt;/font&gt;&lt;br /&gt;  b&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;z&lt;font color="#990000"&gt;);&lt;/font&gt;&lt;br /&gt;  &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This behaves as we would expect.  We can call &lt;code&gt;B::foo&lt;/code&gt; with an &lt;code&gt;X&lt;/code&gt;, &lt;code&gt;Y&lt;/code&gt;, or &lt;code&gt;Z&lt;/code&gt;, since &lt;code&gt;B::foo&lt;/code&gt; takes the superclass to all of them (&lt;code&gt;X&lt;/code&gt;).  But what if we modify it to take &lt;code&gt;Z&lt;/code&gt;:&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;X&lt;/font&gt; &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Y&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; X &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Z&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; Y &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;A&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;  &lt;b&gt;&lt;font color="#0000FF"&gt;virtual&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;void&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#008080"&gt;Y&lt;/font&gt; &lt;font color="#990000"&gt;&amp;amp;&lt;/font&gt;y&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{ }&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;B&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; A &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;  &lt;b&gt;&lt;font color="#0000FF"&gt;virtual&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;void&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#008080"&gt;Z&lt;/font&gt; &lt;font color="#990000"&gt;&amp;amp;&lt;/font&gt;z&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{ }&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#009900"&gt;int&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;main&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;  &lt;font color="#008080"&gt;B&lt;/font&gt; b&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;  &lt;font color="#008080"&gt;Y&lt;/font&gt; y&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;  &lt;font color="#008080"&gt;Z&lt;/font&gt; z&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;  &lt;br /&gt;  b&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;y&lt;font color="#990000"&gt;);&lt;/font&gt;&lt;br /&gt;  b&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;z&lt;font color="#990000"&gt;);&lt;/font&gt;&lt;br /&gt;  &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; &lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;blockquote&gt;$ g++ -W -Wall -ansi -pedantic  foo.cc&lt;br /&gt;foo.cc: In function ‘int main()’:&lt;br /&gt;foo.cc:24: error: no matching function for call to ‘B::foo(Y&amp;)’&lt;br /&gt;foo.cc:14: note: candidates are: virtual void B::foo(Z&amp;)&lt;/pre&gt;&lt;/blockquote&gt;The error we get is about &lt;code&gt;B::foo(Y&amp;)&lt;/code&gt; not existing.  Because &lt;code&gt;Z&lt;/code&gt; is a narrower type than &lt;code&gt;Y&lt;/code&gt;, we have broken the interface of &lt;code&gt;A&lt;/code&gt;, so &lt;code&gt;B&lt;/code&gt; is no longer a valid substitute for &lt;code&gt;A&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;But You Already Knew This&lt;/h3&gt;&lt;p&gt;Intuitively, this is the way that makes the most sense.  The use case for inheritance is generally when a function takes a certain type as input but you want to pass your own type.  In order to ensure that the function, &lt;code&gt;bar&lt;/code&gt;, can successfully use the type you pass it, all of the methods that &lt;code&gt;bar&lt;/code&gt; calls on your type need to take types that &lt;code&gt;bar&lt;/code&gt; can pass to it and return types that &lt;code&gt;bar&lt;/code&gt; knows how to use.  Take this code:&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;X&lt;/font&gt; &lt;font color="#FF0000"&gt;{}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Y&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; X &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;/* ... */&lt;/font&gt;&lt;/i&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Z&lt;/font&gt; &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; Y &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;/* ... */&lt;/font&gt;&lt;/i&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;A&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;  &lt;b&gt;&lt;font color="#0000FF"&gt;virtual&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Y&lt;/font&gt; &lt;font color="#990000"&gt;*&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#008080"&gt;Y&lt;/font&gt; &lt;font color="#990000"&gt;&amp;amp;&lt;/font&gt;y&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt; &lt;i&gt;&lt;font color="#9A1900"&gt;/* ... */&lt;/font&gt;&lt;/i&gt; &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#009900"&gt;void&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;bar&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#008080"&gt;A&lt;/font&gt; &lt;font color="#990000"&gt;&amp;amp;&lt;/font&gt;a&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;  &lt;font color="#008080"&gt;Y&lt;/font&gt; y&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;  &lt;font color="#008080"&gt;Y&lt;/font&gt; &lt;font color="#990000"&gt;*&lt;/font&gt;y_ptr &lt;font color="#990000"&gt;=&lt;/font&gt; a&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;y&lt;font color="#990000"&gt;);&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;If you were to pass your own type, &lt;code&gt;B&lt;/code&gt;, which is a subtype of &lt;code&gt;A&lt;/code&gt; (that is, &lt;code&gt;B &amp;lt;: A&lt;/code&gt;) the only way we can implement &lt;code&gt;B::foo&lt;/code&gt; such that our function &lt;code&gt;bar&lt;/code&gt; still works is if &lt;code&gt;B::foo&lt;/code&gt; takes an object as input that is a supertype to &lt;code&gt;Y&lt;/code&gt; and returns a type that is a subtype of &lt;code&gt;Y&lt;/code&gt;.  Consider if it were valid for &lt;code&gt;B::foo&lt;/code&gt; to want a &lt;code&gt;Z&lt;/code&gt;.  &lt;code&gt;B::foo&lt;/code&gt; could try to call a member function that exists only in &lt;code&gt;Z&lt;/code&gt;.  But since &lt;code&gt;bar&lt;/code&gt; is passing an object of type &lt;code&gt;X&lt;/code&gt;, which we can't guarantee has member function that exists only in &lt;code&gt;Z&lt;/code&gt;, our code would be unsafe.  A similar argument can be made with the return type of &lt;code&gt;Y&lt;/code&gt; and &lt;code&gt;X&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;What About Arrays?&lt;/h3&gt;&lt;p&gt;Now that we get what these terms mean, how do they apply when it comes to arrays of objects?  In C++, arrays are not covariant, however in Java they are:&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Test&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;static&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;void&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;        Test&lt;font color="#990000"&gt;[]&lt;/font&gt; tests &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; Test&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;];&lt;/font&gt;&lt;br /&gt;        Object&lt;font color="#990000"&gt;[]&lt;/font&gt; objects &lt;font color="#990000"&gt;=&lt;/font&gt; tests&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;    &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This code looks innocent enough, but there is a problem: what if I modify &lt;code&gt;objects&lt;/code&gt;?  For example:&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;class&lt;/font&gt;&lt;/b&gt; &lt;font color="#008080"&gt;Test&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;public&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;static&lt;/font&gt;&lt;/b&gt; &lt;font color="#009900"&gt;void&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;        Test&lt;font color="#990000"&gt;[]&lt;/font&gt; tests &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; Test&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;];&lt;/font&gt;&lt;br /&gt;        Object&lt;font color="#990000"&gt;[]&lt;/font&gt; objects &lt;font color="#990000"&gt;=&lt;/font&gt; tests&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;        objects&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;new&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;Integer&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;&lt;br /&gt;    &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This code compiles fine, but executing it gives the following error (changed &lt;code&gt;foo&lt;/code&gt; to &lt;code&gt;main&lt;/code&gt; in order to run it):&lt;pre&gt;&lt;blockquote&gt;Exception in thread "main" java.lang.ArrayStoreException: java.lang.Integer&lt;br /&gt; at Test.main(Test.java:5)&lt;/blockquote&gt;&lt;/pre&gt;This is what people mean when they refer to covariant arrays being a mistake.  A compile-time check has been moved to runtime, which means you don't know if your code is safe without running it.  Note, though, that what makes covariant arrays a problem in Java is modifying the array, not reading it.  If we could somehow ensure that the &lt;code&gt;objects&lt;/code&gt; array was immutable, covariant arrays in Java would be safe.  Why does Java have covariant arrays then?  Originally Java did not have parametric polymorphism (generics), without covariant arrays it would be impossible to write a generic function that copies one array to another.  Instead one would have to write a copy function for every type of array they wish to copy (&lt;a href="http://www.amazon.com/Types-Programming-Languages-Benjamin-Pierce/dp/0262162091/ref=sr_1_1?ie=UTF8&amp;qid=1319515999&amp;sr=8-1"&gt;Pierce&lt;/a&gt;, 188).  While the behavior is not ideal, at the least the JVM can provide some level of safety by performing type checks at runtime.&lt;/p&gt;&lt;p&gt;Unfortunately, I cannot shed any light on why Dart has covariant arrays.  It has done everything from befuddle to enrage type theorists (null pointers, in 2011, why?!).  Dart appears to support parametric polymorphism, the lack of which lead to Java having covariant arrays.  It is a shame that Dart seems to be repeating, what some, would classify as mistakes for no obvious benefit.  Dart is not the only one sinning though, C# also has covariant arrays and seems to have simply copied them from Java.&lt;/p&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;I'm no type theorist, this post went through several iterations with comments and corrections from friends smarter than I, so this post only scratches the surface of covariance and contravariance.  Hopefully it is enough to understand what people are referring to when the terms come up in casual Reddit conversation.  If you're interested in more, Benjamin Pierce's book, &lt;i&gt;&lt;a href="http://www.amazon.com/Types-Programming-Languages-Benjamin-Pierce/dp/0262162091/ref=sr_1_1?ie=UTF8&amp;qid=1319515999&amp;sr=8-1"&gt;Types and Programming Languages&lt;/a&gt;&lt;/i&gt;, has an entire chapter dedicated to subtyping.  While I haven't finished the book yet, what I have read is excellent.  Even if you skip the math that looks complicated you will come out better.&lt;/p&gt;&lt;h3&gt;Thanks&lt;/h3&gt;&lt;p&gt;Special thanks to &lt;a href="http://twitter.com/#!/dklee"&gt;@dklee&lt;/a&gt;.  Much of this post is based off of emails we have exchanged.  Thanks to &lt;a href="http://twitter.com/#!/j2labs"&gt;@j2labs&lt;/a&gt;, and &lt;a href="http://twitter.com/#!/apgwoz"&gt;@apgwoz&lt;/a&gt;, as well, for help in making this post.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-4493597070842707635?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/4493597070842707635/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2011/10/what-is-covariance-and-contravariance.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4493597070842707635'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4493597070842707635'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2011/10/what-is-covariance-and-contravariance.html' title='What is Covariance and Contravariance Anyways?'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-1675438079357266218</id><published>2011-10-02T22:41:00.002-04:00</published><updated>2011-10-02T22:43:58.804-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='wrong'/><category scheme='http://www.blogger.com/atom/ns#' term='node'/><category scheme='http://www.blogger.com/atom/ns#' term='twisted'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='nodejs'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Your Favorite Language is Probably Terrible at Concurrency too</title><content type='html'>The internet has been ablaze with posts on NodeJS, to some people's joy and to others chagrin.  Some have claimed that Node solves a long standing problem in concurrency, &lt;a href="http://www.betabeat.com/2011/04/20/nodejitsu-raises-750k-from-east-and-west-coast-vcs/"&gt;saying&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;People are starting to build more on Node.js because it’s superior and it solves these problems that have always existed. I/O has been done wrong for the last 30 years&lt;/blockquote&gt;&lt;br /&gt;In my opinion, Node is bad at concurrency, and guess what?  Your language probably isn't any better.  But let's make sure we're on the same page first.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Language/Framework&lt;/i&gt; - Most languages do not have concurrency as a first class citizen.  So when I say "your language is bad at concurrency", what I really mean is "the options available for doing concurrent things in your language are bad".  The former just rolls off your tongue better.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Concurrency&lt;/i&gt; - What do I mean by concurrency?  I mean a model by which you can define actions that can happen at the same time.  That could mean running multiple pieces of code in parallel or interleaving them.  Specifically in this post I am concerned with solving problems where the number of things you want to do concurrently is significantly larger than the number of cores you have.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;There are a lot of options for concurrency out there.  You may have heard of things like &lt;a href="http://en.wikipedia.org/wiki/Pi_calculus"&gt;Pi calculus&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Join_calculus"&gt;Join calculus&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Communicating_sequential_processes"&gt;Communicating Sequential Processes&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Event_loop"&gt;Event-loops&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Coroutines"&gt;Coroutines&lt;/a&gt;.  Your language probably has an implementation of one of these, or a conceptual subset.  NodeJS and Twisted implement an event-loop.  Coroutines is the path Python's Gevent has taken, as well as libraries for Ruby, C, and C++.  Go has chosen Communicating Sequential Processes.  But all these distinctions aren't important unless I can say what I consider a good solution to concurrency.&lt;br /&gt;&lt;br /&gt;Ideally, a good solution should have the following properties:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Scaling&lt;/i&gt; - If you are writing concurrent software you've already decided handling one thing at a time is not a scalable solution, so now you want to handle multiple things at a time.  An ideal solution should scale to the limits of the machine.  That means making use of multiple cores, if available.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Reasoning&lt;/i&gt; - It should be easy for a reader of your code to reason about what it does.  Edge cases and gotcha's should be limited.  Preferably one shouldn't even be aware of the concurrent aspects of the code unless they need to be.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Debugging&lt;/i&gt; - Debugging should not be painful.  Standard tools like stacktraces should be meaningful.  Tracing the path a piece of code takes shouldn't be harder than launching the space shuttle.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;My claim is that very few concurrent solutions meet these criteria.  But let me be clear, I'm not saying this is the only way you should judge selecting a solution.  There is a Python library that does basically everything you think you need and it will be really hard to re-implement that functionality in another language?  Well, maybe dealing with Python's concurrency shortcomings is less work than rewriting the library.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Scaling&lt;/h2&gt;Most languages were built for writing serial code.  Memory is accessible by any piece of code in the process and it is assumed that nothing interesting happens between two function calls.  But modern computers are not fast enough to do all the work programmers want them to do in serial and these languages have a lot of momentum behind them.  For valid reasons, it is challenging to just move to another solution.  Instead, we duct tape concurrency on top of these serial languages.  One problem is that some of these languages can't even run code in parallel (that is, have two functions running at the same exact time) even if they wanted to.  Python and Ocaml have a global lock that restricts this.  In other languages it's just too much coordination to do safely.  In C and C++ it can be too hard and time consuming to coordinate distributing concurrent work over multiple threads.  For this reason, many mainstream solutions to concurrency are limited to running on a single core.  It's insane, right?  I can buy a laptop with, ostensibly, 8 cores now, yet a program written in most mainstream languages cannot make use of more than one.&lt;br /&gt;&lt;br /&gt;For this reason, most solutions fail to be &lt;i&gt;scalable&lt;/i&gt;.  For example, NodeJS, Twisted, Ocaml/Lwt, and Gevent: from the point-of-view of a user of these frameworks, their code not only cannot run on multiple cores, but it depends on it.  Consider some Twisted code that downloads N web pages and appends the result to a list:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;downloadUrls&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;urls&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;    d &lt;font color="#990000"&gt;=&lt;/font&gt; defer&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;Deferred&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;br /&gt;    ret &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#990000"&gt;[]&lt;/font&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;_returnWhenDone&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;_&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;        &lt;b&gt;&lt;font color="#0000FF"&gt;if&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;len&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;ret&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;==&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;len&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;urls&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;            d&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;callback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;ret&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;for&lt;/font&gt;&lt;/b&gt; url &lt;b&gt;&lt;font color="#0000FF"&gt;in&lt;/font&gt;&lt;/b&gt; urls&lt;font color="#990000"&gt;:&lt;/font&gt;&lt;br /&gt;        downloadDefer &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;downloadUrlAsString&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;url&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;        downloadDefer&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;addCallback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;lambda&lt;/font&gt;&lt;/b&gt; s &lt;font color="#990000"&gt;:&lt;/font&gt; ret&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;append&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;s&lt;font color="#990000"&gt;))&lt;/font&gt;&lt;br /&gt;        downloadDefer&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;addCallback&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;_returnWhenDone&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;return&lt;/font&gt;&lt;/b&gt; d&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Ignoring my failure to handle failures, this code is acceptable Twisted, and it could not work if Python suddenly got the ability to run code on multiple cores and Twisted used it.  The reason being, there is no coordination around the &lt;code&gt;ret.append(s)&lt;/code&gt; line.  What if two threads were to try to &lt;code&gt;append&lt;/code&gt; to &lt;code&gt;ret&lt;/code&gt; at the same time?  NodeJS and Gevent have the same idea in mind.  Almost no data access is surrounded by a mechanism to coordinate multiple pieces of code accessing it at the same time.  The result is, none of the code using these frameworks can be run on multiple cores.  If CPython or V8 got multicore support it would take a rewrite of all of the code to make use of it.&lt;br /&gt;&lt;br /&gt;But, you say, who cares?  "I can just spin up N instances of my program, where N is the number of cores on my machine.  I can easily scale that way".  You can't even get concurrency right and now you want to move into distributed programming? Who are you fooling?  But seriously, the problem is your code now needs to be "location aware".  If you want to do something with object X, you have to be aware of where object X lives.  This adds another layer of complexity to your system.  Without a good way of communicating between instances you are limited to solving embarrassingly parallel problems or pushing the concurrency to another software layer.  Either way, you aren't actually solving the problem with your framework.  Luckily, a lot of what people want concurrency for is serving webpages, which requires almost no interprocess communication right now.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Reasoning&lt;/h2&gt;No matter how you slice it, writing concurrent code is hard.  When it comes to serial code, looking at it and knowing what it does is as simple as understanding how each function operates given the current state of the program.  But with concurrent code, the state of the program is changing while a function runs.  Understanding a concurrent program involves understanding how the concurrent components are interacting with each other.  Some solutions make this easier than others.&lt;br /&gt;&lt;br /&gt;Take the &lt;a href="https://github.com/koush/node/wiki/%22async%22-support-in-node.js"&gt;following&lt;/a&gt; piece of example NodeJS code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; db &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;require&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'somedatabaseprovider'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;&lt;br /&gt;app&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;get&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'/price'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;req&lt;font color="#990000"&gt;,&lt;/font&gt; res&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;  db&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;openConnection&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'host'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;12345&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;,&lt;/font&gt; conn&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;    conn&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;query&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'select * from products where id=?'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;req&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;param&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'product'&lt;/font&gt;&lt;font color="#990000"&gt;)],&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;err&lt;font color="#990000"&gt;,&lt;/font&gt; results&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;      conn&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;close&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt;&lt;br /&gt;      res&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;send&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;results&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]);&lt;/font&gt;&lt;br /&gt;    &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;&lt;br /&gt;  &lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The amount of syntax is enormous.  There is a huge amount of line noise for what should look, at worst, like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; db &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;require&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'somedatabaseprovider'&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;&lt;br /&gt;app&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;get&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'/price'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;function&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;req&lt;font color="#990000"&gt;,&lt;/font&gt; res&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#FF0000"&gt;{&lt;/font&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; conn &lt;font color="#990000"&gt;=&lt;/font&gt; db&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;openConnection&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'host'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;12345&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;var&lt;/font&gt;&lt;/b&gt; result &lt;font color="#990000"&gt;=&lt;/font&gt; conn&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;query&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'select * from products where id=?'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;req&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;param&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'product'&lt;/font&gt;&lt;font color="#990000"&gt;)])&lt;/font&gt;&lt;br /&gt;    conn&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;close&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;();&lt;/font&gt;&lt;br /&gt;    res&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;send&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;results&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]);&lt;/font&gt;&lt;br /&gt;&lt;font color="#FF0000"&gt;}&lt;/font&gt;&lt;font color="#990000"&gt;);&lt;/font&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;If you want to add proper error handling, the situation gets worse with callback code.  Twisted has attempted to solve this by encapsulating code flow in an object called a &lt;code&gt;Deferred&lt;/code&gt;, but the problem remains: a unit of work in callback-based code is not a function, like one is used to in serial code, it is work to do between events.  Like the above example code showed, there isn't a function that connects to a db, does a query, and returns the result.  There is a function to open a db connection, another function for when that is done and to do the db query, and another function to handle the result.  You have defined three functions where you previously needed one.  More importantly, you have to define functions not because it makes your code clearer but because the framework requires it.&lt;br /&gt;&lt;br /&gt;Given how negatively this affects code, there are a lot of attempted solutions.  Twisted, for example, allows one to use the &lt;code&gt;defer.inlineCallbacks&lt;/code&gt; decorator so a function can use generators to express asynchronous code.  Our previous NodeJS code might look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;@defer&lt;font color="#990000"&gt;.&lt;/font&gt;inlineCallbacks&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;handlePrice&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;req&lt;font color="#990000"&gt;,&lt;/font&gt; res&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;    conn &lt;font color="#990000"&gt;=&lt;/font&gt; yield db&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;openConnection&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'host'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;12345&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;    result &lt;font color="#990000"&gt;=&lt;/font&gt; yield conn&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;query&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'select * from products where id=?'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;req&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;param&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'product'&lt;/font&gt;&lt;font color="#990000"&gt;)])&lt;/font&gt;&lt;br /&gt;    yield conn&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;close&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;br /&gt;    res&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;send&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;results&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;])&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;app&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;get&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'/price'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; handlePrice&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In many ways this is an improvement but it does have its limitations.&lt;br /&gt;&lt;br /&gt;The NodeJS community has been at work solving this problem for themselves too.  One person &lt;a href="https://github.com/koush/node/wiki/%22async%22-support-in-node.js"&gt;added&lt;/a&gt; coroutines to V8, and gave it a C#-like syntax.  OKCupid gave us &lt;a href="http://tamejs.org/"&gt;TameJS&lt;/a&gt;.  Both of these solutions have their problems which are deal breakers for many.&lt;br /&gt;&lt;br /&gt;There are also, less complete, solutions like &lt;a href="https://github.com/creationix/step"&gt;Step&lt;/a&gt;.  But library solutions, like Step, only give you access to a subset of functionality you would get from the sequential code you really want to write.  To do that you need a full &lt;a href="http://en.wikipedia.org/wiki/Continuation_passing_style"&gt;CPS&lt;/a&gt; transformation (which is what TameJS gives you, at a cost of debugging).  This is actually how the syntax extensions for Ocaml/Lwt work.  The previous NodeJS code might look like this in Ocaml/Lwt (the relevant part is that &lt;code&gt;lwt&lt;/code&gt; causes a CPS transformation to turn the code into the appropriate callback-based code):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;let&lt;/font&gt;&lt;/b&gt; handle_price req res &lt;font color="#990000"&gt;=&lt;/font&gt;&lt;br /&gt;  lwt conn &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000080"&gt;DB&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;open_connection &lt;font color="#FF0000"&gt;"host"&lt;/font&gt; &lt;font color="#993399"&gt;12345&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;in&lt;/font&gt;&lt;/b&gt;&lt;br /&gt;  lwt result &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;b&gt;&lt;font color="#000080"&gt;DB&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;query conn &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000080"&gt;SQL&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;sprintf &lt;font color="#FF0000"&gt;"select * from products where id=?"&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;req#param &lt;font color="#FF0000"&gt;"product"&lt;/font&gt;&lt;font color="#990000"&gt;))&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;in&lt;/font&gt;&lt;/b&gt;&lt;br /&gt;  &lt;b&gt;&lt;font color="#000080"&gt;DB&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;close conn&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;  res#send results&lt;font color="#990000"&gt;.[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;]&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#000080"&gt;App&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;.&lt;/font&gt;get &lt;font color="#FF0000"&gt;"/price"&lt;/font&gt; handle_price&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This is one reason for Gevent/Eventlet's popularity in Python.  Gevent uses coroutines to give you asynchronous code that looks sequential.  The trick is, underneath the hood, some function calls actually result in all of the state for your current function call being saved, another one switched to, executed, rinse, repeat.  Gevent has a cooperative scheduler that tries to intelligently decide which function to switch to.&lt;br /&gt;&lt;br /&gt;Say you want to write the earlier NodeJS code in sequential Python, you might get:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;handlePrice&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;req&lt;font color="#990000"&gt;,&lt;/font&gt; res&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;    conn &lt;font color="#990000"&gt;=&lt;/font&gt; db&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;openConnection&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'host'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#993399"&gt;12345&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;    result &lt;font color="#990000"&gt;=&lt;/font&gt; conn&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;query&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'select * from products where id=?'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; &lt;font color="#990000"&gt;[&lt;/font&gt;req&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;param&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'product'&lt;/font&gt;&lt;font color="#990000"&gt;)])&lt;/font&gt;&lt;br /&gt;    conn&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;close&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;br /&gt;    res&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;send&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;results&lt;font color="#990000"&gt;[&lt;/font&gt;&lt;font color="#993399"&gt;0&lt;/font&gt;&lt;font color="#990000"&gt;])&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;app&lt;font color="#990000"&gt;.&lt;/font&gt;&lt;b&gt;&lt;font color="#000000"&gt;get&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#FF0000"&gt;'/price'&lt;/font&gt;&lt;font color="#990000"&gt;,&lt;/font&gt; handlePrice&lt;font color="#990000"&gt;)&lt;/font&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;How would this look in Gevent?  Exactly the same.  The &lt;code&gt;openConnection&lt;/code&gt; and &lt;code&gt;query&lt;/code&gt; functions have an I/O call which actually jumps back to the Gevent scheduler so it can do something else while the I/O happens.&lt;br /&gt;&lt;br /&gt;But Gevent is not without its cost when it comes to reasoning about code.  Consider this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;def&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color="#000000"&gt;foo&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;data&lt;font color="#990000"&gt;):&lt;/font&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;print&lt;/font&gt;&lt;/b&gt; data&lt;font color="#990000"&gt;.&lt;/font&gt;bar&lt;br /&gt;    &lt;b&gt;&lt;font color="#000000"&gt;do_something&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;()&lt;/font&gt;&lt;br /&gt;    &lt;b&gt;&lt;font color="#0000FF"&gt;print&lt;/font&gt;&lt;/b&gt; data&lt;font color="#990000"&gt;.&lt;/font&gt;bar&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Looking at this code, will the same value be printed twice?  The answer is: no idea.  Even though &lt;code&gt;do_something&lt;/code&gt; does not take &lt;code&gt;data&lt;/code&gt; as input, it could do something that causes Gevent to context switch to another function, another function which also has access to &lt;code&gt;data&lt;/code&gt; and modifies it.  There is no way to tell, simply by looking at the code, if it will context switch or not.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Debugging&lt;/h2&gt;The previous Gevent code is printing out two different values for &lt;code&gt;data.bar&lt;/code&gt; and you don't want this, how do you fix it?  The first thing you might try, from your serial programming days, is a debugger.  But that might not work very well.  Why?  You're in concurrent-land now, multiple things are happening at once!  That means timing is important.  If you set a break point somewhere, you've disrupted the time things happen and your program could take a completely different path, not the one you want to debug.&lt;br /&gt;&lt;br /&gt;If you're smart and you control access to &lt;code&gt;data.bar&lt;/code&gt; through function calls, you can do some printf debugging.  Perhaps print out a stacktrace when one modifies it.  But let's say, even those prints are causing the timing of your program to change, so now &lt;code&gt;data.bar&lt;/code&gt; is coming out as the same value at each &lt;code&gt;print&lt;/code&gt;.  What do you do?!&lt;br /&gt;&lt;br /&gt;The point is, debugging concurrent code can be very hard.  Event-loop code adds another problem to debugging: your code doesn't have a linear path.  If you could visualize sequential code, it would be a line.  You start at point A, you do the things in order to get to point B, at any point if you have an error your callstack represents the path you took to get there.  Event-loop code always needs to hit the event-loop for a blocking call though.  The callstack you see is always limited to the path from the last event you got.  A callstack in the code handling a database query may not contain the how you got there.  If that query is part of a piece of fairly generic code you don't have many leads to go on to track it down.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Who got it right then?&lt;/h3&gt;Three languages come to mind: Erlang, Oz, Haskell.  There are more out there but I'm not omnipotent.  In my opinion, these languages are capable of the three properties I previously mentioned.  Right now you are probably rolling your eyes and saying "I should have known, one of THOSE guys".  But my argument is conservative: based on the properties that I believe are important for concurrent solution to be good, these languages excel (or are capable of it) at them.  Real world problems contain more than just concurrency issues though, so this does not mean you're wrong to use a language that doesn't meet my criteria, but it does mean you are sacrificing something.  Perhaps that sacrifice is acceptable.  But don't fool yourself into thinking your language is not terrible at concurrency, because it probably is.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-1675438079357266218?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/1675438079357266218/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2011/10/your-favorite-language-is-probably.html#comment-form' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1675438079357266218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1675438079357266218'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2011/10/your-favorite-language-is-probably.html' title='Your Favorite Language is Probably Terrible at Concurrency too'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-3330657000794387461</id><published>2011-07-31T14:35:00.003-04:00</published><updated>2011-07-31T14:44:21.731-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pointers'/><category scheme='http://www.blogger.com/atom/ns#' term='gotcha'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>C Gotcha Of The Day: Pointers aren't integers</title><content type='html'>The C standard is clear that pointers are not required to be convertible to or from an integer.&lt;br /&gt;&lt;br /&gt;Section 6.3.2.3.5-6 in the C99 draft&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;An integer may be converted to any pointer type. The result is implementation-defined, might not be properly aligned, and might not point to an entity of the referenced type.)&lt;br /&gt;&lt;br /&gt;Any pointer type may be converted to an integer type; the result is implementation-deﬁned. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.&lt;/blockquote&gt;&lt;br /&gt;Basically, you can't depend on the following code doing anything useful:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;tt&gt;&lt;font color="#009900"&gt;int&lt;/font&gt; &lt;font color="#990000"&gt;*&lt;/font&gt;p &lt;font color="#990000"&gt;=&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#009900"&gt;int&lt;/font&gt;&lt;font color="#990000"&gt;*)&lt;/font&gt;&lt;font color="#993399"&gt;0xff&lt;/font&gt;&lt;font color="#990000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The C standard does not define a machine with a flat memory model.  Old Intel systems are an example of a non flat memory model, they had a segmented memory model where a pointer needed a segment and offset.&lt;br /&gt;&lt;br /&gt;Conversion to a string is also implementation defined in C, from 7.19.6.1 &lt;code&gt;fprintf&lt;/code&gt;, the section on the &lt;code&gt;%p&lt;/code&gt; format specifier:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printable characters, in an implementation-defined manner.&lt;/blockquote&gt;&lt;br /&gt;And from &lt;code&gt;fscanf&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Matches an implementation-defined set of sequences, which should be the same as the set of sequences that may be produced by the %p conversion of the fprintf function. The corresponding argument shall be a pointer to a pointer to void. The interpretation of the input item is implementation-defined. If the input item is a value converted earlier during the same program execution, the pointer that results shall compare equal to that value; otherwise the behavior of the %p conversion is undefined. &lt;/blockquote&gt;&lt;br /&gt;It does appear that even though the result of &lt;code&gt;%p&lt;/code&gt; is implementation defined, it is guaranteed that you can &lt;code&gt;fprintf&lt;/code&gt; and &lt;code&gt;fscanf&lt;/code&gt; pointers and get back the same result inside the same program execution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-3330657000794387461?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/3330657000794387461/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2011/07/c-gotcha-of-day-pointers-arent-integers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/3330657000794387461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/3330657000794387461'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2011/07/c-gotcha-of-day-pointers-arent-integers.html' title='C Gotcha Of The Day: Pointers aren&apos;t integers'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-3038888074999624086</id><published>2011-07-29T13:26:00.000-04:00</published><updated>2011-07-29T13:26:18.857-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gotcha'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>C Gotcha Of The Day: ptrdiff_t</title><content type='html'>Excerpt from C99 Draft (AFAIK this has not changed):&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The size of the result is implementation-deﬁned, and its type (a signed integer type) is &lt;code&gt;ptrdiff_t&lt;/code&gt; deﬁned in the &lt;code&gt;&amp;lt;stddef.h&amp;gt;&lt;/code&gt; header. If the result is not representable in an object of that type, the behavior is undefined. In other words, if the expressions &lt;code&gt;P&lt;/code&gt; and &lt;code&gt;Q&lt;/code&gt; point to, respectively, the i-th and j-th elements of an array object, the expression &lt;code&gt;(P) - (Q)&lt;/code&gt; has the value i−j provided the value fits in an object of type &lt;code&gt;ptrdiff_t&lt;/code&gt;.&lt;/blockquote&gt;&lt;br /&gt;That means, while the type &lt;code&gt;size_t&lt;/code&gt; is capable of expressing the size of any object, you cannot guarantee that the subtraction of two pointers inside your object will result in defined behavior. That is because &lt;code&gt;ptrdiff_t&lt;/code&gt; is signed (so it can give you the direction of the difference) and &lt;code&gt;size_t&lt;/code&gt; is unsigned. You can use the macros &lt;code&gt;PTRDIFF_MAX&lt;/code&gt; and &lt;code&gt;SIZE_MAX&lt;/code&gt; to determine if your subtraction is safe though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-3038888074999624086?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/3038888074999624086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2011/07/c-gotcha-of-day-ptrdifft.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/3038888074999624086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/3038888074999624086'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2011/07/c-gotcha-of-day-ptrdifft.html' title='C Gotcha Of The Day: ptrdiff_t'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-7574585944859958260</id><published>2011-05-03T13:31:00.000-04:00</published><updated>2011-05-03T13:31:32.030-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scoping'/><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='complaining'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Sometimes I forget the full degree in which Python's "scoping" is broken.</title><content type='html'>&lt;blockquote&gt;&gt;&gt;&gt; [s for s in [1, 2,3]]&lt;br /&gt;[1, 2, 3]&lt;br /&gt;&gt;&gt;&gt; s&lt;br /&gt;3&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-7574585944859958260?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/7574585944859958260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2011/05/sometimes-i-forget-full-degree-in-which.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7574585944859958260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7574585944859958260'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2011/05/sometimes-i-forget-full-degree-in-which.html' title='Sometimes I forget the full degree in which Python&apos;s &quot;scoping&quot; is broken.'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-4290907213630568419</id><published>2011-04-27T22:53:00.003-04:00</published><updated>2011-05-02T10:36:34.724-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional programming'/><category scheme='http://www.blogger.com/atom/ns#' term='ocaml'/><category scheme='http://www.blogger.com/atom/ns#' term='parallelism'/><category scheme='http://www.blogger.com/atom/ns#' term='ml'/><category scheme='http://www.blogger.com/atom/ns#' term='journal club'/><title type='text'>[JC] Efficient Parallel Programming in Poly/ML and Isabelle/ML</title><content type='html'>Authors: David C.J. Matthews and Makarius Wenzel&lt;br /&gt;URL: &lt;a href="http://www4.in.tum.de/~wenzelm/papers/parallel-ml.pdf"&gt;http://www4.in.tum.de/~wenzelm/papers/parallel-ml.pdf&lt;/a&gt;&lt;br /&gt;Year: 2010&lt;br /&gt;&lt;br /&gt;I had not heard of Poly/ML or Isabelle/ML prior to reading this paper.  I tried to do a bit of background research to get an idea for it, but I may have gotten some details wrong.  If I made any mistakes below I will be happy to correct them.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;The Paper&lt;/h1&gt;&lt;br /&gt;Poly/ML is a full implementation of Standard ML originally developed by David Matthews.  Larry Paulson was an early adopter and implemented the Isabelle theorem prover.  Isabelle/ML is the implementation of Isabelle on Poly/ML.  Poly/ML was originally implemented with a single threaded run time system (RTS).  With the ubiquity of multicore machines the RTS was modified to support threading, the garbage collector was modified and threading APIs were introduced.  Finally, the modifications were tested in Isabelle.  This paper is relevant to the frequent debates that occur on the Ocaml mailing list.  Ocaml currently has no support for parallelism and this deficiency is frequently brought up as a negative.&lt;br /&gt;&lt;br /&gt;The primary motivation for adding parallelism to Poly/ML is Isabelle/ML, where proofs can take hours to days to execute.  Poly/ML and Isabelle/ML have been developed for many years which restricted the modifications to not break existing code and not grossly negatively effect single threaded applications.  The authors decided to start with a fairly low level, pthreads-like, implementation and build layers on top of it, each more abstract than the previous.  The majority of the changes took place in the RTS, Poly/ML base library, and Isabelle/ML library.  In the end, no user's Isabelle code need be modified to take advantage of the performance benefits.&lt;br /&gt;&lt;br /&gt;As stated before, Poly/ML is an implementation of Standard ML.  The original definition of SML included an asynchronous exception called &lt;code&gt;Interrupt&lt;/code&gt;.  This was removed from the 1997 definition however Poly/ML has kept in for interrupting threads.  This exception can be triggered by one thread in another thread to stop a computation.  &lt;code&gt;Interrupt&lt;/code&gt; is a useful mechanism to get a threads attention.&lt;br /&gt;&lt;br /&gt;The RTS is written in C++, provides memory management, access to the underlying OS and required the most modifications.  The RTS provides a one-to-one relationship between OS threads and ML threads.  The OS is in charge of scheduling threads on cores.  Synchronization primitives are not implement as a direct call to the underlying OS's, however.  Each thread is given a single condition variable which the RTS can signal for the unlocking of a mutex, or signaling of a condition variable, in the ML code.  A single threaded stop-the-world GC is used.  While it is known that this is a likely bottleneck as the number of cores increase, it is shown that it not an issue up to 8 cores.&lt;br /&gt;&lt;br /&gt;The base libraries were hardly altered, beyond adding the necessary threading APIs.  The low-level APIs provided are: &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Threads:&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;tt&gt;fork&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;unit &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; unit&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;*&lt;/font&gt; attribute list &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; thread&lt;br /&gt;interrupt&lt;font color="#990000"&gt;:&lt;/font&gt; thread &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; unit&lt;br /&gt;setAttributes&lt;font color="#990000"&gt;:&lt;/font&gt; attribute list &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; unit&lt;br /&gt;getAttributes&lt;font color="#990000"&gt;:&lt;/font&gt; unit &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; attribute list&lt;/tt&gt;&lt;/code&gt;&lt;/pre&gt;&lt;b&gt;Mutexes:&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;tt&gt;mutex&lt;font color="#990000"&gt;:&lt;/font&gt; unit &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; mutex&lt;br /&gt;lock&lt;font color="#990000"&gt;:&lt;/font&gt; mutex &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; unit&lt;br /&gt;unlock&lt;font color="#990000"&gt;:&lt;/font&gt; mutex &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; unit&lt;/tt&gt;&lt;/code&gt;&lt;/pre&gt;&lt;b&gt;Condition Variables:&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;tt&gt;condVar&lt;font color="#990000"&gt;:&lt;/font&gt; unit &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; condVar&lt;br /&gt;wait&lt;font color="#990000"&gt;:&lt;/font&gt; condVar &lt;font color="#990000"&gt;*&lt;/font&gt; mutex &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; unit&lt;br /&gt;signal&lt;font color="#990000"&gt;:&lt;/font&gt; condVar &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; unit&lt;br /&gt;boradcast&lt;font color="#990000"&gt;:&lt;/font&gt; condVar &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; unit&lt;/tt&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The only one that might need explaining is &lt;code&gt;interrupt&lt;/code&gt;.  This raises the asynchronous exception &lt;code&gt;Interrupt&lt;/code&gt; in the provided thread.  A few other locations of the standard library were modified, such as the I/O module which had locks added to each operation.  The authors do point out:&lt;br /&gt;&lt;blockquote&gt;... this overhead can be almost entirely avoided by using the functional IO layer of the ML library in which reading a character returns the character and a new stream since in this case a lock is only needed when the buffer is empty and needs to be refilled.&lt;/blockquote&gt;&lt;br /&gt;Abstractions over these were added to the Isabelle/ML library.  The first is a synchronized variable with the following definition:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;type&lt;/font&gt;&lt;/b&gt; 'a var&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;val&lt;/font&gt;&lt;/b&gt; var&lt;font color="#990000"&gt;:&lt;/font&gt; 'a &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; 'a var&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;val&lt;/font&gt;&lt;/b&gt; value&lt;font color="#990000"&gt;:&lt;/font&gt; 'a var &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; 'a&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;val&lt;/font&gt;&lt;/b&gt; guarded_access&lt;font color="#990000"&gt;:&lt;/font&gt; 'a var &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;'a &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;'b &lt;font color="#990000"&gt;*&lt;/font&gt; 'a&lt;font color="#990000"&gt;)&lt;/font&gt; option&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; 'b&lt;/tt&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;code&gt;guarded_access&lt;/code&gt; takes a synchronized variable, and a function that takes the value of the synchronized variable as input and returns an option containing a tuple of the new value to put in the synchronized variable and the value to return.  The combinator combines the idea of a mutex and condition variable.  In the code &lt;code&gt;guarded_access v f&lt;/code&gt;, &lt;code&gt;f&lt;/code&gt; will be applied to the value stored in &lt;code&gt;v&lt;/code&gt;.  If &lt;code&gt;f&lt;/code&gt; returns &lt;code&gt;NONE&lt;/code&gt; then &lt;code&gt;guarded_access&lt;/code&gt; waits for the next signal on that variable and applies &lt;code&gt;f&lt;/code&gt; again.  If &lt;code&gt;f&lt;/code&gt; returns &lt;code&gt;Some (a, b)&lt;/code&gt;, then the value &lt;code&gt;b&lt;/code&gt; will be put back into the synchronized variable and the value &lt;code&gt;a&lt;/code&gt; will be returned.&lt;br /&gt;&lt;br /&gt;This simple construct can be used to implement variables that can be safely shared, and updated, between threads.  mvar's, variables where a thread waits for a value if none is there when getting and waits for the value to be removed when putting, can be easily implemented with this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;type&lt;/font&gt;&lt;/b&gt; 'a mvar &lt;font color="#990000"&gt;=&lt;/font&gt; 'a option var&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;fun&lt;/font&gt;&lt;/b&gt; mvar &lt;font color="#990000"&gt;()&lt;/font&gt; &lt;font color="#990000"&gt;=&lt;/font&gt; var NONE&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;fun&lt;/font&gt;&lt;/b&gt; take v &lt;font color="#990000"&gt;=&lt;/font&gt; guarded_access v &lt;br /&gt;               &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;fn&lt;/font&gt;&lt;/b&gt; NONE &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; NONE &lt;font color="#990000"&gt;|&lt;/font&gt; Some x &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; Some &lt;font color="#990000"&gt;(&lt;/font&gt;x&lt;font color="#990000"&gt;,&lt;/font&gt; NONE&lt;font color="#990000"&gt;))&lt;/font&gt;&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;fun&lt;/font&gt;&lt;/b&gt; put v x &lt;font color="#990000"&gt;=&lt;/font&gt; guarded_access v &lt;br /&gt;               &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;fn&lt;/font&gt;&lt;/b&gt; SOME _ &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; NONE &lt;font color="#990000"&gt;|&lt;/font&gt; NONE &lt;font color="#990000"&gt;=&amp;gt;&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;SOME &lt;font color="#990000"&gt;((),&lt;/font&gt; SOME x&lt;font color="#990000"&gt;)))&lt;/font&gt;&lt;/tt&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The other abstraction presented is futures, which are a way to represent the result of a computation before it is completed.  The futures interfaces looks a lot like a typical lazy evaluation interface, except the value will always be computed unless it is canceled.  Futures are an attractive way to represent parallel computations.  Consider this contrived example:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;val&lt;/font&gt;&lt;/b&gt; x &lt;font color="#990000"&gt;=&lt;/font&gt; future some_expensive_computation&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;val&lt;/font&gt;&lt;/b&gt; y &lt;font color="#990000"&gt;=&lt;/font&gt; future some_other_expensive_computation&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;val&lt;/font&gt;&lt;/b&gt; z &lt;font color="#990000"&gt;=&lt;/font&gt; join x &lt;font color="#990000"&gt;+&lt;/font&gt; join y&lt;/tt&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We create two futures, &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; which evaluate to integers.  Then we create &lt;code&gt;z&lt;/code&gt; which will be the sum of &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;.  Assuming you have enough cores, &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; will be computed in parallel.  The &lt;code&gt;join&lt;/code&gt; function waits for the future and evaluates to the value of the future.  Here is the interface for futures in Isabelle/ML:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;type&lt;/font&gt;&lt;/b&gt; 'a future&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;val&lt;/font&gt;&lt;/b&gt; future&lt;font color="#990000"&gt;:&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;unit &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; 'a&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; 'a future&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;val&lt;/font&gt;&lt;/b&gt; join&lt;font color="#990000"&gt;:&lt;/font&gt; 'a future &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; 'a&lt;br /&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;val&lt;/font&gt;&lt;/b&gt; cancel&lt;font color="#990000"&gt;:&lt;/font&gt; 'a future &lt;font color="#990000"&gt;-&amp;gt;&lt;/font&gt; unit&lt;/tt&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;If a future is cancelled or produces an exception, that exception will be reraised when &lt;code&gt;join&lt;/code&gt; is called.  Isabelle/ML also contains a few future combinators, such as future groups which create a hierarchy of execution that kills all futures in the hierarchy if one fails.&lt;br /&gt;&lt;br /&gt;The implied implementation of futures is a thread pool where the &lt;code&gt;future&lt;/code&gt; function queues work for the thread pool.  A scheduler will then decide which futures get work or are cancelled.&lt;br /&gt;&lt;br /&gt;That is the end of additions to Poly/ML and Isabelle/ML.  How well does it work?  While subjective, performance improvements were more than acceptable with tests plateauing at around 8 cores.  The tests were performed using large Isabelle/Isar proofs available in the standard distribution.  Isabelle/Isar is non computational language and has a modular nature that makes it possible to exploit implicit parallelism.  Four Isabelle applications were used for testing, all of which are considered reasonably large.  The results showed a maximum of 3.2x speedup for 4 cores and 6.5x on 8 cores.  Past 8 cores the performance increase plateaus.  Two bottlenecks were investigated further.  The first is garbage collection.  As stated earlier Poly/ML has a single threaded stop-the-world GC.  At 16 cores GC becomes about 15-30% of the run time.  The second bottleneck is insufficient parallelization.  Of the applications chosen, there was an insufficient amount of work to keep all of the cores busy.&lt;br /&gt;&lt;br /&gt;While there are many implementations for functional languages out there, Poly/ML remains one of the few that supports true multicore threads in a stable state and used in realistic applications.  The modifications to Poly/ML took about 1 person year of work.  Future work includes parallelizing the garbage collector.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;The Discussion&lt;/h1&gt;Every few months the question of if Ocaml will get multicore support comes up.  The answer is generally "no" (although it's coming closer to "yes" thanks to OcamlPro) with the reason being it is too hard to provide a proper implementation, garbage collection being given as the primary reason.  I think that the results of Poly/ML show that even a single threaded stop-the-world GC can provide a sufficient performance advantage while also providing more powerful abstractions for parallelism.  A parallel garbage collector can be worked in later, if needed, without affecting existing code.&lt;br /&gt;&lt;br /&gt;I liked that the authors chose to add low-level threading support and build layers on top.  It gives developers options if the provided abstractions are not meeting their needs.  Futures appear to be a very appealing abstraction but I worry somewhat that they are insufficient.  In order to maximize parallelism, should every function consume and produce futures?  That seems a bit overkill and the overhead would likely be enormous.  But it is easy to think of situations where either decision hurts you, either because of the overhead or because you aren't utilizing all of the cores effectively. I do like futures as an option though and hope to see them if/when Ocaml gets multicore support.&lt;br /&gt;&lt;br /&gt;This is my first exposure to Poly/ML and the authors have done excellent work.  I hope it provides motivation for bringing Ocaml into the multicore world.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-4290907213630568419?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/4290907213630568419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2011/04/jc-efficient-parallel-programming-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4290907213630568419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4290907213630568419'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2011/04/jc-efficient-parallel-programming-in.html' title='[JC] Efficient Parallel Programming in Poly/ML and Isabelle/ML'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-8195321608617175636</id><published>2011-04-14T10:50:00.011-04:00</published><updated>2011-04-17T19:45:26.389-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='gotcha'/><title type='text'>A little gotcha in overloading comparison methods in Python</title><content type='html'>Python supports chaining relational operators so you can express 2 &lt; 3 &lt; 4 and get true.  It looks like this is implemented as a little compiler trick that actually creates the expression "2 &lt; 3 and 3 &lt; 4".  This can be confusing if you try to do something insane like implement Haskell's (&gt;&gt;=) in Python using (&gt;=).  Something like: &lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#000000"&gt;Just&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;&amp;gt;=&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;lambda&lt;/font&gt;&lt;/b&gt; x &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Just&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x &lt;font color="#990000"&gt;+&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;))&lt;/font&gt; &lt;font color="#990000"&gt;&amp;gt;=&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;lambda&lt;/font&gt;&lt;/b&gt; x &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Just&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x &lt;font color="#990000"&gt;/&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;))&lt;/font&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/code&gt;&lt;/pre&gt;Will actually become:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;tt&gt;&lt;b&gt;&lt;font color="#000000"&gt;Just&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;&lt;font color="#993399"&gt;10&lt;/font&gt;&lt;font color="#990000"&gt;)&lt;/font&gt; &lt;font color="#990000"&gt;&amp;gt;=&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;lambda&lt;/font&gt;&lt;/b&gt; x &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Just&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x &lt;font color="#990000"&gt;+&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;))&lt;/font&gt; &lt;b&gt;&lt;font color="#0000FF"&gt;and&lt;/font&gt;&lt;/b&gt; &lt;font color="#990000"&gt;\&lt;/font&gt;&lt;br /&gt;    &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;lambda&lt;/font&gt;&lt;/b&gt; x &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Just&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x &lt;font color="#990000"&gt;+&lt;/font&gt; &lt;font color="#993399"&gt;1&lt;/font&gt;&lt;font color="#990000"&gt;))&lt;/font&gt; &lt;font color="#990000"&gt;&amp;gt;=&lt;/font&gt; &lt;font color="#990000"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#0000FF"&gt;lambda&lt;/font&gt;&lt;/b&gt; x &lt;font color="#990000"&gt;:&lt;/font&gt; &lt;b&gt;&lt;font color="#000000"&gt;Just&lt;/font&gt;&lt;/b&gt;&lt;font color="#990000"&gt;(&lt;/font&gt;x &lt;font color="#990000"&gt;/&lt;/font&gt; &lt;font color="#993399"&gt;2&lt;/font&gt;&lt;font color="#990000"&gt;))&lt;/font&gt;&lt;/tt&gt;&lt;/code&gt;&lt;/pre&gt;This only seems to only apply to the relational operators, choosing to implement (&gt;&gt;=) with (&gt;&gt;) in Python seems to work fine.  Here is a Gist showing the problem from &lt;a href="http://apgwoz.com"&gt;@apgwoz&lt;/a&gt;: &lt;a href="https://gist.github.com/916132"&gt;https://gist.github.com/916132&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-8195321608617175636?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/8195321608617175636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2011/04/little-gotcha-in-overloading-comparison.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/8195321608617175636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/8195321608617175636'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2011/04/little-gotcha-in-overloading-comparison.html' title='A little gotcha in overloading comparison methods in Python'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-1846704065474282229</id><published>2011-04-12T10:51:00.000-04:00</published><updated>2011-04-12T10:51:11.234-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='silly'/><category scheme='http://www.blogger.com/atom/ns#' term='unicorn'/><title type='text'>Unicorn is Unix, What?</title><content type='html'>I'm late to &lt;a href="http://tomayko.com/writings/unicorn-is-unix"&gt;this&lt;/a&gt; blog post but &lt;a href="http://twitter.com/apgwoz"&gt;@apgwoz&lt;/a&gt; just sent it to me.  I found it pretty silly.  Apparently we should like Unicorn because it uses a lot of Unix system calls...&lt;br /&gt;&lt;blockquote&gt;There’s another problem with Unix programming in Ruby that I’ll just touch on briefly: Java people and Windows people. They’re going to tell you that fork(2) is bad because they don’t have it on their platform, or it sucks on their platform, or whatever, but it’s cool, you know, because they have native threads, and threads are like, way better anyways.&lt;br /&gt;&lt;br /&gt;Fuck that.&lt;br /&gt;&lt;br /&gt;Don’t ever let anyone tell you that fork(2) is bad. Thirty years from now, there will still be a fork(2) and a pipe(2) and a exec(2) and smart people will still be using them to solve hard problems reliably and predictably, just like they were thirty years ago.&lt;/blockquote&gt;False dichotomies are the best form of logic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-1846704065474282229?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/1846704065474282229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2011/04/unicorn-is-unix-what.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1846704065474282229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1846704065474282229'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2011/04/unicorn-is-unix-what.html' title='Unicorn is Unix, What?'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-7426360374790086133</id><published>2010-10-05T22:34:00.009-04:00</published><updated>2010-10-06T11:33:18.262-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cufp2010'/><category scheme='http://www.blogger.com/atom/ns#' term='cufp'/><category scheme='http://www.blogger.com/atom/ns#' term='functional'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><category scheme='http://www.blogger.com/atom/ns#' term='jane street'/><category scheme='http://www.blogger.com/atom/ns#' term='credit suisse'/><category scheme='http://www.blogger.com/atom/ns#' term='functional programming'/><category scheme='http://www.blogger.com/atom/ns#' term='ocaml'/><category scheme='http://www.blogger.com/atom/ns#' term='f#'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Summary of CUFP 2010</title><content type='html'>This year was my first attending CUFP and I had a great time.  I was pleasantly surprised at how strong of a showing the OCaml community had.  I knew Jane Street would be there but I ran into several other people working in OCaml.  The star of the show was definitely F# in my opinion.  The weakest part of the conference was the lack of outlets.  My laptop battery ran out by the second session of the first day and it was really quite difficult to find an outlet to charge it.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Day 1&lt;/h1&gt;&lt;br /&gt;The first day was broken into two session, each in a tutorial style.  For the first session I was in the &lt;i&gt;Building Robust Servers Using Erlang&lt;/i&gt; presented by Martin Logan from Orbitz.  This stumbled a bit at the beginning, I think Martin was hoping people would be more familiar with Erlang as a language so he could delve into how to build a robust server.  It picked up in the end though and I think he successfully drove his message home.  The people I talked to after the session expected it to be a basic description on how to write Erlang but were impressed by the power of OTP, especially the supervisor model.  A few people remarked that Erlang seemed great for anything that needed to be long running, so I think Martin was successful.&lt;br /&gt;&lt;br /&gt;I jumped between all of the presentations in the second session.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;F#&lt;/b&gt; - This was interesting, I hadn't seen F# much before.  The presenter was teaching it through an ant simulation and had a contest with prizes.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Camlp4 and Template Haskell&lt;/b&gt; - I was a bit let down by what I saw of this one.  It didn't seem like the presenters really gave a good introduction to templating languages.  They presented a problem and let everyone work on it and would go around answering any questions.  I wish my laptop battery was working so I could have taken a shot at playing with Camlp4.  To their credit they were very helpful when asked but the initial presentation seemed lacking to me.  Perhaps it was just too far over my head at this time.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Scala and Lift&lt;/b&gt; - This was the presentation that I had the least interest in but I think was the most well done.  David's presentation was interactive and had no slides.  He simply wrote code with you and explained what it did and I think that worked well.  Everyone I talked to after seemed impressed by what Lift was capable of accomplishing so easily.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Day 2&lt;/h1&gt;&lt;br /&gt;Day 2 was all talks done in serial.  I enjoyed most of the talks quite a bit.  Yaron Minksy from Jane Street started out by saying something I think was important and easy to forget if you are heavily in the FP community.  Despite the clear progress FP seems to be making (F# in Visual Studio, Real World Haskell, FP's in several big companies), we really &lt;b&gt;aren't&lt;/b&gt; growing like we'd like to think.  For most people management either says no to a functional language or it has to be snuck in through the back door.  That is why they chose the keynote to be about F#.  Microsoft including it in Visual Studio is a big leap and probably the biggest news in terms of FP going mainstream.  But is it enough?  We'll find out in the coming years.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;F#&lt;/b&gt; - This was the keynote presented by Luke Hoban from Microsoft and he painted a really great picture of F#.  His talk spanned how they introduce F# to non-functional programmers, a demo of F#, and some experiences in productizing it.  The integration with Visual Studio was topnotch.  Luke showed off how easy it is to create a GUI, handle events, and run asynchronous code.  It almost made me wish I was running Windows, it looked so nice.  The power of F#, to me, was making GUIs.  The language looked like it had to be weakened a bit in order to successfully exist in the .Net ecosystem but if I ever find myself working on Windows I will gladly use F#.  How much will F# be adopted by mainstream programmers?  Who knows, I'm hoping quite a bit though.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Scaling Scala at Twitter&lt;/b&gt; - I knew Twitter used Scala but I did not realize they were such a large Scala shop.  Scala was another language that seemed to have good representation at CUFP.  I am still not sold on it but people seem to be doing great things with it.  This talk was mostly about experiences in building the geolocation in Twitter.  It was impressive that geolocation was built very quickly by two engineers who had no Scala or Java experience.  There were two takeaways from this talk.  The first is that the data center is the new computer.  When you are designing a distributed application you really need to think differently about it than you would a non distributed application.  This should not be a surprise if you really think about it but the emphasis seemed to be that in many cases people don't realize there is a difference.  The second was that we should be honest about GC and realize it is a leaky abstraction.  It would be nice if the application could get information back from the GC.  The application really knows best how to handle working under heavy load and it would be nice if it could query the GC to figure out what kind of load it is under.  I am not quite sure how much I buy the second one, couldn't the application monitor itself based on some metric relevant to its operations and modify its behavior based on that?&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Cryptol, a DSL for Cryptographic Algorithms&lt;/b&gt; - This was from the people at Galois.  I don't know much about Galois other than dons works there and they do Haskell, but it looks like they get nice government contracts too.  I had no idea how complex the world of cryptology is.  I knew the algorithms were sophisticated but not the rest of it.  Cryptol seems powerful but much of the talk was over my head.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Naïveté vs. Experience - or, How We Thought We Could Use Scala and Clojure, and How We Actually Did&lt;/b&gt; - This talk was by Michael Fogus and my favorite.  MIchael was entertaining and insightful.  Most of this talk was about Scala and it included why they moved to Scala from Java, what they expected to use in Scala, what they actually did use in Scala, and the problems with Scala.  Michael talked a lot about how he convinced his team to move to Scala as well.  The experiences were positive but it did take a lot of convincing.  The slides to his talk can be found &lt;a href="http://blog.fogus.me/2010/10/02/naivete-vs-experience/"&gt;here&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Reactive Extensions (Rx): Curing Your Asynchronous Programming Blues&lt;/b&gt; - Sadly Erik Meijer was unable to present this.  I forgot to write down the name of who did present it, Wes something, but he did a great job.  Rx looks really cool.  I don't know how it scales up in writing an application but Wes was able to throw together some interesting programs very quickly using Rx.  Rx is a Reactive Programming library for .Net.  In short, it treats events like a collection and you simply iterate over the collection to get events (you can even use LINQ).  This makes writing even driven software easier to think about and easier to compose events together.  All of his examples were in C# but, because Rx is on .Net, it can be used seamlessly with F# (is the impression that I got).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Eden: An F#/WPF framework for building GUI tools&lt;/b&gt; - Eden is built by the Credit Suisse guys so they were unable to actually show Eden, however a subset of its functionality was built for the talk.  This showed off more of how pretty GUIs can be created with F#.  WPF has really great graphics and looked easy to produce.  The portion of Eden shown was using a graph-based layout to calculate output on demand.  It is difficult to explain succinctly but this talk showed off GUIs in F# as well as how easy it is to create asynchronous code.  F#'s two strongest points seem to be OCaml's two weakest points.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Functional Language Compiler Experiences at Intel&lt;/b&gt; - The speaker couldn't talk too much about what they were working on (apparently Intel is making a functional language designed to be used for their processors with many many cores) they they did have some interesting meta-things to say.  The first was, even in the FP world, sometimes you just want impurity.  The second was, if your FP language is going to allow you to write code imperatively, don't make the syntax terrible.  In this case they were writing SML.  Finally, it is harder to teach someone FP if they have programming experience than something completely fresh.  In their case they were looking at 8 - 12 months before really getting a return from the people they were training.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Riak Core: Building Distributed Applications Without Shared State&lt;/b&gt; - This talk was great.  Rusty from Basho gave a great look at the important functionality in Riak.  Riak is broken into three components: Riak Core - a core library for building robust distributed applications in Erlang, Riak KV - A key-value store using Riak Core, and Riak Search - a full text search engine using Riak Core.  The message here, again, was the data center is the computer.  I thought Riak's usage of virtual nodes was interesting too, and it seemed obvious in hindsight.  Rather than break your distributed application up by physical nodes, create a ton of virtual nodes (more than you'll ever have of physical nodes) and then map those to physical nodes.  Take sharding, for example, if you map to physical nodes, once you add a new physical node you'll have to repartition your shards all over again.  But if you have a few hundred virtual nodes, adding a physical node just means you have to remap some data to it and point the new virtual nodes at it, but your upstream code doesn't need to change at all.  Riak Core helps take care of the virtual node mapping for you as well as how to push data around when you add or take away physical nodes.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Functional Programming at Freebase&lt;/b&gt; - I was excited for this talk but sadly let down.  This involved rewriting Freebase's query language parser and executor from Python to OCaml.  It looked more like mental masturbation to me though.  Several times I found myself simply wonder why some choices were made.  Many of the choices came off as wishing he were writing Haskell.  In the end the speaker got a 10x speed up, which was pointed out to not be very good, and it looked like they had to go through a lot of headaches a long the way.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;ACL2: Eating One's Own Dogfood&lt;/b&gt; - I was unable to attend this talk.&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I enjoyed CUFP quite a bit.  It was great to meet the people I read papers from or see on videos about my favorite languages.  In terms of being mainstream, Scala seemed to be making the fastest gains, most likely because it is so close to Java, it is an easy switch.  In many ways I felt like we are all slowly catching up to Haskell.  Many of the technical ideas presented here have already existed in Haskell for quite awhile and I could almost see the frustration on faces of the Haskell people wondering why the rest of us haven't figured out that we should be writing it.  I'm hoping that next year the number of companies adopting functional languages continues to grow so we can see more examples of FP in industry at the next CUFP.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-7426360374790086133?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/7426360374790086133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2010/10/summary-of-cufp-2010.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7426360374790086133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7426360374790086133'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2010/10/summary-of-cufp-2010.html' title='Summary of CUFP 2010'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-6904799903144245990</id><published>2010-03-31T15:19:00.004-04:00</published><updated>2010-04-05T00:43:49.546-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='serious bzns'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='lyss'/><category scheme='http://www.blogger.com/atom/ns#' term='lyse'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Learn You Some Erlang renamed Learn You Some Scala</title><content type='html'>&lt;p&gt;&lt;br /&gt;I'm excited to &lt;a href="http://twitter.com/mononcqc/status/11395039195"&gt;announce&lt;/a&gt; that Frederic Trottier-Hebert has decided to change the name of Learn You Some Erlang to Learn You Some Scala!  This should come as no surprise to most of us.  As I demonstrated &lt;a href="http://functional-orbitz.blogspot.com/2010/03/how-much-has-scala-affected-erlang.html"&gt;here&lt;/a&gt; Scala and Erlang are really the same language.  With the growing popularity of Scala it only makes sense to target the Scala audience (whom we can thank for Erlang's actors).  I got the chance to talk to Frederic about the change.  When asked what finally prompted the change he said:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&amp;lt;MononcQc&amp;gt; Well yeah, I mean I was there when you first were talking with Virding about the migration of Erlang to the JVM. I'm quoted in that blog post&lt;br/&gt;&lt;br /&gt;&amp;lt;MononcQc&amp;gt; that discovery was pretty much a shock to me too, and so it's why I've pondered this and discussed the whole issue over #erlang on the course of the last few weeks&lt;br/&gt;&lt;br /&gt;&amp;lt;MononcQc&amp;gt; I picked up one of the many great books about Scala and realized that 'damn, they're the same stuff!'&lt;br/&gt;&lt;br /&gt;&amp;lt;MononcQc&amp;gt; Scala being bigger with the JVM being stress tested in production environment (sometimes claiming 9 nines of uptime)&lt;br/&gt;&lt;br /&gt;&amp;lt;MononcQc&amp;gt; I decided to do the switch.&lt;br/&gt;&lt;br /&gt;&amp;lt;MononcQc&amp;gt; So LYSE becomes LYSS&lt;br/&gt;&lt;br /&gt;&amp;lt;MononcQc&amp;gt; It's much more marketable anyway&lt;br/&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Some of the changes he has told me are upcoming:&lt;br/&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;OTP In Scala - How to work with some of the Scala specific OTP libraries to get better soft real time guarantees and performance&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Mnesia and Scala - Mnesia is written in Erlang/Scala so moving your databases should Just Work.  There should be a pretty big performance increase due to the JIT too (performance improvements have been shown to be about 20%-25.4%) I'm pretty excited about this one.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;JVM Performance tuning - When to use &lt;i&gt;-client&lt;/i&gt; and when to use &lt;i&gt;-server&lt;/i&gt; will play a big part in this chapter.  Frederic plans on really covering the nitty details of JVM tuning.  Frederic admits that he hasn't done much work with the JVM but given the similarity to beam doesn't forsee that being a problem&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Java interop - No more need to use jinterface, Java interop is much easier when running on the JVM!&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;What does Frederic have to say about possible backlash from the Erlang community about the name change? &lt;i&gt;"I see none.  I'm moving for the best"&lt;/i&gt;.  There you have it folks.  Frederic said the rebranding is still a work in progress but he hopes to have the entire book moved over to Scala terminology in a few weeks.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-6904799903144245990?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/6904799903144245990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2010/03/learn-you-some-erlang-renamed-learn-you.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/6904799903144245990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/6904799903144245990'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2010/03/learn-you-some-erlang-renamed-learn-you.html' title='Learn You Some Erlang renamed Learn You Some Scala'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-1648849419347508709</id><published>2010-03-10T13:12:00.007-05:00</published><updated>2010-03-10T13:47:35.857-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='serious bzns'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>How Much Has Scala Influenced Erlang?</title><content type='html'>&lt;p&gt;&lt;br /&gt;This &lt;a href="http://twitter.com/FrancescoC/status/10271901570"&gt;question&lt;/a&gt; was recently overheard at qcon.  On the surface it seems like a rather silly question but after some digging I think the answer might surprise you.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Scala and Erlang have actually gone back and forth, sharing ideas, for quite awhile now.  While many people don't realize it, Erlang was first implemented on the JVM.  This is back in the 1.x days when Java was using green threads.  Joe had seen that this was a great platform for distributed, low latency, high throughput, concurrent applications and wrote a quick language implementation that quickly grew into Erlang.  Martin Odersky has stated several times that Erlang was his influence for implementing Scala on the JVM.  It was at this point that Scala introduced actors.  While not a new concept, Scala was one of the first major implementations of actors.  Erlang originally used a dataflow concept similar to what Mozart/Oz would later implement.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Why, you may ask, did Erlang finally move off the JVM?  Such a great platform, you would expect them to stay.  The answer is tail calls.  The JVM has always lacked tail call optimization and Erlang needed it.  Trampolining just was not sufficient for how Joe wanted to structure programs.  So they ditched the JVM and implemented their own VM (known as beam).  At this point, since Erlang was off the JVM, Sun (now Oracle) decided to drop the green threads for a more traditional threading implementation.  While this transition may seem weird, it actually gave birth to what many people consider the most powerful part of Erlang: fault tolerance.  Because Joe wanted to move off the JVM as quickly as possible he had people use his unfinished VM, which was very buggy.  A lot of the fault tolerance aspects of Erlang come from people trying to work around Joe's buggy VM, which thankfully is quite stable now.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Richard Virding was nice enough to give us a little rundown on what it was like in the early days of moving from the JVM to beam (from #erlang on freenode):&lt;br/&gt;&lt;br /&gt;&amp;lt; MononcQc&amp;gt; Did the need for distribution have anything to do with your move from the JVM?&lt;br/&gt;&lt;br /&gt;&amp;lt; rvirding&amp;gt; No not at all, Terracotta implemented everything we wanted, and better, it was really the tail calls that pushed it.&lt;br/&gt;&lt;br /&gt;&amp;lt; rvirding&amp;gt; I can remember one night late with Joe we were trying to get our own distribution layer worker and we were having trouble with the security model.&lt;br/&gt;&lt;br /&gt;&amp;lt; rvirding&amp;gt; Joe had just happened to be playing with Netscape that day and saw this idea they introduced called 'cookies' and he said "Richard, I've got it!"&lt;br/&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;All of this makes a lot of sense when you think about it though.  Given the popularity of Scala and that it was a forerunner to Erlang's style of programming you can see why there are so few Erlang books. It also becomes clear why Erlang has such a hard time penetrating the market.  You can pretty much pick up Erlang just from a Scala book and at that point, why not just use Scala?&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-1648849419347508709?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/1648849419347508709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2010/03/how-much-has-scala-affected-erlang.html#comment-form' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1648849419347508709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1648849419347508709'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2010/03/how-much-has-scala-affected-erlang.html' title='How Much Has Scala Influenced Erlang?'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-7911233930969528275</id><published>2010-01-28T11:05:00.003-05:00</published><updated>2010-01-28T11:20:48.809-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ec2'/><title type='text'>EC2 Acting Up? Instances not showing up in describe after being launched</title><content type='html'>There have been a bunch of posts lately about EC2 being over saturated.  The latest issue I have run into is running an instance via ec2-run-instances, it returning successfully, but no new instances showing up in ec2-describe-instances.  The instance eventually shows up in ec2-describe-instances about 10 minutes later, up and running.  Unfortunately I cannot reproduce this easily and the actual code which handles this is buried deep in some layers so I don't know what ec2-run-instances is returning (it appears to be returning something valid though).  I also don't feel like trying to bring up instances until one fails unless Amazon wants to reimburse me.  Anyone else noticed this?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-7911233930969528275?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/7911233930969528275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2010/01/ec2-acting-up-instances-not-showing-up.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7911233930969528275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7911233930969528275'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2010/01/ec2-acting-up-instances-not-showing-up.html' title='EC2 Acting Up? Instances not showing up in describe after being launched'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-6867668733193770941</id><published>2009-12-04T08:49:00.002-05:00</published><updated>2009-12-04T08:55:08.642-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='friday links'/><category scheme='http://www.blogger.com/atom/ns#' term='links'/><title type='text'>Friday Links - 2009/12/04</title><content type='html'>&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://incanter-blog.org/"&gt;Incanter Blog&lt;/a&gt; - A guy I work with wrote this.  It is a statistical package in Clojure.  It is currently used by a company that tries to make plane delay predictions.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://gitit.net/paste.lhs"&gt;Pasteboard HappStack Demo&lt;/a&gt; - Here is a little demo of how to write a web app in HappStack.  It looks promising.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://labs.fieldofscience.com/2009/11/earths-size-relative-to-planets-and.html"&gt;Earth's Relative Size&lt;/a&gt; - A neat set of videos that demonstrate Earths relative size among other celestial bodies.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://magnetnerd.com/Neodymium%20Magnets/Dirks%20Accident.htm?1"&gt;Dirk's Accident&lt;/a&gt; - Demonstrates the dangers of magnets!  The guy lost part of a finger.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-6867668733193770941?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/6867668733193770941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2009/12/friday-links-20091204.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/6867668733193770941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/6867668733193770941'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2009/12/friday-links-20091204.html' title='Friday Links - 2009/12/04'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-4878734849011240041</id><published>2009-11-20T10:34:00.002-05:00</published><updated>2009-11-20T10:39:22.664-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='friday links'/><category scheme='http://www.blogger.com/atom/ns#' term='links'/><title type='text'>Friday Links - 2009/11/20</title><content type='html'>&lt;p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=qq_2GOoFaXE"&gt;Paaaancaaaakes!&lt;/a&gt; - By far the best scene from Cabin Fever&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://tech.yahoo.com/news/ap/20091118/ap_on_hi_te/us_tec_ibm_brain_mapping?1"/&gt;Part of cat brain simulated&lt;/a&gt; - This is part of a cat brain simulated in a computer&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://bowtie-bio.sourceforge.net/index.shtml"&gt;Bowtie&lt;/a&gt; - Incredibly fast program for genome assembly against a reference genome&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Not too many interesting links this week unfortunately.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-4878734849011240041?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/4878734849011240041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2009/11/friday-links-20091120.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4878734849011240041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4878734849011240041'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2009/11/friday-links-20091120.html' title='Friday Links - 2009/11/20'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-7752705185388403002</id><published>2009-11-14T13:22:00.008-05:00</published><updated>2009-11-16T09:13:34.328-05:00</updated><title type='text'>My Weaksauce Event Loop In Python</title><content type='html'>&lt;p&gt;&lt;br /&gt;I have been writing a bunch of glorified shell scripts in Python.  Like any tool, they start to get more complicated.  Originally I was just wrapping up os.system into something with a bit more versatility, like throwing an exception if the program failed.  Eventually I started to need to get the output of running programs so I switched to using the &lt;a href="http://docs.python.org/library/subprocess.html#module-subprocess"&gt;subprocess&lt;/a&gt; module.  Then once again I realized I needed to run multiple programs at once to do some things in a reasonable amount of time.  So I took the subprocess code and made it run a list of commands and use select to multiplex.  Once again though I have found that I need more versatility.  In this case I want to run multiple sequences of commands in parallel and I may not be able to predict what commands I need to run in total.  For example, I may want to run a command to mount a drive, then if that succeeds do one thing and if it fails retry or error.  So I decided to take my select code and change it a bit.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Rather than taking a list of commands to run, it takes a list of iterables.  Each iterable returns a function that, when called, returns a list of streams to be processed and a function to call when all of the streams have been processed.  The event loop then goes through handling the streams.  When all of the streams for a specific iterable are finished, it calls the clean up function and calls the next iteration, if that is the last iteration for that iterable it removes it from the list.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Combining this with generations in Python makes writing this very easy.  Here is some usage example code:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def test():&lt;br /&gt;   import sys&lt;br /&gt;   import random&lt;br /&gt;&lt;br /&gt;   def f(id):&lt;br /&gt;       print id&lt;br /&gt;       yield ProgramRunner('date', sys.stdout.write, sys.stderr.write, log=True)&lt;br /&gt;       print id&lt;br /&gt;       yield ProgramRunner('sleep %d' % random.randrange(0, 10), sys.stdout.write, sys.stderr.write, log=True)&lt;br /&gt;       print id&lt;br /&gt;       yield ProgramRunner('date', sys.stdout.write, sys.stderr.write, log=True)&lt;br /&gt;       print id&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   runCommandGens([f(v) for v in range(100)])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;This defines a generator called &lt;b&gt;f&lt;/b&gt; that takes an id.  &lt;b&gt;f&lt;/b&gt; will run three programs in serial.  One just prints out the date, the next sleeps for a random amount of time, and finally prints out the date again.  The call to &lt;b&gt;runCommandGens&lt;/b&gt; is the event loop.  In this case it takes a list of 100 generators.  I plan on changing the name of this function because obviously it doesn't need to be a generator, but something iterable.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The object being yielded, in this case a class &lt;b&gt;ProgramRunner&lt;/b&gt; implements __call__.  The cool thing is you can use whatever you want for this as long as it lives upto the interface required.  Eventually having a &lt;b&gt;Sleep&lt;/b&gt; instance would be helpful so you can pause reliably.  You could also use sockets since the event loop is just selecting on streams.  Here is another example:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def test1():&lt;br /&gt;   import sys&lt;br /&gt;&lt;br /&gt;   def f1():&lt;br /&gt;       yield ProgramRunner('date', sys.stdout.write, sys.stderr.write, log=True)&lt;br /&gt;       yield ProgramRunner('echo what is up', sys.stdout.write, sys.stderr.write, log=True)&lt;br /&gt;       yield ProgramRunner('sleep 3', sys.stdout.write, sys.stderr.write, log=True)&lt;br /&gt;       yield ProgramRunner('echo that is cool', sys.stdout.write, sys.stderr.write, log=True)&lt;br /&gt;&lt;br /&gt;   def f2():&lt;br /&gt;       yield ProgramRunner('sleep 2', sys.stdout.write, sys.stderr.write, log=True)&lt;br /&gt;       yield ProgramRunner('echo this is another thing running concurrently', sys.stdout.write, sys.stderr.write, log=True)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   runCommandGens([f1(), f2()])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;As you can see in this case it has iterables that it works through.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The use case for this is if you are mostly planning on doing work in serial and then want to do some work concurrently for a bit and when it is done go back to work in serial.  This is mostly a toy at this point (although I do use it for simple things in production).  I also want to add more specific versions of &lt;b&gt;ProgramRunner&lt;/b&gt;.  For example, one that constructs an ssh call or an scp call.  I plan on using this for working with clusters of machines, for example on EC2.  Often times I need to bring up N many machines and then run through a series of steps to properly set it up.  I'll post some example code in the near future.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;This code is also quite limited currently, in that it only allows output streams.  In reality, this is the reverse of what I would like it to look like.  What would be really cool is, rather than each iterator yielding something with a bunch of callbacks is if they could do:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def f():&lt;br /&gt;    for event in ProgramRunner(...):&lt;br /&gt;        process_event(event)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;In this case, processing events would be no different than just iterating over a source of events.  This is what Meijer appears to be going after in &lt;a href="http://www.youtube.com/watch?v=8Mttjyf-8P4"&gt;Meijer on .NET Reactive Framework&lt;/a&gt;.  I really like the idea of what he was going for there.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Here is the code for runCommandGens.  I'll probably be posting the complete code somewhere when I get a chance and if there is interest.  Bear in mind this is just something I'm playing with, comments, criticisms and suggestions are welcome.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def runCommandGens(generators):&lt;br /&gt;    """&lt;br /&gt;    This takes a list of generators and runs through each of them&lt;br /&gt;    in parallel running the commands.&lt;br /&gt;&lt;br /&gt;    Each iteration of a generator must return something that is callable and returns a tuple that looks like:&lt;br /&gt;    (oncomplete, [(stream1, function), (stream2, function), ... (streamn, function)])&lt;br /&gt;&lt;br /&gt;    Where 'oncomplete' is a function that gets called when all streams have been exhausted&lt;br /&gt;    and each stream has an associated function that gets called with the output&lt;br /&gt;    """&lt;br /&gt;&lt;br /&gt;    ##&lt;br /&gt;    # contain objects being worked on from generator&lt;br /&gt;    states = [(g, None) for g in ctorGenerators(generators)]&lt;br /&gt;&lt;br /&gt;    ##&lt;br /&gt;    # start initial commends:&lt;br /&gt;    states = nextIteration(states)&lt;br /&gt;&lt;br /&gt;    outputStreams = dict(activeOutputStreams(states))&lt;br /&gt;&lt;br /&gt;    while outputStreams:&lt;br /&gt;        input, _output, _error = select(outputStreams.keys(), [], [])&lt;br /&gt;&lt;br /&gt;        iterateAndBuild = False&lt;br /&gt;        for s in input:&lt;br /&gt;            line = s.readline()&lt;br /&gt;&lt;br /&gt;            if line:&lt;br /&gt;                callStreamF(s, line, states[outputStreams[s]])&lt;br /&gt;            else:&lt;br /&gt;                iterateAndBuild = True&lt;br /&gt;                            &lt;br /&gt;                ##&lt;br /&gt;                # removeStream returns True if this was the last stream to be removed&lt;br /&gt;                # which means we need to try to start up the next iteration&lt;br /&gt;                # and recreate outputStreams&lt;br /&gt;                if not removeStream(s, states[outputStreams[s]]):&lt;br /&gt;                    state = states[outputStreams[s]]&lt;br /&gt;                    f = getOnComplete(state)&lt;br /&gt;                    ##&lt;br /&gt;                    # Finished with this one, call onComplete&lt;br /&gt;                    f()&lt;br /&gt;                    # Set the second portion to None, nextIteration uses that to know&lt;br /&gt;                    # when to get the next iteration&lt;br /&gt;                    states[outputStreams[s]] = (state[0], None)&lt;br /&gt;&lt;br /&gt;        # If any of our streams are completely done, lets get new ones and rebuild&lt;br /&gt;        if iterateAndBuild:&lt;br /&gt;            states = nextIteration(states)&lt;br /&gt;            outputStreams = dict(activeOutputStreams(states))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-7752705185388403002?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/7752705185388403002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2009/11/my-weaksauce-event-loop-in-python.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7752705185388403002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7752705185388403002'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2009/11/my-weaksauce-event-loop-in-python.html' title='My Weaksauce Event Loop In Python'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-7686864016759737125</id><published>2009-11-12T23:09:00.005-05:00</published><updated>2009-11-13T00:00:20.634-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='friday links'/><category scheme='http://www.blogger.com/atom/ns#' term='links'/><title type='text'>Friday links - 2009/11/13</title><content type='html'>&lt;a href="http://blog.fireeye.com/research/2009/11/smashing-the-ozdok.html"&gt;Smashing the Mega-d/Ozdok botnet in 24 hours&lt;/a&gt; - Pretty neat story of taking down a large botnet&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.skytopia.com/project/fractal/mandelbulb.html"&gt;3D Mandelbrot Set&lt;/a&gt; - purdy pictures&lt;br /&gt;&lt;br /&gt;&lt;a href="http://moultano.blogspot.com/2009/11/google-can-generate-your-equations-for.html"&gt;Google can render LaTeX math&lt;/a&gt; - Very nice feature to easily get proper mathematical equations in your webpages&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.infoq.com/interviews/Erlang-Haskell-John-Hughes"&gt;Interview with John Hughes&lt;/a&gt; - John Hughes talking about Erlang and Haskell, I need to check out QuickCheck it sounds rad.  I really like the end of this when he asks where the next order of magnitude in decreasing code size will come from.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://python.org/dev/peps/pep-3003/"&gt;Python Language Moratorium&lt;/a&gt; - A moratorium has been put on the Python language so that other implementations can catch up.  This might mean we'll get an implementation that makes some aggressive optimizations&lt;br /&gt;&lt;br /&gt;&lt;a href="http://stephenmann.net/2009/07/17/cool-haskell-function/"&gt;Cool Haskell Function&lt;/a&gt; - Shows off how simple and powerful Haskell can be&lt;br /&gt;&lt;br /&gt;&lt;a href="http://scienceblogs.com/goodmath/2009/11/philosophizing_about_programmi.php"&gt;Philosophizing about Programming&lt;/a&gt; - MarkCC talks about his experiences with Haskell and why he thinks functional languages are great for building large systems&lt;br /&gt;&lt;br /&gt;&lt;a href="http://scienceblogs.com/goodmath/2009/11/googles_new_language_go.php"&gt;Google Go Language&lt;/a&gt; - Another MarkCC post.  Go has made a lot of noise this week, it looks like it has promise&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-7686864016759737125?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/7686864016759737125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2009/11/friday-links-20091113.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7686864016759737125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7686864016759737125'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2009/11/friday-links-20091113.html' title='Friday links - 2009/11/13'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-1266100384727692665</id><published>2009-11-06T00:23:00.005-05:00</published><updated>2009-11-06T00:33:51.927-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='friday links'/><category scheme='http://www.blogger.com/atom/ns#' term='links'/><title type='text'>Friday Links - 2009/11/06</title><content type='html'>I thought I'd add a weekly list of links that I found interesting over the course of the week.  Here is the first installment.  Some of these links may be old, they are presented in the week that I get to them, not necessarily the week they hit the 'tubes.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bluebrain.epfl.ch/"&gt;Blue Brain Project&lt;/a&gt; - A project to simulate a brain, pretty neat.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.economist.com/daily/chartgallery/displayStory.cfm?story_id=14743264"&gt;Where smoking kills most people&lt;/a&gt; - In developed countries, surpriiiiiiiise.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.revolution-computing.com/2009/10/shazam-not-magic-after-all.html"&gt;Shazam - Not Magic After All&lt;/a&gt; - How that Shazam program works, pretty neat.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.lexparse.com/2009/10/29/f-and-workflows-monads/"&gt;F# and workflows&lt;/a&gt; - A short blurb + links about F# and workflows (which are monads).  F# seems to have some pretty neat stuff.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.wired.com/magazine/2009/10/mf_optigenetics"&gt;Algae and Light Help Injured Mice Walk Again&lt;/a&gt; - Pretty amazing article on 'optigenetics".&lt;br /&gt;&lt;br /&gt;&lt;a href="http://academicearth.org/courses/machine-learning"&gt;Machine Learning - Stanford&lt;/a&gt; - Videos of Stanford course on Machine Learning (according to klafka the best part of stats).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-1266100384727692665?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/1266100384727692665/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2009/11/friday-links.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1266100384727692665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1266100384727692665'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2009/11/friday-links.html' title='Friday Links - 2009/11/06'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-7494028195898068453</id><published>2009-10-24T00:16:00.002-04:00</published><updated>2009-10-24T00:17:52.267-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='biology'/><category scheme='http://www.blogger.com/atom/ns#' term='cell biology'/><category scheme='http://www.blogger.com/atom/ns#' term='harvard'/><title type='text'>One of those amazing Harvard Uni cell biology videos</title><content type='html'>&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/1Tjz7ya7iAg&amp;hl=en&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/1Tjz7ya7iAg&amp;hl=en&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-7494028195898068453?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/7494028195898068453/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2009/10/one-of-those-amazing-harvard-uni-cell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7494028195898068453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7494028195898068453'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2009/10/one-of-those-amazing-harvard-uni-cell.html' title='One of those amazing Harvard Uni cell biology videos'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-8035558046104582575</id><published>2009-10-22T23:35:00.004-04:00</published><updated>2009-10-22T23:59:31.355-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='distributed'/><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><title type='text'>Suggestions On Debugging Distributed Apps?</title><content type='html'>&lt;p&gt;&lt;br /&gt;So far distributed apps seem to be the best use case for why it is important to be able to walk through code and do it by hand with a pencil and paper.  I have been writing analytics code that runs on a cluster for close to a year and still have not been able to figure out a good way of debugging the code that runs on it.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Being able to bring it down to a testcase works well in some situations but I have found it ineffective in the long run.  When you are dealing with a few terabytes of data it can be difficult to cut the problem down to a few megs of input data that you can reason about.  While the framework I am using lets me run code on a single process so I can debug it, it is again not always possible to bring the input data down small enough that it is manageable on a single process.  On top of that, the behavior you are trying to debug may not show up on such a simple case.  It's pretty impossible to use a traditional debugger if the bug only shows up in a few megs of data when you are dealing with a terabyte, how can you step through a 6 hour run if it only shows up on a small portion of that data?  How do you predict what machine that bad data will run on if you don't even know what the bad data is?&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I have so far been using three methods to debug a distributed app.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;If I have some idea what the bad data looks like, I'll look for some approximation of it in the input data and throw an exception with the debugging info I'm interested in.  Exceptions make their way back to the main console of where the jobs are run from so I can see them easy enough.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use standard IO.  The annoying part is the framework I use only logs this out to local files on the machine it ran on, so I have to wrap the grep in an ssh call to each machine.  It's also sometimes difficult to know what to even print out.  Too much printing can also significantly reduce performance and even fill up the disk with logging data.  Logging data as big as the input data is not any easy to comb through.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Just reading through the code by hand and working it out with pencil and paper.  This has only really worked if I can get a good mental image of what the input is like.  If I have a terabyte of input from untrusted sources it can be quite freeform and difficult to reason about as I walk through the code by hand.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Right now I am experiencing a bug that I have been unsuccessful in tracking down.  The problem is it only shows up when I use it on huge amounts of data.  I have two ways of doing the same thing.  One of them takes way too long and the other takes a very short time, and the short way is not producing the same numbers as the long way.  It is off by only about 500 million in 5 billion rows of input and it is being a very frustrating bug to track down.  The main problem is that I cannot produce a smaller set of input files to cause the issue.  Runs take over 6 hours with the input file I need, so a single test can take almost my entire work day.  If anyone has any suggestions, please let me know.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-8035558046104582575?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/8035558046104582575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2009/10/suggestions-on-debugging-distributed.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/8035558046104582575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/8035558046104582575'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2009/10/suggestions-on-debugging-distributed.html' title='Suggestions On Debugging Distributed Apps?'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-3291180065638183483</id><published>2009-10-18T20:58:00.006-04:00</published><updated>2009-10-18T23:24:15.914-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='complexity'/><category scheme='http://www.blogger.com/atom/ns#' term='asynchronous'/><title type='text'>Sneaking Complexity - Being Asynchronous</title><content type='html'>&lt;p&gt;&lt;br /&gt;I went out to lunch with some coworkers last week and we got to talking about the project they are working on.  They had done a great job of implementing the app which pretty much makes up the backbone of our company.  They rewrote it in Java and have gotten orders of magnitude better performance.  The app needs access to various pieces of persistent data quickly and they have created several data-clusters that perform amazingly.  And the code is very clean and easy to read.  The problem they are running into though is the client code for the data-clusters.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;One of the main reasons that Java was selected as a language to write in is the simplicity of reading and writing it.  It is fairly easy to jump into a method and, with a good IDE, figure out what it is doing.  It is simple.  The problems they are running into, though, is when doing things Teh Java Way isn't working out for the volume and latency they are trying to reach.  Specifically, they are hitting issues when they query the data-cluster.  Generally when they decide they need to hit the data-cluster they do a query and if they don't get a response back in some timeout period they go on as if they have a new record.  In this case, being correct about the data all the time is not very important.  But they are getting over the number of timed out queries they feel comfortable with (there is also a concern that the timeouts on the library they are using are not working properly).  What they would like to do is handle hitting the data-cluster asynchronously.  When they think they are going to need data, they send their query in, go do some more processing, then check to see if the data is there and continue on as if a new record if the timeout is reached.  The problem is, this really sucks so far in Java.  Being asynchronous is hard if you haven't designed your application around it in the first place.  You pretty much have to fire up a new thread for every one of these queries you want to do.  When considering a single case, this doesn't sound too bad, but the JVM uses OS threads so if you are already pushing your app to the limit, in the worst case doubling or tripling the number of threads it needs is not going to help.  You also have increased the complexity of your application.  Most of the threading in this application doesn't really need to share any data, each request is off doing its own thing and rarely hitting shared objects.  But in this case, sharing the result of the query will need to share some data.  It may not be much but it is added complexity.  On top of that, there might be a performance hit in terms of GC.  I'm not an expert in the JVM GC but shared memory means you might have to walk the entire heap in order to clean up the objects created by the query thread.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;This brings me to something that is so great about Erlang.  Accomplishing this is trivial.  Since messages in Erlang are asynchronous, you simply send your message to query the data-cluster at the beginning of your block, then do whatever work you'd like, and receive it when you are good and ready.  A receive block can take a timeout so you don't have any issues there.  Doing things asynchronously is how Erlang works pretty much from the get-go.  Erlang processes also have their own heap so cleaning up after one is fairly light on the GC, just throw away that process's heap.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;To be fair, I am certain that had they implemented this in Erlang they would have run into their own fair share of issues.  No language is perfect and Erlang certainly is no exception.  But the application in question is basically what Erlang was designed for and is good at.  There are also other issues that we talked that they would benefit from had they used Erlang too that I did not talk about.  But this is a pattern that seems common in my short career as a developer.  People look at the project they are solving, then look at whatever tools solve all the easy problems fast but in the end leave them in a worse state when it comes to solving the harder problems.  Those tools that get you 70% of the way there have forced you to design your app so that it even harder to solve that 30%.  This happened at my previous employer.  A framework was chosen that implemented all the simple things they wanted to solve but they had now inherited this framework whose design was not made to solve the more complex problems.  In the end they had to rewrite a bunch of the framework to get what they wanted.  I'm sure that my coworkers are going to be able to solve this problem in Java (they have no choice) and perhaps there is a Java-way that this should have been done and I am sure that had they implemented this in Erlang there would still be problems being discussed over lunch.  But I feel confident that they would be frustration Erlang records, or syntax, or strings, not with the sneaking complexity of trying to get it to do things asynchronously (and don't even get me started on fault-tolerance).&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-3291180065638183483?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/3291180065638183483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2009/10/sneaking-complexity-being-asynchronous.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/3291180065638183483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/3291180065638183483'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2009/10/sneaking-complexity-being-asynchronous.html' title='Sneaking Complexity - Being Asynchronous'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-1586174285939845664</id><published>2009-10-18T18:31:00.015-04:00</published><updated>2009-10-18T19:37:58.035-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chua circuit'/><category scheme='http://www.blogger.com/atom/ns#' term='lorenz attractor'/><category scheme='http://www.blogger.com/atom/ns#' term='chaos theory'/><category scheme='http://www.blogger.com/atom/ns#' term='r'/><title type='text'>Lorenz Attractor In R</title><content type='html'>&lt;p&gt;&lt;br /&gt;I spent much of this weekend trying to figure out how to graph &lt;a href="http://en.wikipedia.org/wiki/Chua_circuit"&gt;Chua's Circuit&lt;/a&gt; for a homework assignment.  I ended up using &lt;a href="http://www.r-project.org/"&gt;R&lt;/a&gt; since I don't have or know &lt;a href="http://www.mathworks.com/"&gt;MATLAB&lt;/a&gt; and I don't really want to learn &lt;a href="http://www.gnu.org/software/octave/"&gt;Octave&lt;/a&gt;.  It took me longer than it should have mostly because I don't know much of anything about differential equations.  The implementation required two extra R packages, deSolve and scatterplot3d.  The fun thing about working on this project is the whole point is to graph it so you get to see some neat visual output.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;After finishing the circuit I decided to do a little extra and graph the &lt;a href="http://en.wikipedia.org/wiki/Lorenz_attractor"&gt;Lorenz Attractor&lt;/a&gt;, which comes up quite often in class.  This is a pretty famous structure in the realm of &lt;a href="http://en.wikipedia.org/wiki/Chaos_theory"&gt;chaos theory&lt;/a&gt;.  The term 'butterfly effect' comes from look of the attractor.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;My solution uses the deSolve package in R.  The function &lt;b&gt;ode&lt;/b&gt; is used to solve the three equations that make up the attractor.  With some minor understanding of R it should be pretty easy to play with.  The settings I have in there give this pretty image:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_in0fqbaTtB0/Stub5h0GZtI/AAAAAAAAAAM/uS55innJ1Wk/s1600-h/lorenz.png"&gt;&lt;img style="margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 370px; height: 370px;" src="http://2.bp.blogspot.com/_in0fqbaTtB0/Stub5h0GZtI/AAAAAAAAAAM/uS55innJ1Wk/s320/lorenz.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5394076391338043090" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;library(deSolve)&lt;br /&gt;library(scatterplot3d)&lt;br /&gt;&lt;br /&gt;##&lt;br /&gt;# Parameters for the solver&lt;br /&gt;pars &lt;- c(alpha = 10,&lt;br /&gt;          beta = 8/3,&lt;br /&gt;          c = 25.58)&lt;br /&gt;&lt;br /&gt;##&lt;br /&gt;# In initial state&lt;br /&gt;yini &lt;- c(x = 0.01, y = 0.0, z = 0.0)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;lorenz &lt;- function(Time, State, Pars) {&lt;br /&gt;  with(as.list(c(State, Pars)), {&lt;br /&gt;    xdot &lt;- alpha * (y - x)&lt;br /&gt;    ydot &lt;- x * (c - z) - y&lt;br /&gt;    zdot &lt;- x*y - beta*z&lt;br /&gt;    return(list(c(xdot, ydot, zdot)))&lt;br /&gt;  })&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;runIt &lt;- function(times) {&lt;br /&gt;  out &lt;- as.data.frame(ode(func = lorenz, y = yini, parms = pars, times = times))&lt;br /&gt;&lt;br /&gt;  scatterplot3d(x=out[,2],&lt;br /&gt;                y=out[,3],&lt;br /&gt;                z=out[,4],&lt;br /&gt;                type="l",&lt;br /&gt;                box=FALSE,&lt;br /&gt;                highlight.3d=TRUE,&lt;br /&gt;                xlab="x",&lt;br /&gt;                ylab="y",&lt;br /&gt;                zlab="z",&lt;br /&gt;                main="3d Plot of Lorenz Oscillator")&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;##&lt;br /&gt;# Run a default value&lt;br /&gt;runAll &lt;- function() {&lt;br /&gt;  runIt(seq(0, 100, by=0.01))&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-1586174285939845664?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/1586174285939845664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2009/10/lorenz-attractor-in-r.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1586174285939845664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1586174285939845664'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2009/10/lorenz-attractor-in-r.html' title='Lorenz Attractor In R'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_in0fqbaTtB0/Stub5h0GZtI/AAAAAAAAAAM/uS55innJ1Wk/s72-c/lorenz.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-1619924503187376621</id><published>2009-09-06T20:08:00.000-04:00</published><updated>2009-10-18T18:16:23.241-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ocaml'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Impressed with Haskell's concurrency</title><content type='html'>I have been playing with both Ocaml and Haskell* lately.  In Ocaml, I have been rewriting a lot of simple Python scripts I use at work to see how they compare.  They tend to be faster and more trustworthy.  Ocaml, though, has pretty bad concurrency support.  They have some thread library that wraps the OS threads, no real good message passing interface.  Even the guys at Jane St have listed that as a complaint**.&lt;br /&gt;&lt;br /&gt;So I decided to check out Haskell again.  With Haskell I have always thought it was a great language, but could never grok it.  That sounds a little weird, but reading Haskell code is simply great.  When you figure out what it does, it tends to be very expressive and flexible.  After looking at what Haskell offers for concurrency, I think that in theory it could give Erlang a serious run for its money.  Here's why:&lt;br /&gt;&lt;br /&gt;- Haskell, in general and in my opinion, is a safer language to write code in than Erlang.  One can do a lot of work with Dialyzer to verify their code, but they are still somewhat limited.  Haskells type system is very expressive and powerful.  Haskell also has ADT's, which as far as I know Erlang still does not.  For an idea of why ADT's are so powerful when it comes to writing safe code, see the Caml Trading video.  And in this case, by 'safe' I mean writing correct code.&lt;br /&gt;&lt;br /&gt;- Haskell produces generally fast code.  GHC does some impressive optimizations, and supercompilation*** is most likely getting going to be part of GHC in the near future.  It should noted that while Haskell can produce fast results, its lazyness can also be unpredictable in the optimizations (both speed and memory) that it performs.  This is believed, by many, to be a big drawback to Haskell.  I haven't done enough work in Haskell to really say how bad this is but Real World Haskell does give a complete chapter to diagnosing performance problems and optimizing them.&lt;br /&gt;&lt;br /&gt;- Haskell's threading implementation uses green threads with a many-to-one mapping to OS threads.  This means you can take advantage of multiple cores without modifying your Haskell code.   The Erlang VM does this too, with SMP support.  The greenthread implementation also appears to be blazing fast.  Haskell is number one in the threadring solution on the language shootout.  Erlang is about 4x slower.  Take from that what you will.&lt;br /&gt;&lt;br /&gt;- You can implement Erlang-like best-case programming in Haskell, from what I can tell.  Haskell supports Exceptions, and you can throw exceptions to other threads using asynchronous exceptions.  This gives you a way to 'link' threads like you can link Erlang processes.  It is still programmer driven, so you can make a mistake, point for Erlang.&lt;br /&gt;&lt;br /&gt;- STM, while I haven't read up on this, it seems like a pretty great way to handle synchronization between threads.&lt;br /&gt;&lt;br /&gt;- Monads.  When reading up on concurrency in Haskell, monads seemed to often come up as valuable in ensuring correctness.  For example, in an STM transaction, one wants to restrict the transaction from doing things that cannot be rolled back, such as IO.  This is done by the 'atomically' function taking an STM monad as input and wrapping the output in an IO monad.  What this all means is one can't do IO in the atomically block unless it's unsafe.  The ability to restrict what the user can do, when one wants to, with the type system is quite powerful.&lt;br /&gt;&lt;br /&gt;That being said, Haskell does have some clear losses next to Erlang.  The biggest drawback is the lack of a distributed model.  There is distributed Haskell, I have not researched it much but I'm under the impression it is not 'there' yet.  Erlang is easy to learn, very easy.  Haskell is not.  I have found that, in order to write really good Haskell code, one has to keep a lot of stuff in their head at once.  Perhaps this is just because I am new but I have found Haskell better to read than to write.  Erlang is not like this, while the syntax has some peculiarities to it, it is not hard to pick up and start writing good Erlang.  I think Ocaml shares more in common to Erlang in this regard.  The hump one needs to get over in order to write solid Haskell code is a real and legitimate reason to not choose Haskell.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;All that being said, I admittedly am fairly new to Haskell so these opinions will change over time, I'm planning on putting more effort into writing real projects in Haskell to see how it goes.  Needless to say, I am impressed by what Haskell has to offer for concurrency.  If I'm factually wrong on anything here, please correct me, this is all based on some reading research I've been doing on Haskell, not my actual experiences.&lt;br /&gt;&lt;br /&gt;* When I say Haskell, I really mean GHC here&lt;br /&gt;&lt;br /&gt;** Yaron Minsky's Caml Trading lecture, very good! Makes a great, practical argument, for Ocaml - http://ocaml.janestreet.com/?q=node/61&lt;br /&gt;&lt;br /&gt;*** Supercompilation http://community.haskell.org/~ndm/downloads/slides-supercompilation_for_haskell-03_mar_2009.pdf&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-1619924503187376621?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/1619924503187376621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2009/09/impressed-with-haskell-concurrency.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1619924503187376621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1619924503187376621'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2009/09/impressed-with-haskell-concurrency.html' title='Impressed with Haskell&amp;#39;s concurrency'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-8186032296174578418</id><published>2008-04-02T10:46:00.000-04:00</published><updated>2009-10-18T18:16:23.263-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='google talk'/><category scheme='http://www.blogger.com/atom/ns#' term='comet'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='meebo'/><category scheme='http://www.blogger.com/atom/ns#' term='server-push'/><category scheme='http://www.blogger.com/atom/ns#' term='webapp'/><title type='text'>Scaling webapps</title><content type='html'>DISCLAIMER: I am not an expert in web apps and simply have been doing some research on them.  Given that, my claims and concerns may be completely unfounded and simply a result of my ignorance of web app design, if so, please let me know.&lt;br /&gt;&lt;br /&gt;I have been doing a little bit of research on webapps and I'm not sure how I feel about the standard model.  The standard model, as I understand it, works by every incoming http request results in some number of DB requests where the DB is the holder of all state information.  The web app itself, whether it be in PHP, or Rails, etc is stateless.  I certainly don't doubt that for a large majority of applications this works fine.  Take something like &lt;a href="http://www.yellowpages.com/"&gt;the yellow pages&lt;/a&gt; which is a Rails application according to &lt;a href="http://www.buildingwebapps.com/articles/13"&gt;this&lt;/a&gt;.  The standard model seems quite reasonable for this.  You have a page that is fairly static, people are mostly doing requests for data which requires walking through some large database and the results are being displayed and not much is happening again until the user initiates another page request.&lt;br /&gt;&lt;br /&gt;Web apps are changing though.  Today, we expect our web apps to look and feel like native applications, which means snappy responses and updates of it even without the user explicitly reloading the page.  We have things like AJAX and &lt;a href="http://en.wikipedia.org/wiki/Comet_%28programming%29"/&gt;Comet&lt;/a&gt;-style serverpush.  In the end, this means more requests are going to the http server even when the user is not doing anything.  The Comet style is pretty neat but from what I can see, polling with AJAX is the most widely used way.  My concern is how well the standard model is going to scale as web apps are required to act more and more like native applications.  The reason for my concern is because this method is simply polling the DB for state changes on every request and in every other situation polling quite clearly has not scaled.  This is the exact reason Comet exists.&lt;br /&gt;&lt;br /&gt;For the sake of simplicity, let's imagine that the web app is AJAX with polling.  Some portion of the page is going to be asking for updates every 5 seconds.  The standard model would have us querying the DB every 5 seconds for that request to see if the state has changed.  If you have a couple thousand people on this page that is a lot of work.  If the component of the page is changing often for a majority of the people then it's not too big of a deal but if it's not changing often for a majority we are doing a lot of worthless DB calls.  I'm sure we would design our database so that this call is hopefully very lightweight but how well does that really scale in the end?&lt;br /&gt;&lt;br /&gt;Now, the reason we want our wep app (such as something in Rails) to be stateless is because for each request we can be pushed around to a separate VM.  So if we hold onto session state information there is a good chance we might not even get a chance to use it on the next request.  On top of that, if you are load balancing between several hosts, you may not even be in a good place to share state information between VMs.&lt;br /&gt;&lt;br /&gt;I'm sure almost all of this is not news to anyone who has made it this far in the post.  What can be done to make a webapp scale better?  I'm not sure but here is my suggestion and hopefully someone with more experience than myself can come back and say if it's a horrible idea or not.  Let's say I want to make a web app that will be handling something like instant messaging such as google talk or meebo (which are both using Comet).&lt;br /&gt;&lt;br /&gt;For starters, I want this to be fairly real time, when I send a message to someone, I want it to get to them ASAP.  Secondly, there will be a lot of interaction between users.  Clearly, page-by-page viewing is not going to work here.  People can't be refreshing their page every few seconds to see if there is an update.  AJAX with polling or Comet are clearly your two choices currently.  How should this look after the HTTP request comes in though?&lt;br /&gt;&lt;br /&gt;Here is how I am suggesting it should:&lt;br /&gt;Each request should have some sort of session ID.  Each session ID will be associated with a process.  By process here, it could be an Erlang process or some OS process written in some other language, whatever.  The point here is, for a particular session ID, its request will get forwarded to the same process every time for the life time of its session.  This way, the process can store all the state information.  We don't have to do worry about sharing state information in something like memcache.  The process would have some sort of timeout value so they die off eventually.  At worst case, we are back to the standard model where if a user does multiple requests that happen to have a pause between them longer than the timeout we now have to initiate a new process and it has to do the DB calls to initiate itself.  In the best case though, we are consistently getting sent to the same process which is holding onto our data.  The upside to this method is the process can also do things specific for that user such as opening up other connections.  For instance, in the instant messaging example,  a user logs in, they get a session ID and a process created for them somewhere that will be mapped to this session ID.  The process opens up a connection to an event server for that user so it can listen for IMs and push IM's out.  We now have an application that is quite event based on all sides of it.  We won't be hitting the DB too often.  Given that we don't really care where this process lives, we can also scale it out to multiple machines and not have to worry about replicating the same data over many machines because we don't know where the users request will go to.&lt;br /&gt;&lt;br /&gt;Downsides?&lt;br /&gt;Certainly.  Clearly if we have 2000 people using our IM application at once, we need to have 2000 processes a live.  If we wrote this in Erlang where each process for a session ID maps to an Erlang process (sorry about the terminology here all)?  That's childsplay.  We could host this application on one machine!  But not everyone wants to write things in Erlang, so what about them?  If I were in this situation, I would probably have some machines each running some amount of applications that will be doing some I/O multiplexing to handle this.  So you would have some amount of OS processes and each one can handle some amount of session ID's.  Pretty standard for something that isn't Erlang but needs to handle a bunch of things at once.  If you are into Python, &lt;a href="http://en.wikipedia.org/wiki/Twisted_%28software%29"&gt;Twisted&lt;/a&gt; comes to mind.  I'm sure other languages have their own way of doing this.&lt;br /&gt;&lt;br /&gt;Another edge case here, and I think this is probably not too hard to deal with, is what if an event comes in (such as an IM) and the process times out due to lack of activity?  You could have each event have a timeout and if it is not ACK'd in that time it gets saved to a DB and the next process that is created for that user picks it up as part of its initiation.  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To reiterate, I do not have much experience in webapps, I simply have been doing some research and this is the impression that I have gotten.  Are my concerns valid?  Is the system I described what people are already going to or is it broken?  How would someone write Meebo or google talk?  Let me know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-8186032296174578418?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/8186032296174578418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2008/04/scaling-webapps.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/8186032296174578418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/8186032296174578418'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2008/04/scaling-webapps.html' title='Scaling webapps'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-6587693220357520792</id><published>2008-03-19T11:18:00.000-04:00</published><updated>2009-10-18T18:16:23.271-04:00</updated><title type='text'>Back in the saddle</title><content type='html'>So I have been working on Wall Street for the last year+ and last week decided to quit my job.  And non-too-soon, as my job will most likely no longer exist in a few months if you have been following the news over the past few weeks.&lt;br /&gt;&lt;br /&gt;I am going back to school, moving out of NYC and off to Maryland so over this summer I should have a lot of free time and I am working on possibly being involved in sort of a freelance project in order to make money (details are still pending).  Anyways, the current design of the project has a typical web-app interface, then a manager layer that encapsulates the database.  The manager layer handles caching data and moving it back to the database when needed, and event dispatching, blah blah blah.&lt;br /&gt;&lt;br /&gt;Immediately I think this is the perfect use case for Erlang.  We want it to be fault tolerant of course (the downside of a web-app is when things go wrong it affects everyone) and be able to handle a lot of data moving back and forth (although I'm unsure of the specifics since this is so early).  Basically this sounds like a standard Erlang app with mnesia as the cache most likely, spanning a few nodes and moving data back to a DB in a write-behind method.&lt;br /&gt;&lt;br /&gt;Some people have a bit of a concern about Erlang, how will we find developers and so on, which are perfectly valid.  My response to that is:&lt;br /&gt;Erlang is such a simple language it does not take much time to learn, and while OTP is not as simple, it does not take much time to learn either.  In the end, one needs to be less of an expert in Erlang to get an equal or better application (in terms of Erlang's strengths) than they would have to be in another language such as Java.&lt;br /&gt;&lt;br /&gt;One possible alternative language being considered is Java because of JBoss.  I haven't looked into JBoss in-depth yet, but at a quick glance it looks like it has some really nice and really mature features.  The JMS implementation sounds pretty solid and the clustering.  Everyone knows Java, or at least puts it on their CV, but this sounds misleading.  How good does one need to be in Java in order to not make a mess of an application written using JBoss compared to Erlang?  My opinion is that the way one learns Erlang is fairly similar to how they would write production software with Erlang, but perhaps not the same for Java.  The features we use in our 'Hello World' are the same that we use in a production environment, this is not true of Java in my experience.&lt;br /&gt;&lt;br /&gt;We are still looking into things but I'm currently hoping for Erlang.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-6587693220357520792?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/6587693220357520792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2008/03/back-in-saddle.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/6587693220357520792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/6587693220357520792'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2008/03/back-in-saddle.html' title='Back in the saddle'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-1873160510587809103</id><published>2008-01-25T23:03:00.000-05:00</published><updated>2009-10-18T18:16:23.277-04:00</updated><title type='text'>Erlang Job Advert</title><content type='html'>Well, it's been over a year, sorry.  Today I received an email with an Erlang job offer for a company based in Boston.  I don't know anything about the company at all, perhaps it is junk, but the project seems like something Erlang is good at.  It's a telecommuting job, so that might raise a red flag with some people.  If you are interested I'll put you in touch with the recruiter or whatever he is, email me at orbitz AT ortdotlove.net (that is really ortdotlove.net, not fancy spelling for ort.love.net).&lt;br /&gt;&lt;br /&gt;Here are the job details:&lt;br /&gt;&lt;blockquote&gt;Job Description:&lt;br /&gt;&lt;br /&gt;Our client, who is based in Boston, is seeking an adept Erlang developer to help build a next generation metrics and monitoring system on the GNU/Linux platform. This system will watch and report on hundreds and thousands of systems, ranging from network devices to servers to software applications.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Required Skills:&lt;br /&gt;&lt;br /&gt;·         Must have experience with the Erlang programming language&lt;br /&gt;&lt;br /&gt;·         Must have expert level network programming experience, preferably in Erlang, C++ and/or C&lt;br /&gt;&lt;br /&gt;·         Strong background in developing on GNU/Linux for mission-critical production deployments&lt;br /&gt;&lt;br /&gt;·         Strong understanding of MySQL 4.1-5.x, including database design patterns&lt;br /&gt;&lt;br /&gt;·         Strong experience programming network servers/clients, including knowledge of fundamental protocols such as TCP, UDP, IPV4/6, and SSL/TLS&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-1873160510587809103?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/1873160510587809103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2008/01/erlang-job-advert.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1873160510587809103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1873160510587809103'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2008/01/erlang-job-advert.html' title='Erlang Job Advert'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-185150837753291061</id><published>2006-11-20T21:14:00.000-05:00</published><updated>2009-10-18T18:16:23.283-04:00</updated><title type='text'>Cryptogram solver</title><content type='html'>Newspaper puzzles beware.  I have been working on soving newspaper cryptograms for the past few days in my free time.  It is a bit more interesting of a problem to solve than sudoku I think.  The algorithm I've implementing is nothing alltogether impressive and it relies on a good dictionary file to get solutions.&lt;br /&gt;&lt;br /&gt;The algorithm works like so:&lt;br /&gt;First you need an index which is a map of abstract words to lists of words.&lt;br /&gt;An abstract word is taking a word and turning it into a pattern, for instance, 'cat' has the pattern '123',  as does 'hat', and 'fat'.  'mom' has the pattern '121'.&lt;br /&gt;&lt;br /&gt;Then it takes the sentence you have given it, splits it on spaces.&lt;br /&gt;Popping the first word off the list, finds the list in the index of possible words it could be, iterates over it generating a map of letters to letters and recurses on the rest of the sentence, once it has reached the end of the sentence it puts the map it has generated into a list of possible solutions.  If a generated map for a word conflicts with teh current map it is not a valid solution and moves onto the next possible solution.&lt;br /&gt;The solve function returns a list of solution maps that can eb applied to any sentence to get the result.&lt;br /&gt;&lt;br /&gt;Little things that make it helpful include being able to give an intial map, if you are sure some letters map to other letters you can give that as a hint.  It can also remove any words whos pattern does not appear in the map.&lt;br /&gt;&lt;br /&gt;Todo:&lt;br /&gt;Solve only those subsets of words that, if solved, will result in the entire alphabet being solved.  It should do this for all possible combinations of words in teh sentence that will result in this.  This is not an optimizations, it should probably make it take longer to solve actually, however it allows it to solve sentences with words that might not exist in the dictionary but could come about as a result of solving the other words.  I have a few ideas of how to do this but havn't had time to implement it yet.&lt;br /&gt;&lt;br /&gt;The current code can be downloaded &lt;a href="http://ortdotlove.net/~orbitz/temp/crypto.erl"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-185150837753291061?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/185150837753291061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2006/11/cryptogram-solver.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/185150837753291061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/185150837753291061'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2006/11/cryptogram-solver.html' title='Cryptogram solver'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-5723399369383810022</id><published>2006-11-14T22:00:00.000-05:00</published><updated>2009-10-18T18:16:23.289-04:00</updated><title type='text'>Sudoku</title><content type='html'>I've got sudoku fever!  Actually, no, I don't, I don't really like sudoku at all but I decided to write a solver in erlang.  It was pretty trivial.  The basic algorithm is as follows:&lt;br /&gt;1) Create a list of every blank square and the possible values that can go into that square&lt;br /&gt;2) Find the square with the least number of possible values&lt;br /&gt;3) Iterate over the list of possible numbers that can be in that square, create a new board with that value in it and recurse on the new board&lt;br /&gt;4) Continue until there are no more possible values (in which case it failed) or the puzzle is solved.&lt;br /&gt;&lt;br /&gt;The code is not the prettiest stuff in the world but it appears to solve the problem (specifically the remove_* functions).&lt;br /&gt;&lt;br /&gt;Usage looks like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Eshell V5.5.1  (abort with ^G)&lt;br /&gt;1&gt; {solved, Res} = sudoku:solve([&lt;br /&gt;1&gt; [9, 5, b, b, b, 6, 4, 7, b],&lt;br /&gt;1&gt; [4, b, 8, 7, b, 2, b, b, b],&lt;br /&gt;1&gt; [6, 2, b, 4, b, b, b, 5, b],&lt;br /&gt;1&gt; [5, b, 2, b, 6, b, 3, b, b],&lt;br /&gt;1&gt; [b, b, b, 2, b, 7, b, b, b],&lt;br /&gt;1&gt; [b, b, 4, b, 1, b, 2, b, 8],&lt;br /&gt;1&gt; [b, 7, b, b, b, 9, b, 3, 4],&lt;br /&gt;1&gt; [b, b, b, 1, b, 3, 7, b, 5],&lt;br /&gt;1&gt; [b, 4, 3, 5, b, b, b, 2, 9]]).&lt;br /&gt;...&lt;br /&gt;2&gt; sudoku:print(Res).&lt;br /&gt;9 5 1 8 3 6 4 7 2 &lt;br /&gt;4 3 8 7 5 2 9 6 1 &lt;br /&gt;6 2 7 4 9 1 8 5 3 &lt;br /&gt;5 8 2 9 6 4 3 1 7 &lt;br /&gt;3 1 9 2 8 7 5 4 6 &lt;br /&gt;7 6 4 3 1 5 2 9 8 &lt;br /&gt;8 7 5 6 2 9 1 3 4 &lt;br /&gt;2 9 6 1 4 3 7 8 5 &lt;br /&gt;1 4 3 5 7 8 6 2 9 &lt;br /&gt;ok&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Code (can be downloaded &lt;a href="http://ortdotlove.net/~orbitz/temp/sudoku.erl"&gt;here&lt;/a&gt;):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-module(sudoku).&lt;br /&gt;&lt;br /&gt;-export([solve/1, print/1]).&lt;br /&gt;&lt;br /&gt;solve(Puzzle) when is_list(Puzzle) -&gt;&lt;br /&gt;    solve_puzzle(dict_from_list(Puzzle)).&lt;br /&gt;&lt;br /&gt;print(Puzzle) -&gt;&lt;br /&gt;    lists:foreach(fun(X) -&gt;&lt;br /&gt;                          lists:foreach(fun(Y) -&gt;&lt;br /&gt;                                                io:format("~w ", [dict:fetch({X, Y}, Puzzle)])&lt;br /&gt;                                        end, lists:seq(0, 8)),&lt;br /&gt;                          io:format("~n", [])&lt;br /&gt;                  end, lists:seq(0, 8)).&lt;br /&gt;                          &lt;br /&gt;dict_from_list(List) -&gt;&lt;br /&gt;    element(2, lists:foldl(fun(Elm, {X, Dict}) -&gt;&lt;br /&gt;                                   {_, DDict} = lists:foldl(fun(Elem, {Y, NDict}) -&gt;&lt;br /&gt;                                                                    {Y + 1, dict:store({X, Y}, Elem, NDict)}&lt;br /&gt;                                                            end, {0, Dict}, Elm),&lt;br /&gt;                                   {X + 1, DDict}&lt;br /&gt;                           end, {0, dict:new()}, List)).&lt;br /&gt;&lt;br /&gt;solve_puzzle(Puzzle) -&gt;&lt;br /&gt;    case generate_open_spots(Puzzle) of&lt;br /&gt;        [{{X, Y}, Set} | _] -&gt;&lt;br /&gt;            try_value({X, Y}, Set, Puzzle);&lt;br /&gt;        [] -&gt;&lt;br /&gt;            {solved, Puzzle}&lt;br /&gt;    end.&lt;br /&gt;&lt;br /&gt;try_value(_, [], Puzzle) -&gt;&lt;br /&gt;    print(Puzzle),&lt;br /&gt;    io:format("~n", []),&lt;br /&gt;    failed;&lt;br /&gt;try_value({X, Y}, [H | R], Puzzle) -&gt;&lt;br /&gt;    case solve_puzzle(dict:store({X, Y}, H, Puzzle)) of&lt;br /&gt;        {solved, RPuzzle} -&gt;&lt;br /&gt;            {solved, RPuzzle};&lt;br /&gt;        failed -&gt;&lt;br /&gt;            try_value({X, Y}, R, Puzzle)&lt;br /&gt;    end.&lt;br /&gt;                      &lt;br /&gt;generate_open_spots(Puzzle) -&gt;&lt;br /&gt;    OpenSquareList = dict:fold(fun(Key, b, Acc) -&gt;&lt;br /&gt;                                       [Key | Acc];&lt;br /&gt;                                  (_Key, _Value, Acc) -&gt;&lt;br /&gt;                                       Acc&lt;br /&gt;                               end, [], Puzzle),&lt;br /&gt;    lists:sort(fun({{_X1, _Y1}, E1}, {{_X2, _Y2}, E2}) when length(E1) &lt; length(E2) -&gt;&lt;br /&gt;                       true;&lt;br /&gt;                  (_E1, _E2) -&gt;&lt;br /&gt;                       false&lt;br /&gt;               end, generate_open_values(OpenSquareList, Puzzle)).&lt;br /&gt;&lt;br /&gt;generate_open_values(List, Puzzle) -&gt;&lt;br /&gt;    generate_open_values(List, [], Puzzle).&lt;br /&gt;&lt;br /&gt;generate_open_values([], Acc, _Puzzle) -&gt;&lt;br /&gt;    Acc;&lt;br /&gt;generate_open_values([{X, Y} | R], Acc, Puzzle) -&gt;&lt;br /&gt;    generate_open_values(R, [{{X, Y}, remove_region_vals({X, Y},&lt;br /&gt;                                                         remove_x_vals(Y,&lt;br /&gt;                                                                       remove_y_vals(X, lists:seq(1, 9),&lt;br /&gt;                                                                                     Puzzle),&lt;br /&gt;                                                                       Puzzle),&lt;br /&gt;                                                         Puzzle)} | Acc],&lt;br /&gt;                         Puzzle).&lt;br /&gt;&lt;br /&gt;remove_x_vals(Y, List, Puzzle) -&gt;&lt;br /&gt;    lists:foldl(fun(Idx, Acc) -&gt;&lt;br /&gt;                        case dict:fetch({Idx, Y}, Puzzle) of&lt;br /&gt;                            b -&gt;&lt;br /&gt;                                Acc;&lt;br /&gt;                            E -&gt;&lt;br /&gt;                                lists:delete(E, Acc)&lt;br /&gt;                        end&lt;br /&gt;                        end,&lt;br /&gt;                        List, lists:seq(0, 8)).&lt;br /&gt;&lt;br /&gt;remove_y_vals(X, List, Puzzle) -&gt;&lt;br /&gt;    lists:foldl(fun(Idx, Acc) -&gt;&lt;br /&gt;                        case dict:fetch({X, Idx}, Puzzle) of&lt;br /&gt;                            b -&gt;&lt;br /&gt;                                Acc;&lt;br /&gt;                            E -&gt;&lt;br /&gt;                                lists:delete(E, Acc)&lt;br /&gt;                        end&lt;br /&gt;                        end,&lt;br /&gt;                        List, lists:seq(0, 8)).&lt;br /&gt;&lt;br /&gt;remove_region_vals({X, Y}, List, Puzzle) -&gt;&lt;br /&gt;    {RX, RY} = find_region(X, Y),&lt;br /&gt;    lists:foldl(fun(IX, AccX) -&gt;&lt;br /&gt;                        lists:foldl(fun(IY, AccY) -&gt;&lt;br /&gt;                                            case dict:fetch({IX, IY}, Puzzle) of&lt;br /&gt;                                                b -&gt;&lt;br /&gt;                                                    AccY;&lt;br /&gt;                                                E -&gt;&lt;br /&gt;                                                    lists:delete(E, AccY)&lt;br /&gt;                                            end&lt;br /&gt;                                    end, AccX, lists:seq(RY, RY + 2))&lt;br /&gt;                        end, List, lists:seq(RX, RX + 2)).&lt;br /&gt;&lt;br /&gt;find_region(X, Y) -&gt;&lt;br /&gt;    {find_region(X), find_region(Y)}.&lt;br /&gt;&lt;br /&gt;find_region(V) when V &gt;= 0, V &lt; 3 -&gt;&lt;br /&gt;    0;&lt;br /&gt;find_region(V) when V &gt;= 3, V &lt; 6 -&gt;&lt;br /&gt;    3;&lt;br /&gt;find_region(V) when V &gt;= 6, V &lt; 9 -&gt;&lt;br /&gt;    6.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-5723399369383810022?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/5723399369383810022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2006/11/sudoku.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5723399369383810022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5723399369383810022'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2006/11/sudoku.html' title='Sudoku'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-8248363012567711379</id><published>2006-07-19T14:28:00.000-04:00</published><updated>2009-10-18T18:16:23.296-04:00</updated><title type='text'>Lack of activity</title><content type='html'>I have been busy looking for a job so I have had not had much time to do anything Erlang related.  This, unfortunately, means I have not had much time to blog.  I am hoping this will change by Sept.  If anyone has any job offers and wants a resume,  I am currently looking in the New York Ciy area for Financial Programming work or Bioinformatics work.  Send an email to orbitz AT ortdotlove.net   (that is really ortdotlove.net, not fancy spelling for ort.love.net).  I'll gladly mail you back my resume.&lt;br /&gt;&lt;br /&gt;I'm looking forward to getting back to programming for fun soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-8248363012567711379?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/8248363012567711379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2006/07/lack-of-activity.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/8248363012567711379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/8248363012567711379'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2006/07/lack-of-activity.html' title='Lack of activity'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-4515054154466526530</id><published>2006-05-30T00:43:00.000-04:00</published><updated>2009-10-18T18:16:23.302-04:00</updated><title type='text'>Shell</title><content type='html'>The other day, araujo suggested Erlang might make a good shell.  Shell as in, bash.  Hrm, I thought, maybe...&lt;br /&gt;I don't think Erlang would be flexible enough to make a decent shell.  Take something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;for i in *; do echo $i; done&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What would the Erlang equivalent look like?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;lists:map(fun(X) -&gt; print([X]) end, ls())&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I just don't see it?  I should hope it doesn't look like that but I don't know.  On the other hand, I seem to have it pretty set in my mind that Common Lisp would make an excellent shell language.  A few people have told me that CL would probably be too verbose and not work out well but,  I don't know, it just seems so succinct and powerful.  You could make a lot of macros to make your life easier.  I sent an email to the Lisp At Light Speed blog dude to get his opinion but I figured I'd post it here too to see if anyone has any thoughts.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;What I have in mind is basically an interactive shell, using Common&lt;br /&gt;Lisp as its programming language.  For instance something like:&lt;br /&gt; &lt;br /&gt;for i in *; do echo $i; done&lt;br /&gt; &lt;br /&gt;Might look like:&lt;br /&gt; &lt;br /&gt;(loop for i in (ls) do (print i))&lt;br /&gt; &lt;br /&gt;The second thing I would love to see is Monad/Powershell.  Rather&lt;br /&gt;than using text to pass data around, uses lists/objects/etc.  (ls)&lt;br /&gt;for instance gives a list of file objects to iterate over, and you&lt;br /&gt;can extract things like the size and permissions and what not.&lt;br /&gt; &lt;br /&gt;This raises a question though. In order to do this, just about every&lt;br /&gt;standard program becomes obsolete. For instance, why use 'cut' when&lt;br /&gt;you can simply split a string with a CL function.  However some&lt;br /&gt;things would still be very useful, such as ls, or grep, but these&lt;br /&gt;now need to communicate via objects rather than just text, so those&lt;br /&gt;will have ot be rewritten.  In which cause it seems like they could&lt;br /&gt;simply be packages and loaded into the shell, meaning you don't&lt;br /&gt;have to deal with program startup times or what not.  Is this a lot&lt;br /&gt;of work to rewrite all of these programs, and does it mean that we&lt;br /&gt;cannot usefully use third party programs that people write?  You&lt;br /&gt;can always drop down to using strings as communication I suppose.&lt;br /&gt; &lt;br /&gt;That is the basic idea.  So far a few people have suggested that&lt;br /&gt;sexprs really aren't any better for this sort of thing.  sexpr's&lt;br /&gt;won't be any better than say...bash.  Someone suggested that Factor&lt;br /&gt;might be a better language for this.  But it seems to me, with&lt;br /&gt;Common Lisps powerful macro system, you can easily make most&lt;br /&gt;operations incredibly simple?  The most useful aspect would be using&lt;br /&gt;objects to communicate.  But even if this is a lot of work to&lt;br /&gt;accomplish, it seems to me that simply using CL as a shell programming&lt;br /&gt;language seems like it would be nice. Am I wrong here? Am I missing&lt;br /&gt;something?&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If CL would make a poor langauge, what would make a good language?  Riastrach has suggested Factor.  I don't know enough about factor to say that but I think I like CL better for this.&lt;br /&gt;&lt;br /&gt;All I know is:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://squirrelsh.sourceforge.net/"&gt;This is not the answer&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-4515054154466526530?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/4515054154466526530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2006/05/shell.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4515054154466526530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4515054154466526530'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2006/05/shell.html' title='Shell'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-766614150586339395</id><published>2006-05-06T23:27:00.000-04:00</published><updated>2009-10-18T18:16:23.308-04:00</updated><title type='text'>Pastebin design - Mnesia tables</title><content type='html'>I have started to design the tables for this.  The main goal is simple: make it easily extendable.  That is to say I want to make it so I can easily develope it incrementally and add things to it that I didn't think of before.  But that should be obvious to any developer.  Given the spec of my previous post, here is the beginning of the database.&lt;br /&gt;&lt;br /&gt;Table:&lt;br /&gt;paste - This is the table that will hold the actual pastes.  &lt;br /&gt;pid | text | annotation | language | date&lt;br /&gt;&lt;br /&gt;pid - unique id to identify a paste&lt;br /&gt;text - the actual text&lt;br /&gt;annotation - any annotation the paster wants to include&lt;br /&gt;language - Plaintext/C++/Erlang, etc&lt;br /&gt;date - when they pasted it&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;highlight - cache of pastes that have been put through the source highlighter&lt;br /&gt;pid | text | last_viewed&lt;br /&gt;&lt;br /&gt;pid - the same as paste.pid&lt;br /&gt;text - result of being put through the highlighter&lt;br /&gt;last_viewed - to keep track of when the entry should be removed&lt;br /&gt;&lt;br /&gt;threads - paste threads&lt;br /&gt;tid | [pid]&lt;br /&gt;&lt;br /&gt;tid - the unique id for a thread&lt;br /&gt;[pid] - list of pid's&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I decided to have the thread table just contain an id and list so you don't have to do a bunch of queries to get every paste in a thread.  This way a paste can be part of multiple threads (Although I don't see when this will ever happen).    The paste table contains, I think, the minimalist amount of data in order to be useful.  Using a highlight table means we can store, if we want, every single paste with a highlighted copy of the text, or just a few and use it as a cache style system.  Later on we can also add the ability to associate a paste with an irc channel or a user if we wish to track that sort of information.&lt;br /&gt;&lt;br /&gt;I'm not sure how to generate unique id's in mnesia.  In a SQL database I would use a serial data type but I am unsure if mnesia supports this functionality.  If not I suppose I could use newref maybe?  I need to be able to convert it to a string to make url's, and also be valid between restarts.&lt;br /&gt;&lt;br /&gt;As I think about it, I guess serials are just implemented as a table and store the integer in there, I can implement that in mnesia I suppose.  It just needs to have some sort of get_and_increment functionality so two proceses don't get the same idea.  If anyone has any ideas on how to implement this let me know.  Bear in mind I have not looked at the mnesia documentation yet and am just brainstorming, so it is quite possible the solution is incredibly simple.&lt;br /&gt;&lt;br /&gt;Next step - determine what pages pages will be needed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-766614150586339395?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/766614150586339395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2006/05/pastebin-design-mnesia-tables.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/766614150586339395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/766614150586339395'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2006/05/pastebin-design-mnesia-tables.html' title='Pastebin design - Mnesia tables'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-2943662025259319126</id><published>2006-05-04T01:08:00.000-04:00</published><updated>2009-10-18T18:16:23.319-04:00</updated><title type='text'>Erlang Pastebin</title><content type='html'>I have always wanted to make a pastebin for some reason.  When I first started looking at nevow, I wanted to make one in that however mg beat me to it (and made a kickass one at that).  So now I have been looking at yaws and think it would be a good project.  Perhaps it can be packaged along with the wiki and chat client.  I think my pastebin is a bit ambitious, but I would like to design it in such a way that it can all be added incrementally so I can have a functional pastebin and add onto it.&lt;br /&gt;&lt;br /&gt;For starters, I would like a nice clean layout.  I am going to do my best to use CSS and valid HTML for all of this.  I am hoping petekaz can possibly help out with this.  I am going to write it with everything in a div tags with proper ids so it should be easy to give this thing a skin eventually.&lt;br /&gt;&lt;br /&gt;Technical Features:&lt;br /&gt;Syntax highlighting - As with any pastebin this will most likely be used for code 90% of the time.  For all of those languages we need syntax highlighting so they are easy to read.  I have found a program, I beleive it is just called 'highlight'.  It handles 100+ languages, including all of the ones I have an interst in supporting so I can simply interface to that.&lt;br /&gt;&lt;br /&gt;Documentation links - People seem to want this.  I am not sure how easy it is to support, especially if you want to support a lot of languages.  It's a thought but not on the top of my list.&lt;br /&gt;&lt;br /&gt;Annotation - Instead of putting suplimentery information in comments of the paste, just having a section for such information would be nice.&lt;br /&gt;&lt;br /&gt;Threads for pastes - lisppaste does this I beleive.  A paste should be like a discussion.  "Here this doesn't compile" "You have a mistake here, this fix will work" "Ok, but now I have a problem here" "Ok do this".  Each post in a paste thread will have the paste + annotation.  To reply, since you are generally going to simply be making small changes to the previous post, the paste section should be populated with that already.&lt;br /&gt;&lt;br /&gt;Compile code for your language - I am not sure how to do this safely, if at all.  It would be nice to provide a gcc interface and an erlc interface and a ghc, yadda yadda.  But I am not going to put my system at risk just for this feature that shouldn't be needed all too much in the first place.&lt;br /&gt;&lt;br /&gt;Interface to any erlang app - By providing a node + a process name, this should be able to send a message that  paste is ready to any erlang node.  The obvious first usage of this would be an IRC bot.  The main problem I see with this is, depending on what application the data is sent to, that will affect the look of the pastebin.  For example, if the events are sent to an IRC bot, you want to be able to select what channel the notification gets sent to for the IRC bot.  Should I just hardcode this into the pastebin or provide some way for the IRC bot to register information with the pastebin and somehow have the pastebin display the information on the web app?  This sounds a bit harder, but works better with any application (But what other applications would even want notification of a paste?).  Perhaps I will hard code it at first and then move towards a more dynamic system as I figure out how.&lt;br /&gt;&lt;br /&gt;Mnesia configuration - I like to use mnesia for my configuration.  I have a config module which provides functions to be used in setting/getting values from the mnesia config data base.  I also want to use mnesia to store all of the information for the actual pastes.  I hear mnesia falls apart after store a lot of data, I can imagine some of these pastes will grow to be a fair size, so I am considering using a cache for the syntax highlighted pastes.  Running the application to highlight the text on every hit sounds inefficient, and storing it for every paste sounds like a waste of space, so a cache is probably a good inbetween.  Right now I would like to store as many pastes as I can but will consider deleting those that are too old.&lt;br /&gt;&lt;br /&gt;Download paste - Being able to download the paste is always very helpful.  Providing a nice filename that ends in the proper extension for the language would be nice.&lt;br /&gt;&lt;br /&gt;Browsing recent pastes - You paste to my site you loste all privacy, go figure.&lt;br /&gt;&lt;br /&gt;File upload - Somtimes it is easier to just upload a file rather than pasting.&lt;br /&gt;&lt;br /&gt;This sounds like a lot but I don't think it will be too bad.  It seems like I should be able to do most of it fairly modular.&lt;br /&gt;&lt;br /&gt;Step one - Come up with mnesia tables, do some research on mnesia in terms of foreign keys and possibly how to do decent QLC queries.  I think learning QLC will be important, especially when a lot of pastes get put into this thing.&lt;br /&gt;&lt;br /&gt;Step two - Get the basic form for uploading going&lt;br /&gt;&lt;br /&gt;Step three - Come up with step three when I get there.&lt;br /&gt;&lt;br /&gt;UPDATE&lt;br /&gt;Some obvious ideas were brought to my attention&lt;br /&gt;&lt;br /&gt;Indent - Running various languages through astyle and friends would be very helpful, some people just can't indent properly.&lt;br /&gt;&lt;br /&gt;Customize with cookies - Store various color information in cookies so people can keep colors they enjoy.  This probably won't be implemented until much later.&lt;br /&gt;&lt;br /&gt;Differences - Highlight differences between pastes so you can show what changes have been made.  This sounds kind of difficult, especially if I am outsourcing the highlighting to a third party.&lt;br /&gt;&lt;br /&gt;Line numbers - This should be obvious&lt;br /&gt;&lt;br /&gt;Non GUI Browsers - Yes some people use these.  The download as text option should be helpful for these people, but the probably also want line numbers so a specific Non GUI version of the code might be nice, this will include line numbers.  &lt;br /&gt;&lt;br /&gt;RSS - This certainly isn't a need but might be nice, especialy as the maintainer I might want to keept track of who's pasting what.&lt;br /&gt;&lt;br /&gt;Intelligent Mouseovers - Showing balanced paren when the mouse is over&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-2943662025259319126?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/2943662025259319126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2006/05/erlang-pastebin.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/2943662025259319126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/2943662025259319126'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2006/05/erlang-pastebin.html' title='Erlang Pastebin'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-5839170827110759707</id><published>2006-04-04T20:24:00.000-04:00</published><updated>2009-10-18T18:16:23.327-04:00</updated><title type='text'>Yaws 1.58 true_nozip bug</title><content type='html'>Yaws 1.58 has a bit of a bug.  If you specify dir_listings = true_nozip, it poops out.  This is because the if condition is written to only handle the situation where it is true or false.&lt;br /&gt;&lt;br /&gt;Here is my little bug fix, the problem file is src/yaws_ls.erl&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;47c47,54&lt;br /&gt;&lt;            if DoAllZip == true -&gt; allzip() end,&lt;br /&gt;---&lt;br /&gt;&gt;            case DoAllZip of&lt;br /&gt;&gt;                  true -&gt;&lt;br /&gt;&gt;                      allzip();&lt;br /&gt;&gt;                  true_nozip -&gt;&lt;br /&gt;&gt;                      [];&lt;br /&gt;&gt;                  false -&gt;&lt;br /&gt;&gt;                      []&lt;br /&gt;&gt;              end,&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;klacke says he also has a fix but, as usual, sourceforge is down so he has not been able to commit it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-5839170827110759707?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/5839170827110759707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2006/04/yaws-158-truenozip-bug.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5839170827110759707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5839170827110759707'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2006/04/yaws-158-truenozip-bug.html' title='Yaws 1.58 true_nozip bug'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-1344815795007503810</id><published>2006-03-31T17:04:00.000-05:00</published><updated>2009-10-18T18:16:23.339-04:00</updated><title type='text'>Fun with processes (Updated)</title><content type='html'>I really need to go through all of my Erlang documentation so people like petekaz can stop making me feel small.&lt;br /&gt;I had an issue with some poor Erlang code I was running where it performed a file:open but not the appropriate file:close.  Not wanting to restart my application I wanted to know how I could fix this problem without shutting it down.  Erlang, of course, provides a solution.&lt;br /&gt;One thing that made this workable in the first place was the fact that I had no other open files besides those that needed to be closed.&lt;br /&gt;&lt;br /&gt;So imagine for a second you have opened a number of files and lost the reference to them.  For example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(ort_bot@blong)21&gt; [file:open("/tmp/c2.log", read) || X &lt;- lists:seq(1, 10)].&lt;br /&gt;[{ok,&lt;0.8974.7&gt;},&lt;br /&gt; {ok,&lt;0.8975.7&gt;},&lt;br /&gt; {ok,&lt;0.8976.7&gt;},&lt;br /&gt; {ok,&lt;0.8977.7&gt;},&lt;br /&gt; {ok,&lt;0.8978.7&gt;},&lt;br /&gt; {ok,&lt;0.8979.7&gt;},&lt;br /&gt; {ok,&lt;0.8980.7&gt;},&lt;br /&gt; {ok,&lt;0.8981.7&gt;},&lt;br /&gt; {ok,&lt;0.8982.7&gt;},&lt;br /&gt; {ok,&lt;0.8983.7&gt;}]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;file:open causes a process to be created (this is Erlang afterall).&lt;br /&gt;In the shell you can simply type i(). and get output like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(ort_bot@blong)22&gt; i().&lt;br /&gt;Pid                   Initial Call                          Heap     Reds Msgs&lt;br /&gt;Registered            Current Function                     Stack              &lt;br /&gt;&lt;0.0.0&gt;               otp_ring0:start/2                      377     6569    0&lt;br /&gt;init                  init:loop/1                              2              &lt;br /&gt;&lt;0.2.0&gt;               erlang:apply/2                        4181   179350    0&lt;br /&gt;erl_prim_loader       erl_prim_loader:loop/3                   5              &lt;br /&gt;&lt;0.4.0&gt;               gen_event:init_it/6                   1597     1114    0&lt;br /&gt;error_logger          gen_event:loop/4                        10              &lt;br /&gt;&lt;0.5.0&gt;               erlang:apply/2                        6765     8325    0&lt;br /&gt;application_controlle gen_server:loop/6                        7              &lt;br /&gt;&lt;0.7.0&gt;               application_master:init/4              377       45    0&lt;br /&gt;                      application_master:main_loop/2           8              &lt;br /&gt;&lt;0.8.0&gt;               application_master:start_it/4          233       90    0&lt;br /&gt;                      application_master:loop_it/4             5              &lt;br /&gt;&lt;0.9.0&gt;               supervisor:kernel/1                    610     1373    0&lt;br /&gt;kernel_sup            gen_server:loop/6                       12              &lt;br /&gt;&lt;0.10.0&gt;              rpc:init/1                             610 17456475    0&lt;br /&gt;rex                   gen_server:loop/6                       12              &lt;br /&gt;&lt;0.11.0&gt;              global:init/1                          233     1246    0&lt;br /&gt;global_name_server    gen_server:loop/6                       12              &lt;br /&gt;&lt;0.12.0&gt;              erlang:apply/2                         233      275    0&lt;br /&gt;                      global:loop_the_locker/1                 4              &lt;br /&gt;&lt;0.13.0&gt;              erlang:apply/2                         233        4    0&lt;br /&gt;                      global:collect_deletions/2               6              &lt;br /&gt;&lt;0.14.0&gt;              inet_db:init/1                         233      137    0&lt;br /&gt;inet_db               gen_server:loop/6                       12              &lt;br /&gt;&lt;0.16.0&gt;              supervisor:erl_distribution/1          377      307    0&lt;br /&gt;net_sup               gen_server:loop/6                       12              &lt;br /&gt;&lt;0.17.0&gt;              erl_epmd:init/1                        233      137    0&lt;br /&gt;erl_epmd              gen_server:loop/6                       12              &lt;br /&gt;&lt;0.18.0&gt;              auth:init/1                            233       77    0&lt;br /&gt;auth                  gen_server:loop/6                       12              &lt;br /&gt;&lt;0.19.0&gt;              net_kernel:init/1                      233     3272    0&lt;br /&gt;net_kernel            gen_server:loop/6                       12              &lt;br /&gt;&lt;0.20.0&gt;              inet_tcp_dist:accept_loop/2            233      178    0&lt;br /&gt;                      prim_inet:accept0/2                     10              &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This list goes on for awhile longer, depending on what you have done. As you scan through this output you should see something like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;0.8974.7&gt;            erlang:apply/2                         233      135    0&lt;br /&gt;                      file_io_server:server_loop/1             3              &lt;br /&gt;&lt;0.8975.7&gt;            erlang:apply/2                         233      135    0&lt;br /&gt;                      file_io_server:server_loop/1             3              &lt;br /&gt;&lt;0.8976.7&gt;            erlang:apply/2                         233      135    0&lt;br /&gt;                      file_io_server:server_loop/1             3              &lt;br /&gt;&lt;0.8977.7&gt;            erlang:apply/2                         233      135    0&lt;br /&gt;                      file_io_server:server_loop/1             3              &lt;br /&gt;&lt;0.8978.7&gt;            erlang:apply/2                         233      135    0&lt;br /&gt;                      file_io_server:server_loop/1             3              &lt;br /&gt;&lt;0.8979.7&gt;            erlang:apply/2                         233      135    0&lt;br /&gt;                      file_io_server:server_loop/1             3              &lt;br /&gt;&lt;0.8980.7&gt;            erlang:apply/2                         233      135    0&lt;br /&gt;                      file_io_server:server_loop/1             3              &lt;br /&gt;&lt;0.8981.7&gt;            erlang:apply/2                         233      135    0&lt;br /&gt;                      file_io_server:server_loop/1             3              &lt;br /&gt;&lt;0.8982.7&gt;            erlang:apply/2                         233      135    0&lt;br /&gt;                      file_io_server:server_loop/1             3              &lt;br /&gt;&lt;0.8983.7&gt;            erlang:apply/2                         233      135    0&lt;br /&gt;                      file_io_server:server_loop/1             3   &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;All of those file_io_server's are the open files.  And the Pid associated with it is the file handle.  So to close all these files all you have to do is call file:close on those pids.  You can create a pid give 3 numbers in the shell by using the pid function:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(ort_bot@blong)23&gt; file:close(pid(0, 8974, 7)).                              &lt;br /&gt;ok&lt;br /&gt;(ort_bot@blong)24&gt; file:close(pid(0, 8975, 7)).&lt;br /&gt;ok&lt;br /&gt;(ort_bot@blong)25&gt; file:close(pid(0, 8976, 7)).&lt;br /&gt;ok&lt;br /&gt;(ort_bot@blong)26&gt; file:close(pid(0, 8977, 7)).&lt;br /&gt;ok&lt;br /&gt;(ort_bot@blong)27&gt; file:close(pid(0, 8978, 7)).&lt;br /&gt;ok&lt;br /&gt;(ort_bot@blong)28&gt; file:close(pid(0, 8979, 7)).&lt;br /&gt;ok&lt;br /&gt;(ort_bot@blong)29&gt; file:close(pid(0, 8980, 7)).&lt;br /&gt;ok&lt;br /&gt;(ort_bot@blong)30&gt; file:close(pid(0, 8981, 7)).&lt;br /&gt;ok&lt;br /&gt;(ort_bot@blong)31&gt; file:close(pid(0, 8982, 7)).&lt;br /&gt;ok&lt;br /&gt;(ort_bot@blong)32&gt; file:close(pid(0, 8983, 7)).&lt;br /&gt;ok&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, call i() again and you'll notice all of those pesky file's have been closed.  You can also do all of this from a remote machine if you have run your erl properly.  For example my remote application is run on a machine called 'blong' and the node name is 'ort_bot'.  I am on 'ooter' on a machine called 'osx'.  So from 'osx' I can do this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;osx:~/projects/Erlang orbitz$ erl -sname ooter -setcookie cookiemonster&lt;br /&gt;Erlang (BEAM) emulator version 5.4.13 [source] [threads:0]&lt;br /&gt;&lt;br /&gt;Eshell V5.4.13  (abort with ^G)&lt;br /&gt;(ooter@osx)1&gt; &lt;br /&gt;User switch command&lt;br /&gt; --&gt; r ort_bot@blong&lt;br /&gt; --&gt; j&lt;br /&gt;   1  {shell,start,[init]}&lt;br /&gt;   2* {ort_bot@blong,shell,start,[]}&lt;br /&gt; --&gt; c 2&lt;br /&gt;Eshell V5.4.12  (abort with ^G)&lt;br /&gt;(ort_bot@blong)1&gt; i().&lt;br /&gt;Pid                   Initial Call                          Heap     Reds Msgs&lt;br /&gt;Registered            Current Function                     Stack              &lt;br /&gt;&lt;0.0.0&gt;               otp_ring0:start/2                      377     6579    0&lt;br /&gt;init                  init:loop/1                              2              &lt;br /&gt;&lt;0.2.0&gt;               erlang:apply/2                         610   161416    0&lt;br /&gt;erl_prim_loader       erl_prim_loader:loop/3                   5              &lt;br /&gt;&lt;0.4.0&gt;               gen_event:init_it/6                    610      557    0&lt;br /&gt;error_logger          gen_event:loop/4                        10              &lt;br /&gt;&lt;0.5.0&gt;               erlang:apply/2                        6765     8289    0&lt;br /&gt;application_controlle gen_server:loop/6                        7              &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Connecting to a remote shell is easy and we now have a shell on that node and can do anything from here we want (infact I've done halt(). quite a few times by accident not thinking oi!).&lt;br /&gt;&lt;br /&gt;Alternativly, you can also use pman, which provides an interface much like i() but does more interesting stuff too.  For instance you can see linked processes and kill various processe through pman.  In order to use pman, on your local node simply run: pman:start().&lt;br /&gt;This provide you with a window that looks like:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://ortdotlove.net/~orbitz/images/pman_01.png"/&gt;&lt;br /&gt;&lt;br /&gt;This looks just like i().  And from the 'node' menu you can switch nodes to view the processes on.  As you can see from this screenshot I am viewing the processes on ort_bot@blong, which is a remote node.&lt;br /&gt;&lt;br /&gt;As you can see, Erlang provides a very powerful set of tools to keep your application stable and perform various operations.  It is things like this that make me glad to run code in a shell rather than a stand alone appliction.  For situations like this, the power of the erlang shell is unparalleled.&lt;br /&gt;&lt;br /&gt;Update:&lt;br /&gt;Well in his infinite wisdom, after a bit of playing around petekaz came up with two functions that makes solving this particular problem all of the easier.  My goal was mainy to show how to interact with the shell to get useful information about processes, but petekaz has shown me how to actually close a specific file.  It seems file:open drops some useful information into ets.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;[ file:close(P) || P &lt;- processes(), {ok, "/tmp/test.erl"} == file:pid2name(P) ].&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Where "/tmp/test.erl" is the file you are trying to close.&lt;br /&gt;This makes use of two useful functinos.  processes for starters evaluates to a list of all current proceses runninging in the node, and file:pid2name takes a pid and tells you what file it is associated with.  If the pid is not a file it returns undefined.&lt;br /&gt;So it seems Erlang has a complete solution to this problem.&lt;br /&gt;&lt;br /&gt;Thanks petekaz for figuring this one out completely.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-1344815795007503810?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/1344815795007503810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2006/03/fun-with-processes-updated.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1344815795007503810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1344815795007503810'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2006/03/fun-with-processes-updated.html' title='Fun with processes (Updated)'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-9156454241247392277</id><published>2006-03-23T22:33:00.000-05:00</published><updated>2009-10-18T18:16:23.356-04:00</updated><title type='text'>Oort</title><content type='html'>Well it was pretty painful but I ripped out most of my terrible code and replaced it with pretty gen_server's and the likes.  The code is still in a state of flux and needs to be polished a bit more, but it's a good start.  You can gawk at it here:&lt;br /&gt;&lt;br /&gt;svn://ortdotlove.net/Erlang/trunk/p1&lt;br /&gt;&lt;br /&gt;Ignore the manderlbot source tree in there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-9156454241247392277?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/9156454241247392277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2006/03/oort.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/9156454241247392277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/9156454241247392277'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2006/03/oort.html' title='Oort'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-8994171110846398548</id><published>2006-03-06T12:43:00.000-05:00</published><updated>2009-10-18T18:16:23.366-04:00</updated><title type='text'>MEUG</title><content type='html'>MEUG is Massachusetts Erlang User Group.&lt;br /&gt;For some reason, there seem to be a lot of Erlang users in MA.   I would like to get us all together semi-regularly.  We can enjoy some good food, some drinks, and talk about Erlang, or whatever else comes up. Concurrency in general is an interesting topic that that is much to talk about.&lt;br /&gt;I will keep people updated.  If there are any MA based Erlangers interested that I am not yet aware of feel free to email me at:&lt;br /&gt;orbitz AT ortdotlove.net  (That is really ortdotlove) or post a comment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-8994171110846398548?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/8994171110846398548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2006/03/meug.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/8994171110846398548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/8994171110846398548'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2006/03/meug.html' title='MEUG'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-5522379107049731702</id><published>2006-01-23T12:04:00.000-05:00</published><updated>2009-10-18T18:16:23.373-04:00</updated><title type='text'>Re: Re: Re: Ruby Array class sucks</title><content type='html'>I have been meaning to respond to this &lt;a href="http://factor-language.blogspot.com/2005/12/approaching-functional-programming.html"&gt;post&lt;/a&gt; on the factor blog for awhile.  Factor has grown a lot, and this blog tracks the development of it.  Factor is the result of Forth and Lisp having babies.  But the post I'm interested in doesn't have so much to do with factor but with ruby.  It is in response to another post (URL at the factor site) about a complaint with Ruby's Array class.  The complaint centers mainly around the Array object having far more methods than it should and quite a few that don't belong there.  Slava's (factor creator) response suggests that the methods do deserve to be there and from a functional standpoint most of them make plenty of sense.&lt;br /&gt;&lt;br /&gt;For a number of the methods in Array, I do agree with slava that they should be present.  For instance, the authors complaint about Array.new being able to preset an array to a specific value is silly to me, I often want some sort of initial value to work from so I would imagine many other people are in my boat.&lt;br /&gt;&lt;br /&gt;Around Array.transpose, I start to disagree though.  transpose takes an Array and treats it like a matrix.  Slava's response is:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;It might surprise the author to learn that mathematically, a matrix &lt;i&gt;is&lt;/i&gt; a two-dimensional array. In Factor, you can perform mathematical operations on vectors, such as vector addition, dot product, and so on.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Ok, so basicaly the argument is, a matrix resembles an array in some way and factor allows these sort of manipulations, thus ruby should.  Well ok, let's say, yes, a matrix is a two-dimensional array, that's nice.  But what does that make an Array then?  An Array is also a two-dimensional array? That sounds a bit circular.  Why should a method in Array depend on Array being thought of as a specific type of object.  If we want to do matrix work, I suggest abstracting a matrix type, even if it's as simple as Matrix = Array.  But really, it sounds like transpose should be in some sort of Matrix object.&lt;br /&gt;&lt;br /&gt;Array.rassoc also seems a bit out of place to me.  Slava says:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Yes, and there's nothing wrong with that. Association lists, while they suffer from linear lookup time, are occasionally useful where you want to have a mapping together with a certain intrinsic order. For example, Factor's generic word code takes the hashtable of methods defined on a generic, converts this to an association list, then sorts the association list according to the partial ordering of classes. Finally, the sorted association list is used to generate code.&lt;/blockquote&gt;&lt;br /&gt;Again, the argument of "This is ok because factor does it" does not quite fly with me.  Now, when I write code and I'm not quite sure what data type I really want, but I need some sort of key-&gt;value association, I will often just use a list or array type to start out with, abstracted into some interface so when I decide what I finally need I can simply change the backend.  Now, is this a good reason to put a function that treats a list like a map inside a list object?  In my opinion, No.&lt;br /&gt;&lt;br /&gt;In my opinion, I would use some sort of generic sequence object that has various methods that act on arrays and lists and other sequence objects, allowing you to perform some of these manipulations.  In most languages, I would probably go as far to even make something like rassoc just be a plain function, no need to make it part of an object.  But I have a feeling a lot of Ruby programmers don't feel content unless they have methods in some class.&lt;br /&gt;&lt;br /&gt;This Array object seems to be similar to various classes in Python.  Back in the day, Python developers could add methods to classes without any sort of vote.  This is why the Python standard lib has lots of random modules that one would not normally think should be in a standard library, and also why Python has been making such an effort to clean up a lot of the standard classes and provide a more consistent interface to them.&lt;br /&gt;&lt;br /&gt;Sorry this post does not actually contain anything on erlang.  My next one will, I promise.  Feel free to flame me in response to my Ruby thoughts, just be civil.&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-5522379107049731702?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/5522379107049731702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2006/01/re-re-re-ruby-array-class-sucks.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5522379107049731702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5522379107049731702'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2006/01/re-re-re-ruby-array-class-sucks.html' title='Re: Re: Re: Ruby Array class sucks'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-3853828046204515792</id><published>2005-11-21T23:11:00.000-05:00</published><updated>2009-10-18T18:16:23.381-04:00</updated><title type='text'>Port Drivers</title><content type='html'>Does anyone have any good tutorials on writing ports?  Google doesn't seem to return much on initial tries.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-3853828046204515792?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/3853828046204515792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/11/port-drivers.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/3853828046204515792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/3853828046204515792'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/11/port-drivers.html' title='Port Drivers'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-5730028025264922162</id><published>2005-11-17T22:43:00.000-05:00</published><updated>2009-10-18T18:16:23.389-04:00</updated><title type='text'>Single exit point</title><content type='html'>Many programmers insist on only having the flow of control in their function end at a single point.  I got wondering for a few minutes if any languages enforce this style of programming.  Then I realized.  Erlang has no 'return' operator, so doesn't Erlang enforce this?  That sounds about right as far as I can see.  So an Erlang function can only have 1 exit point.  That should make them feel good.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;But as was just pointed out to me in the middle of writing this, Erlang has 'throw'.  There can be many of thoughs.  So perhaps Erlang doesn't have 1 exit point.&lt;br /&gt;&lt;br /&gt;On a final note:&lt;br /&gt;Does having 1 exit point even matter? Who cares?  The beauty of Erlang (in my opinion) is it almost forces you to write short concise functions.  Every single one of my erlang functions fits on 1 screen easily, so does having multiple exit locations from there matter? In my opinion, no.  I don't need to go searching through pages of code for that function to find it, I can see it, so who cares?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-5730028025264922162?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/5730028025264922162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/11/single-exit-point.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5730028025264922162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5730028025264922162'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/11/single-exit-point.html' title='Single exit point'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-5172974583597272819</id><published>2005-09-21T19:39:00.000-04:00</published><updated>2009-10-18T18:16:23.396-04:00</updated><title type='text'>The Twisted Matrix</title><content type='html'>It has been a long road from where I started to using Erlang.  I certainly don't plan on stopping with Erlang but so far I am quite the fan of it.  On this road, which finally lead me here, I have used C, C++, Java, and Python, to name a few.  I still have code for a multithreaded http I was writing in C hanging around.&lt;br /&gt;I still use Python quite a bit, and one of the best tools in Python I have used is the &lt;a href="http://www.twistedmatrix.com/"&gt;Twisted Matrix&lt;/a&gt; framework.  Prior to discovering Erlang (well more of introduced to it by noss, which i am deeply in debt for), I felt that Python was really *the* language for socket programming.  Twisted is what made me think this.&lt;br /&gt;Now, just to be clear, Erlang certainly does not make Python obsolete.  Don't confuse enthusiasm for Erlang with feeling every other language is useless.  I introduced Python and Twisted into our development cycle at work and I am fairly pleased with the results.&lt;br /&gt;For those that don't know what Twisted is, it is a framework for developing software.  What makes Twisted special is they have put a lot of work into making everything work in one thread.  Making a server or client that handles multiple network connections is fairly trivial in Twisted.&lt;br /&gt;So what makes Twisted work how it does? A uniform eventloop.  In their case it's called a reactor.  There are a bunch of different kinds of reactors in Twisted.   One needs to be made for whichever kind of event loop you are using.  There is a select reactor (default), gtkreactor, gtk2reactor, wxwidgets reactor, and some sort of win32 reactor (I think still under development).  The good thing is, most of your code can generally be written without caring about what reactor is being used.  That is, atleast, the portions that don't depend on gtk or win32 or wx.&lt;br /&gt;Five years ago, when the Twisted project was first created, the authors feel that Python was the best language for the job.  My question is, if Twisted was started today, would Python still be the best choice.  I address part of the problem in a previous &lt;a href="http://orbitz-erlang.blogspot.com/2005/08/where-concurrency-shines.html"&gt;post&lt;/a&gt;. Part of the problem that I point out is, you have to do a lot of work to force everything into the event loop.  That makes code reuse more difficult, and near impossible if you need to use a proprietary library that you can't make non-blocking.&lt;br /&gt;An obvious example of this is the adbapi module.  adbapi module can use any DB-API 2.0 compliant module.  This is to make adbapi useful.  There are quite a few DB-API 2.0 compliant modules for Python so the best thing is to make use of them.  adbapi's API is not asynchronous or non-blocking though.  Doing queries in the Twisted reactor thread means the entire application will stall until the query is finished.  To solve this, Twisted does the queries in a thread.  Twisted has to fall-back on the very thing it is trying to avoid in order to work.  Python is particularly bad at threading too so Twisted tries to keep the number of threads to a reasonable amount.  This means the number of queries you can have going concurrently is dependent on this.&lt;br /&gt;A native implementation of the postgresql protocol has been implemented.  It is called &lt;a href="http://www.jamwt.com/pgasync/"&gt;pgasync&lt;/a&gt;.  I beleive the author has commented on how much quicker a large number of queries runs in his implementation, although I cannot find the quote.  But has the same problem I pointed out before.  Because Twisted is all in one thread, everything has to conform to its event loop making the implementation of the pgsql protocol useless.  It had to be rewritten to work well in Twisted.  This implementation is also fairly useless anywhere except Twisted.  I cannot use this in an application that uses an event loop other than Twisted.  Wouldn't it be nice if I could use code between projects that arn't dependent on Twisted?  In a COL this is a non-issue.  Simply run the database code in a process.  Processes are part of the language so they are part of any program.&lt;br /&gt;So, to get back to my question, would Python still be the choice of Twisted today, I don't know.  I asked the people of Twisted if they still would.  For the most part, it seems like they didn't quite know Erlang well enough to say if they would choose it.  A few developers said one of the main reasons they chose Python was for its large standard library.  In particular the 'os' module was pointed out as an important module that makes Python a good choice.  However, after some research, most of the 'os' module is in Erlang's standard library as well.  In my opinion, I think the quality of the Erlang standard library and OTP is quite a bit better than Pythons.  Python's standard library seems to have suffered from a time period where anyone put anything they wanted into it.  As a result, it is large, but a number of modules are fairly poor in quality.&lt;br /&gt;Even if Python has a number of modules in its standard library that are nice for building Twisted, they still need to do a lot of work to force all of this code into the Twisted event loop.  If you choose a COL, then you don't have to do any work in forcing code into a single event loop.  Instead, you have to do work to build the standard library that Python has.  Is that a lot of work? Yes.&lt;br /&gt;One could also argue, "There are a lot more Python projects than Erlang ones so there is a lot of code being written for Python that Twisted can make use of".  I think there is little contest in the point that there are more Python projects and programmers.  But can Twisted really make use of this code?  I think, in general, no, not without work.  A lot of interesting things are probably going to involve some blocking somewhere which either needs to be pushed to a thread or rewritten not to block, such as the example I have already given.&lt;br /&gt;The choice to use Python is a difficult one, I think.  In my opinion, Python really does not offer much that Erlang doesn't.  I think, considering the services Twisted is trying to offer, a COL would be an excellent choice for it.  Twisted does a lot of work trying to make asynchronous programming less confusing but writing concurrent programs is more natural.  It feels more natural atleast.&lt;br /&gt;I have had a lot of success using Twisted.  I don't think I'd write a socket program in Python without it.  I also think I would generally not write a socket program in Python these days.  Twisted and Erlang seem to be trying to accomplish much the same thing, although going about things in very different ways.  In the end I think something like Erlang will win out.  A COL seems to be saying, the world is concurrent so lets try to let people write in this natural way.  Whereas, Twisted is forcing people to write in a rather artifical and unnatural way.  Asynchronous programming works once you grasp it but even still the flow of the programs is rather awkward and hard to grasp I think.&lt;br /&gt;I feel that, today, something like Twisted would be better off written in a COL.  Let the work go into making powerful tools instead of massaging prewritten code into the event loop.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-5172974583597272819?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/5172974583597272819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/09/twisted-matrix.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5172974583597272819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5172974583597272819'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/09/twisted-matrix.html' title='The Twisted Matrix'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-6859902567308754574</id><published>2005-09-20T18:52:00.000-04:00</published><updated>2009-10-18T18:16:23.413-04:00</updated><title type='text'>Java And Threads (Jetty)</title><content type='html'>noss in #erlang on freenode recently brought to my attention: &lt;a href="http://www.mortbay.com/MB/log/gregw/?permalink=Jetty6Continuations.html"&gt;Jetty Continuations&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is an interesting blog entry. The basic idea is, instead of using 1 thread per connection, since connections can last awhile, they use 1 thread per request that a connection has. The hope being, a connection will idle most of the time and only send requests once in awhile. The problem that they ran into is, a piece of software is using a request timeout to poll for data. So requests are now sticking around for a long time, so they have all these active threads that they don't want. So to deal with this, they use a concept of continuations so the thread can die but the request still hang around, and then once it's ready to be processed a thread is created again and the request is handled. So having all these requests hanging around that arn't doing anything is no longer a problem.&lt;br /&gt;Well, this begs the question, why are you using a dynamic number of threads in the first place if you are going to have to limit how many you can even make. If the problem, in the first place, is they have too many threads running, then their solution works only for idle threads doesn't it? Being forced to push some of the requests to a continuation means they have applied some artificial limit to the number of threads which can be run. What happens then, when the number of valid active requests exceeds this limit? What then? Push active requests to a continuation and get to then when you have time? Simply don't let the new requests get handled? If they want to to use threads to solve their problem then putting a limit on them seems to make the choice of threads not a good one. Too poorly paraphrase Joe Armstrong, are they also going to put a limit on the number of objects they can use? If threads are integral to solving your problem, then it seems as though you are limiting how well you can solve the problem.&lt;br /&gt;&lt;br /&gt;This also got me thinking about other issues involving threading in non-concurrent orientated languages. Using a COL (Concurrent Orientated Language) all the time would be nice (and I hope that is what the future holds for us). But today, I don't think it is always practical. We can't use Erlang or Mozart or Concurrent ML for every problem due to various limiting factors. But on the same token, using threads in a non-COL sometimes makes the solution to a problem a bit easier to work with. At the very least, making use of multiple processors sounds like a decent argument. But writing code in, say, java, as if it was Erlang does not work out. I think the best one can hope to do is a static number of threads. Spawning and destroying threads dynamically in a non-COL can be fairly expensive in the long run and you have to avoid situations where you start up too many threads. I think having a static number of threads i a pool or with each doing a specific task is somewhat the "best of both worlds". You get your concurrency and you, hopefully, avoid situations like Jetty is running into. As far as communication between the threads is concerned, I think message passing is the best one can hope for. The main reason I think one should use message passing in these non-COL's is, it forces all of the synchornization to happen in one localized place. You can, hopefully, avoid deadlocks this way. And if there is an error in your synchornization, you can fix it in one spot and it is fixed everywhere. As opposed to having things synchornized all over the code, god knows where you may have made an error.&lt;br /&gt;&lt;br /&gt;I think this post most likely opened up a can of worms. I lightly touched on a lot of issues and most likely did not explain things in full. Perhaps this will raise some interesting questions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-6859902567308754574?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/6859902567308754574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/09/java-and-threads-jetty.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/6859902567308754574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/6859902567308754574'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/09/java-and-threads-jetty.html' title='Java And Threads (Jetty)'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-5535607090814434741</id><published>2005-09-11T19:08:00.000-04:00</published><updated>2009-10-18T18:16:23.421-04:00</updated><title type='text'>Initial impressions of yaws</title><content type='html'>If any of this post is incorrect, please feel free to post a comment and correct me.&lt;br /&gt;&lt;br /&gt;I have recently installed yaws and I am looking at it to create a small website. It will be fairly simple. My previous web experience has been using &lt;a href="http://www.divmod.org/projects/nevow"&gt;Nevow&lt;/a&gt; with Twisted. Nevow allows you to create xml files and then the template engine extracts information from the xml file which is translated to function calls on an object representing the page. I like this solution. It keeps the code seperate from presentation which many people seem to suggest is a good idea. I see it as a positive purely based on working with webdesigners. I dislike doing web frontends so allowing someone to make that and giving them the bare minimum needed to let them call functions in my code seems rather nice. From my experiences with yaws, it seems to use a style that reminds me more of PHP. The major difference being that you can use Erlang terms to be transformed to HTML. Nevow has something similar to this called stan. Even with this though, the .yaws file is still not purely Erlang code, but requires escaping html with a &lt;erl&gt; tag.  This style of making web applications seems fairly error prone and difficult to work with in a team.&lt;br /&gt;I do think Erlang would make a fairly good web development language. The applications could easily be distributed over several nodes, not requiring one to use some sort of load balancer. A web app could scale quite well. But what can be done about the interface for programming? Some sort of XML system might work but I'm not convinced of that. There must be some more intuitive means of mixing code and presentation. I wouldn't be sirprised if someone has attempted to tackle this already, maybe something exists on google about it.&lt;/erl&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-5535607090814434741?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/5535607090814434741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/09/initial-impressions-of-yaws.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5535607090814434741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5535607090814434741'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/09/initial-impressions-of-yaws.html' title='Initial impressions of yaws'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-4940676457160476935</id><published>2005-09-07T20:40:00.000-04:00</published><updated>2009-10-18T18:16:23.429-04:00</updated><title type='text'>Parallel Project</title><content type='html'>I have a study in Parallel Programming this semester.  However, the teacher is fairly lenient as far as projects are concerned.  I am looking for some interesting project relating to Erlang.  The leading idea right now is to create some sort of distributed computing framework.  The idea would be using Erlang to communicate between nodes and then have each node communicate with a local process which does the actual computing (assuming Erlang could not handle the calculations).  The major implementation would be a BLAST algorithm since that seems fairly easy to distribute and could possibly have some use at my college.  Other ideas include some sort of fault tolerence framework or application which handles nodes going down well.  That would seem fairly easy in Erlang so that probably would not provide a semester worth of interesting work.  Another possibility is a peer-to-peer chat application where each user contributes to the number of possible people to host.&lt;br /&gt;Hrmm, hopefully I'll get a better idea soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-4940676457160476935?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/4940676457160476935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/09/parallel-project.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4940676457160476935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4940676457160476935'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/09/parallel-project.html' title='Parallel Project'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-1171667982021420239</id><published>2005-09-05T20:13:00.000-04:00</published><updated>2009-10-18T18:16:23.435-04:00</updated><title type='text'>Bookmarks</title><content type='html'>My archive of bookmarks is slowly growing. It contains a Erlang section, a long with a number of other languages as well as lots of other URL's.&lt;br /&gt;&lt;a href="http://ortdotlove.net/bookmarks.html"&gt;&lt;br /&gt;http://ortdotlove.net/bookmarks.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-1171667982021420239?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/1171667982021420239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/09/bookmarks.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1171667982021420239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1171667982021420239'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/09/bookmarks.html' title='Bookmarks'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-1747845248124943228</id><published>2005-08-20T15:30:00.000-04:00</published><updated>2009-10-18T18:16:23.448-04:00</updated><title type='text'>Where concurrency shines</title><content type='html'>I think that it can almost be stated as a fact that concurrency in languages that weren't designed with concurrency in mind  tends to be poor.  The languages I have in mind here are Python, C, C++ and similar.  I have come across a few people who disagree with this statement however after questioning I have found that they have A) Not done much of anything complex with threads B) Never used a concurrently oriented language.  Needless to say, I don't take their opinion very seriously.  Now, obviously, you can take the time to write an application that uses threads and works well.  But, with enough time, you can do just about anything, and in the time it takes to make that application one can deffinatly develope an equivalent program faster in concurrent orientated (CO) language.&lt;br /&gt;Because writting decent threaded applications in other languages is so difficult there are a number of frameworks available that try to make it easier to write applications in a single thread.  One of the reasons I think these frameworks will fail in comparison to a language such as Erlang for most developers is the amount of work it takes to integrate other libraries into it.  For anyone that has used a framework such as Twisted, they have probably run into a situation where they have a third party library they want to use however the problem is, it blocks.  For an asynchornous framework this is murder.  So one has two choices.  Either to run the third party library in its own thread.  Obviously this is generally not what we want to do since the whole point of using the framework is to avoid threads.  The other solution is to rewrite the library to integrate it into the frameworks event loop.  Depending on the situation, this might be acceptable but it sure is a pain to have to do extra work to use this library.  Now, a language which supports concurrency does not have this problem so much.  The first solution, of running the library in a thread, works perfectly fine.  You probably have 300 or 400 threads going already so it is no big deal.  This makes it easy to distribute libraries for the particular language.&lt;br /&gt;For a simple example.  Imagine you make a really great http client in python.  You can't really make a general http client because you need to take into account the various networking frameworks they might be using.  If they are using twisted then it needs to integrate into the twisted event loop to be really useful.  If they are using asyncore it needs to integrate into the asyncore event loop, and so on and so forth.  Now take the same situation in erlang.  Just throw the client in a process and you are all set.  You don't have to rewrite anything.  The obvious benefit of this is increased development speed.&lt;br /&gt;&lt;br /&gt;I think it seems pretty clear that our processors and applications are moving towards more concurrent environments.  Languages that can take advantage of this environment are most likely going to be the ones that make it.  However I'm no fortune teller, so there is a good chance I could be wrong.&lt;br /&gt;&lt;br /&gt;I think I tried to put too much into this one post so it might not make sense.  Hopefully I got my ideas across.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-1747845248124943228?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/1747845248124943228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/where-concurrency-shines.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1747845248124943228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/1747845248124943228'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/where-concurrency-shines.html' title='Where concurrency shines'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-7461319891080215652</id><published>2005-08-19T14:46:00.000-04:00</published><updated>2009-10-18T18:16:23.460-04:00</updated><title type='text'>Developing on the go</title><content type='html'>One benefit to using erlang compared to more traditional languages is the development cycle.  Generally you write code, compile, debug, write, compile, debug, until you have something you want to use.  In between compile and debug you run the program.  In traditional languages you shut down the application then restart it to debug again.  In erlang we can skip the 'restart' and simply load the new code in.  This is assuming no bugs in the code didn't cause the entire application to crash horribly.&lt;br /&gt;So basically, what is going on is, if you have a logic problem or what not in your application that you wish to fix.  Outside of your running application, you edit the appropriate .erl files and recompile.  For example, your application consists of a.erl and b.erl.  In b.erl you have a function called mogwai.&lt;br /&gt;So in our example.  a.erl calls b:mogwai, and b:mogwai has some sort of error in it that does not cause the application to crash but you want to fix, regardless.  You fix b:mogwai's error and you want to load the new codebase in your running application.  Recompile b.erl then in the shell to your application you simple do:&lt;br /&gt;&lt;br /&gt;nl(b).&lt;br /&gt;&lt;br /&gt;This loads the new version of b into your application and now calls to b:mogwai will use the current version of the function.  For certain applications this certinaly provides a more elegant development cycle.  I think this style also alters the structure of ones code.  For instance, if one writes an application knowing that errors in the code can be fixed on the fly, no longer do they necesarly have to exit nicely.  Rather, the application can provide a means of restarting the portions that have crashed.  The application can continue working without the crashed process/code or stall until the required portion can be brought back.  I'm under the impression this is a feature supervision trees offer you.  A supervisor simply restarts a process if it crashes, and reports it.  By restarting, a new codebase can be loaded that fixes the error.&lt;br /&gt;&lt;br /&gt;One final note on how code replacement works.  Erlang only attempts to load a new module if the call is in the form of: module:function.  For instance, if you have a process in a loop something like:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;loop() -&gt;&lt;br /&gt;  receive&lt;br /&gt;     Something -&gt;&lt;br /&gt;         loop()&lt;br /&gt;   end.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;If you reload the module that this loop is defined in, the call the 'loop()' will not load the new codebase.  The common idiom is something a long the lines of:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;loop() -&gt;&lt;br /&gt;  receive&lt;br /&gt;    restart -&gt;&lt;br /&gt;      ?MODULE:loop();&lt;br /&gt;    Something -&gt;&lt;br /&gt;       loop()&lt;br /&gt;  end.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;This will load the new codebase.  On a final note, any function called as module:function must be exported.&lt;br /&gt;Erlang certinaly provides some interesting features.  Certinaly somethign like code replacement is possible in other languages, such as python (which provides a reload function to reload a module) I think erlang provides a more elegant solution.  For instance I don't think Python provides a means of a module to reload itself, especially in the middle of an event loop.&lt;br /&gt;However this is not a contest between code replacement in various languages.  I have modified my irc bot to allow code replacement more seemlessly, however I have not allowed a decent means of bringing an irc bot back if there is an error which causes a crash.  I'll have the new code online later if anyone is interested.&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-7461319891080215652?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/7461319891080215652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/developing-on-go.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7461319891080215652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/7461319891080215652'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/developing-on-go.html' title='Developing on the go'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-4392386078295828866</id><published>2005-08-16T23:10:00.000-04:00</published><updated>2009-10-18T18:16:23.473-04:00</updated><title type='text'>Erlang and strings</title><content type='html'>A lot of people complain about strings in erlang. I am one of them. Right now I am under the impression a string type needs to be added to erlang. Joe Armstrong thinks that instead of a string we simply need a character type. My complaint with that is there is no decent container for the character type. In erlangs we have tuples, binaries, and lists. Tuples are meant to store a fixed number of objects and do not have operations on them to perform operations such as iterate through them. The element/2 function allows you to access an index of a tuple but that isnt' very useful for iterating through. Binaries might be nice, but there are no functions to nicely deal with binaries as strings. Lists are what we currently have and I am not pleased. Using a linked list to store a string certinaly seems unreasonable in any other language. You have to store a character value and a link to the next node. This is a lot of memory for a string. The other problem with these containers is none of them allow O(1) access to indecies as far as I know. Am I wrong here? I suppose the question then is, is that a problem? I am under the impression that one generally wants O(1) access. For instance, if you have an index in the string and need to access it and surrounding indecies repeatedly.&lt;br /&gt;&lt;br /&gt;http://schemecookbook.org/view/Erlang/StringBasics has a quote supposedly from the sendmail people:&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;But Erlang's treatment of strings as lists of bytes is as elegant as it is impractical. The factor-of-eight storage expansion of text, as well as the copying that occurs during message-passing, cripples Erlang for all but the most performance-insensitive text-processing applications.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;This is in reference to their load balancing software. Is this true? I am inclined to think that it certinaly uses a lot of memory used up, but most text-processing is going to require touching every character in a string anyways won't it? What exactly is performance intensive text-processing? Does anyone have any ideas? If one is going to be iterating through the string they can use a binary to store the byte values. The problem with this is that none of the string functions work on binaries. I'm under the impression a string container type will solve some problems. Using integers as the character values seems like a fine idea to me, as people like to point out it makes dealing with unicode slightly easier.&lt;br /&gt;&lt;br /&gt;What problems would having a character type solve?  Maybe in the morning I'll be able to think of something.&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-4392386078295828866?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/4392386078295828866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/erlang-and-strings.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4392386078295828866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4392386078295828866'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/erlang-and-strings.html' title='Erlang and strings'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-4806521874495418067</id><published>2005-08-16T20:55:00.000-04:00</published><updated>2009-10-18T18:16:23.480-04:00</updated><title type='text'>Identd as done as I care</title><content type='html'>The identd is as done as I'm interested in right now.  It works atleast.  Instead of worrying about how to figure out who belongs to an actual port I just return a random ident value for any input.  However, the function it uses to make this is a variable you pass to the server so it is not very difficult to give it a different function. To run it, simply compile all the files then do&lt;br /&gt;identd:start(SomePort, {random_identd, random}).&lt;br /&gt;&lt;br /&gt;There is no clean shutdown, just kill your shell.&lt;br /&gt;&lt;br /&gt;You can download it &lt;a href="http://ortdotlove.net/%7Eorbitz/temp/p2.tar.gz"&gt;here.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-4806521874495418067?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/4806521874495418067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/identd-as-done-as-i-care.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4806521874495418067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/4806521874495418067'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/identd-as-done-as-i-care.html' title='Identd as done as I care'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-9065071830664863603</id><published>2005-08-15T23:34:00.000-04:00</published><updated>2009-10-18T18:16:23.486-04:00</updated><title type='text'>Identd</title><content type='html'>I think the basic design for my identd is going to be:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Start a process which takes a port and a function.&lt;/li&gt;   &lt;li&gt;On a new connection, start a process to handle the connection with the function given.&lt;br /&gt;  &lt;/li&gt;   &lt;li&gt;Go back to waiting.&lt;/li&gt;   &lt;li&gt;The new process will read in the port numbers, parse them out, then call the function given with the port information&lt;br /&gt;  &lt;/li&gt;   &lt;li&gt;The function does what it needs to and returns the information&lt;/li&gt;   &lt;li&gt;The process responds on the socket with the correct information.&lt;/li&gt; &lt;/ol&gt; I think this would work good with gen_server behavior, unforunatly I don't quite understand superivsion tree's that well.  I will write it the ad-hoc way first then once I figure out the correct method rewrite it that way.&lt;br /&gt;This framework shouldn't be too hard, making a correct identd function which actually gets the  user from the ports might be.  Basic one will just return a random identd.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-9065071830664863603?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/9065071830664863603/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/identd.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/9065071830664863603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/9065071830664863603'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/identd.html' title='Identd'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-5999619463358636029</id><published>2005-08-15T22:38:00.000-04:00</published><updated>2009-10-18T18:16:23.492-04:00</updated><title type='text'>IRC Bot</title><content type='html'>Here is the code for the latest revision of my IRC Bot.  It isn't made to be use friendly right now so don't expect it to work right off the bat.&lt;br /&gt;&lt;br /&gt;I think to get it started you'll need to do the following:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Compile everything, be sure to add the inc directory to your include path.&lt;/li&gt;   &lt;li&gt;Start it with a node name and set a mnesia directory.&lt;/li&gt;   &lt;li&gt;Call p1_db:start().  Then p1_db:create_tables().&lt;/li&gt;   &lt;li&gt;Then call irc_bot:add_bot (Maybe it's addbot?). It takes a tuple, see code to figure it out.&lt;/li&gt;   &lt;li&gt;p1_main:start()&lt;/li&gt;   &lt;li&gt;When you are finished: bot_server ! stop.  The beauty of erlang lets you do this from another node on another machine too, if you so desire.&lt;/li&gt; &lt;/ol&gt; The code can be found &lt;a href="http://ortdotlove.net/%7Eorbitz/temp/p1.tar.gz"&gt;here.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The only other erlang irc bot I've found is manderlbot which can be found on freshmeat.  I think it is a bit better designed than mine and has the intention of other people using it in mind where as mine is more of me just playing around.  If there is an interest in it perhaps I will do more with it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-5999619463358636029?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/5999619463358636029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/irc-bot.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5999619463358636029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/5999619463358636029'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/irc-bot.html' title='IRC Bot'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4348519741358344123.post-2488295488676572976</id><published>2005-08-15T22:09:00.000-04:00</published><updated>2009-10-18T18:16:23.498-04:00</updated><title type='text'>Initial Post</title><content type='html'>I will be posting my various erlang accomplishments here.  My intended goal is to write a smtpd in Erlang.  I will have various posts on that in the future.  So far I would not describe myself as a very good programmer but I am working on that.  I have written portions of an erlang irc bot.  It does not do very much, although it has the ability to relay chats between channels on multiple networks and supports some concept of factoids.  My next mini project is a plugable identd.  This will be fairly small and simply provide the ability to give it a function that creates a response.&lt;br /&gt;Feel free to post responses to my post, I don't mind constructive criticism.  The hope is to make my projects better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4348519741358344123-2488295488676572976?l=functional-orbitz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://functional-orbitz.blogspot.com/feeds/2488295488676572976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/initial-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/2488295488676572976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4348519741358344123/posts/default/2488295488676572976'/><link rel='alternate' type='text/html' href='http://functional-orbitz.blogspot.com/2005/08/initial-post.html' title='Initial Post'/><author><name>orbitz</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
