<?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:blogger='http://schemas.google.com/blogger/2008' 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-7061944</id><updated>2024-11-01T03:03:09.067-07:00</updated><category term="erlang"/><category term="scheme"/><category term="mslug"/><category term="schemescript"/><category term="gambit-c"/><category term="termite"/><category term="blogging"/><category term="jobs"/><category term="montreal"/><category term="voicexml"/><category term="voxeo"/><category term="lisp"/><category term="yaws"/><category term="javascript"/><category term="lalr-scm"/><category term="nuecho"/><category term="oopsla"/><category term="tropo"/><category term="asterisk"/><category term="jazzscheme"/><category term="r6rs"/><category term="scheme snow packages"/><category term="sisc"/><category term="tuple spaces"/><category term="ubuntu"/><category term="arc"/><category term="debugging"/><category term="dsl"/><category term="eclipse"/><category term="grammarserver"/><category term="hot code swapping"/><category term="interoperability"/><category term="json"/><category term="kawa"/><category term="linux"/><category term="nugram"/><category term="prophecy"/><category term="recruiting"/><category term="scripting"/><category term="speech applications"/><category term="technology"/><category term="voice applications"/><category term="web server"/><category term="xml"/><category term="IM"/><category term="IMified"/><category term="android"/><category term="applications"/><category term="architecture"/><category term="books"/><category term="business"/><category term="compiz"/><category term="conferences"/><category term="couchdb"/><category term="erlang user group"/><category term="erlyweb"/><category term="facebook"/><category term="fastagi"/><category term="fun"/><category term="functional programming"/><category term="gamerizon"/><category term="github"/><category term="google code"/><category term="html5"/><category term="ide"/><category term="instant messaging"/><category term="internship"/><category term="ios"/><category term="ivr"/><category term="java"/><category term="library"/><category term="linda"/><category term="linkedin"/><category term="logging"/><category term="marketing"/><category term="mysql"/><category term="network servers"/><category term="open-source"/><category term="openfire"/><category term="optimization"/><category term="otp"/><category term="parser generator"/><category term="parsing"/><category term="plugins"/><category term="postgresql"/><category term="python"/><category term="rest"/><category term="ruby"/><category term="secondlife"/><category term="security"/><category term="skype"/><category term="smack"/><category term="snow"/><category term="socialmedia"/><category term="spark"/><category term="syntax-case"/><category term="testing"/><category term="user group"/><category term="vacations"/><category term="voiceobjects"/><category term="voicephp"/><category term="voip"/><category term="web service"/><category term="workshop"/><category term="wubi"/><category term="xmpp"/><category term="yahoo"/><title type='text'>(The Scheme Way)</title><subtitle type='html'>A blog on Scheme, Erlang, and voice application development.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default?alt=atom'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default?alt=atom&amp;start-index=26&amp;max-results=25'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>209</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7061944.post-7517640754925405099</id><published>2012-10-01T18:20:00.002-07:00</published><updated>2012-10-01T18:20:58.200-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="library"/><category scheme="http://www.blogger.com/atom/ns#" term="logging"/><title type='text'>Lager is cool!</title><content type='html'>No, not that type of lager that is so refreshing on a hot summer day... Although I like beer a lot, I rather meant the &lt;a href=&quot;http://github.com/basho/lager&quot;&gt;Erlang logging library&lt;/a&gt; developed by Basho (the authors of the &lt;a href=&quot;http://basho.com/products/riak-overview/&quot;&gt;Riak&lt;/a&gt; NoSQL database).&lt;br /&gt;
&lt;br /&gt;
Logging is that not so sexy thing that every long running application needs. Especially the kind of application that runs in large data centers with operations people monitoring every aspects of it 24 hours a days, 7 days a week . Log files are central to their work as they have to analyze the behaviour of complex systems when a problem arises. You cannot simply stop those applications or put breakpoints in them. So you rely on log files.&lt;br /&gt;
&lt;br /&gt;
The fact that the Erlang system already provides a default logging infrastructure (error_logger) really proves that Erlang was meant for long-running applications, servers, etc. But frankly, being used to logging frameworks in other languages (like the good old log4j), I always feel error_logger way too verbose. Even a simple logging instruction like:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;error_logger:info_msg(&quot;Hello!~n&quot;, []).&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
generates a verbose trace like:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;=INFO REPORT==== 1-Oct-2012::20:45:39 ===&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Hello!&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
So when I stumbled on Lager, I liked it from the start. I am now using it in all my pet projects and will certainly consider replacing an in-house logging infrastructure we have at &lt;a href=&quot;http://www.nuecho.com/&quot;&gt;Nu Echo&lt;/a&gt;. (I know there are other very nice logging frameworks for Erlang, I just didn&#39;t take time to review them.) It even wraps the error_logger infrastructure, so your existing code will transparently use lager if properly configured.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Lager can log to the console or in files using the provided log handlers (with log rotation and the like). You can also extend it with custom handlers as well (like putting log entries in a database, for example, or actively monitoring special events).&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
With lager, the logging line above would instead be written:&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;lager:info(&quot;Hello!&quot;).&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
and would print the following at the console:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;20:57:48.802 [info] Hello!&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Much better, isn&#39;t it?&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
One interesting feature of Lager is that log entries can be tagged with attribute/value pairs. For example, you can tag log entries with an application ID with something like:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;lager:info([{appid, ?APPID}], &quot;Hello!&quot;).&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
and redirect in a file all the entries for a specific app ID.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
What&#39;s more, thanks to the ability to connect to remote nodes in a distributed Erlang-based system, debugging runtime servers becomes a pleasure. Start a shell on a remote node, and call lager:trace_file like this:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;{ok, Trace} = lager:trace_file(&quot;logfile.log&quot;, [{appid, MyApp}], debug).&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This will write to &quot;logfile.log&quot; all log entries for the debug log level or higher, and whose attribute appid is MyApp. Once you have debugged your stuff, you remove the trace by calling:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;lager:stop_trace(Trace).&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
That&#39;s it. Neat, isn&#39;t it?&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
And you, what logging facilities do you use in your applications?&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/7517640754925405099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2012/10/lager-is-cool.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/7517640754925405099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/7517640754925405099'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2012/10/lager-is-cool.html' title='Lager is cool!'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-580154684333893835</id><published>2012-09-20T13:00:00.000-07:00</published><updated>2012-09-20T13:00:03.252-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="xml"/><title type='text'>xmerl crashes my process!</title><content type='html'>To my greatest surprise&amp;nbsp;this morning, I noticed that the XML parsing library in Erlang, xmerl, crashes the process that launches the parse when the XML document is not valid. That&#39;s right. The parser does not return in that case, it simply calls &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace; font-size: x-small;&quot;&gt;erlang:exit/1&lt;/span&gt;. This was not documented and I had to dig the code to understand why one of my production servers crashed.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/580154684333893835/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2012/09/xmerl-crashes-my-process.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/580154684333893835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/580154684333893835'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2012/09/xmerl-crashes-my-process.html' title='xmerl crashes my process!'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-946195003125885945</id><published>2012-09-20T10:20:00.000-07:00</published><updated>2012-09-20T13:23:57.454-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="blogging"/><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><title type='text'>Quick notes on Erlang</title><content type='html'>In the upcoming weeks, I will try hard to get back to blogging on a more regular basis. As I&#39;m experimenting a bit with Erlang for distributed apps, I will log my thoughts and results as they come in.&lt;br /&gt;
&lt;br /&gt;
Stay tuned!</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/946195003125885945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2012/09/quick-notes-on-erlang.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/946195003125885945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/946195003125885945'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2012/09/quick-notes-on-erlang.html' title='Quick notes on Erlang'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-4476017220452365158</id><published>2012-06-19T18:24:00.001-07:00</published><updated>2012-06-20T08:08:37.424-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="functional programming"/><category scheme="http://www.blogger.com/atom/ns#" term="jobs"/><category scheme="http://www.blogger.com/atom/ns#" term="montreal"/><title type='text'>Functional programming job in Montreal</title><content type='html'>Wow! A job opening for &lt;a href=&quot;http://www.workopolis.com/EN/job/13831628?cid=721%3A19L%3A13590&amp;amp;goback=%2Egde_90878_member_126076229&quot;&gt;functional programmers in Montreal&lt;/a&gt;&amp;nbsp;at &lt;a href=&quot;http://www.genetec.com/&quot;&gt;Genetec&lt;/a&gt;. Very nice! Not clear what language is used as the job description only mentions C#, though. Maybe it&#39;s F# (that would make sense, given that they seem to use the .NET platform).&lt;br /&gt;
&lt;br /&gt;
I hope there would more such jobs on the market.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/4476017220452365158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2012/06/functional-programming-job-in-montreal.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/4476017220452365158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/4476017220452365158'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2012/06/functional-programming-job-in-montreal.html' title='Functional programming job in Montreal'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-8684598379707496593</id><published>2011-11-17T16:49:00.001-08:00</published><updated>2011-11-17T16:52:05.967-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="android"/><category scheme="http://www.blogger.com/atom/ns#" term="gambit-c"/><category scheme="http://www.blogger.com/atom/ns#" term="ios"/><category scheme="http://www.blogger.com/atom/ns#" term="mslug"/><category scheme="http://www.blogger.com/atom/ns#" term="scheme"/><title type='text'>MSLUG meeting next week</title><content type='html'>The MSLUG (Montreal Scheme/Lisp User Group) is rising from the ashes! Next week, Marc Feeley will talk about Gambit REPL, a version of Gambit-C for iOS and Android.&lt;br /&gt;
&lt;br /&gt;
More details can be found &lt;a href=&quot;http://www.meetup.com/Montreal-Scheme-Lisp-Users-Group/events/39894522/&quot;&gt;here&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/8684598379707496593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2011/11/mslug-meeting-next-week.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/8684598379707496593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/8684598379707496593'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2011/11/mslug-meeting-next-week.html' title='MSLUG meeting next week'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-3049591884419451709</id><published>2011-05-25T06:57:00.000-07:00</published><updated>2011-05-25T06:57:03.718-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="grammarserver"/><title type='text'>Session handling in NuGram Hosted Server</title><content type='html'>Some time ago, I wrote a description of how &lt;a href=&quot;http://theschemeway.blogspot.com/2009/11/1-session-per-process-some-comments-on.html&quot;&gt;session&lt;/a&gt; &lt;a href=&quot;http://theschemeway.blogspot.com/2009/11/architecture-of-nugram-hosted-server.html&quot;&gt;handling&lt;/a&gt; works in &lt;a href=&quot;http://www.grammarserver.com/&quot;&gt;NuGram Hosted Server&lt;/a&gt;, which is implemented in &lt;a href=&quot;http://erlang.org/&quot;&gt;Erlang&lt;/a&gt;. It&#39;s also briefly described on slide 15 of my &lt;a href=&quot;http://blog.nuecho.com/2011/05/20/slides-from-my-talk-at-the-erlang-montreal-meetup/&quot;&gt;talk at the Erlang Montreal&lt;/a&gt; meetup. Over on the Nu Echo blog, I wrote a &lt;a href=&quot;http://blog.nuecho.com/2011/05/25/session-timeouts-in-nugram-hosted-server/&quot;&gt;short post&lt;/a&gt; explaining how the session timeout mechanism can be implemented using a plain Erlang/OTP gen_server behaviour. It&#39;s not a very profound post, but it&#39;s one of those areas where OTP shines (a very simple solution to a very common problem, and no need to reinvent the wheel).</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/3049591884419451709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2011/05/session-handling-in-nugram-hosted.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/3049591884419451709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/3049591884419451709'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2011/05/session-handling-in-nugram-hosted.html' title='Session handling in NuGram Hosted Server'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-3299943369547041168</id><published>2011-05-20T04:19:00.000-07:00</published><updated>2011-05-20T04:19:42.842-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang user group"/><category scheme="http://www.blogger.com/atom/ns#" term="nuecho"/><category scheme="http://www.blogger.com/atom/ns#" term="nugram"/><title type='text'>Slides from my talk at the first Erlang Montreal meetup</title><content type='html'>Over on our &lt;a href=&quot;http://blog.nuecho.com/2011/05/20/slides-from-my-talk-at-the-erlang-montreal-meetup/&quot;&gt;corporate blog&lt;/a&gt;, I&#39;ve put the slides from the talk I gave at the first &lt;a href=&quot;http://groups.google.com/group/erlang-montreal?hl=en&quot;&gt;Erlang Montreal&lt;/a&gt; meetup. The talk was a summary of some lessons we&#39;ve learned at Nu Echo building &lt;a href=&quot;http://www.grammarserver.com/&quot;&gt;NuGram Hosted Server&lt;/a&gt; in Erlang.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/3299943369547041168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2011/05/slides-from-my-talk-at-first-erlang.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/3299943369547041168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/3299943369547041168'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2011/05/slides-from-my-talk-at-first-erlang.html' title='Slides from my talk at the first Erlang Montreal meetup'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-2975590947472319265</id><published>2011-05-11T19:29:00.000-07:00</published><updated>2011-05-13T13:35:03.547-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="user group"/><title type='text'>First Erlang Montreal meeting tomorrow</title><content type='html'>Tomorrow, May 12th, 2011, the &lt;a href=&quot;http://www.solea-research.com/blog/332/first-erlang-montreal-meeting&quot;&gt;first meeting of the Erlang Montreal&lt;/a&gt; user group will take place at the Notman House from 6:30PM to 8PM. I will have the pleasure to give the first talk, in which I will share some of the lessons we learned at Nu Echo on building real applications in Erlang.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/2975590947472319265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2011/05/first-erlang-montreal-meeting-tomorrow.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/2975590947472319265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/2975590947472319265'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2011/05/first-erlang-montreal-meeting-tomorrow.html' title='First Erlang Montreal meeting tomorrow'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-3648145707536123168</id><published>2011-02-11T13:30:00.000-08:00</published><updated>2011-03-21T09:43:09.691-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="couchdb"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><title type='text'>Securing a couchdb database</title><content type='html'>&lt;div&gt;Last week, for a &lt;a href=&quot;http://blog.nuecho.com/2011/02/03/testing-your-dynamic-grammars/&quot;&gt;post&lt;/a&gt; on our corporate blog, I created and populated a hosted &lt;a href=&quot;http://couchdb.apache.org/&quot;&gt;CouchDB&lt;/a&gt; database (on &lt;a href=&quot;http://couchone.com/&quot;&gt;CouchOne&lt;/a&gt;, now &lt;a href=&quot;http://www.couchbase.com/&quot;&gt;CouchBase&lt;/a&gt;). Since I put the code on &lt;a href=&quot;http://github.com/nuecho/context-examples&quot;&gt;github&lt;/a&gt; and it contains references to my publicly available database, I had to secure it a bit. Here is what I did.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;b&gt;Note: &lt;/b&gt; this is not a tutorial on CouchDB security issues, only a list of steps I did to secure my database. For a comprehensive guide on CouchDB security, there are excellent &lt;a href=&quot;http://guide.couchdb.org/&quot;&gt;online&lt;/a&gt; &lt;a href=&quot;http://blog.couchone.com/post/1027100082/whats-new-in-couchdb-1-0-part-4-securityn-stuff&quot;&gt;sources&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;&lt;div style=&quot;font-weight: bold;&quot;&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: 800;&quot;&gt;1. &lt;/span&gt;&lt;b&gt;Creating the user/password&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;The first thing to do is to create a new user with an associated password on the instance.&lt;/div&gt;&lt;div&gt;&lt;pre&gt;% curl -X PUT &#39;https://dboucher.couchone.com/_config/admins/&lt;i&gt;username&lt;/i&gt;&#39; -d &#39;&quot;&lt;i&gt;password&lt;/i&gt;&quot;&#39;&lt;/pre&gt;&lt;div&gt;&lt;b&gt;2. Configuring the user &lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;The next step is to configure the user account by setting its type and roles. In my case, I wanted to add the &lt;span class=&quot;Apple-style-span&quot;&gt;editor&lt;/span&gt; role to my account so I could restrict the creation of new documents to this role (the validator below is kept in a document on the database itself, so it is readable by everyone and I don&#39;t want other people to know which user account to hack).&lt;/div&gt;&lt;br /&gt;
&lt;div&gt;The user account configuration is done using another simple HTTP request:&lt;/div&gt;&lt;pre&gt;% curl -X PUT &#39;https://&lt;i&gt;username:password&lt;/i&gt;@dboucher.couchone.com/_users/org.couchdb.user:&lt;i&gt;username&lt;/i&gt;&#39; -d@userdata.json&lt;/pre&gt;&lt;div&gt;where the file userdata.json contains the following text:&lt;/div&gt;&lt;div&gt;&lt;pre&gt;{
  &quot;name&quot;: &quot;newuser&quot;,
  &quot;type&quot;: &quot;user&quot;,
  &quot;roles&quot;: [&quot;editor&quot;]
}&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;3. Validator&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Finally, to prevent creation of new documents (and modifications or deletion as well) from unauthorized users, I created a design document for my database that only contains a &lt;span class=&quot;Apple-style-span&quot;&gt;validate_doc_update&lt;/span&gt; function. The validation function checks that the user that tries to create/modify/delete a document has the role &lt;code&gt;editor&lt;/code&gt;. The code goes as follows:&lt;/div&gt;&lt;pre&gt;{
  &quot;_id&quot;: &quot;_design/address&quot;,
  &quot;validate_doc_update&quot;: &quot;function (newdoc, olddoc, userCtx) { if (userCtx.roles.indexOf(\&quot;editor\&quot;) == -1) throw({unauthorized: \&quot;illegal access\&quot;});}&quot;
}&lt;/pre&gt;&lt;div&gt;To create the design document, I simply entered the following at the shell prompt:&lt;br /&gt;
&lt;pre&gt;% curl -X PUT &#39;https://&lt;i&gt;username:password&lt;/i&gt;@dboucher.couchone.com/streets/_design/address&#39; -d@designdoc.json&lt;/pre&gt;That&#39;s it. I could certainly have done something fancier, but that worked and that was really easy to setup.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/3648145707536123168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2011/02/securing-couchdb-database.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/3648145707536123168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/3648145707536123168'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2011/02/securing-couchdb-database.html' title='Securing a couchdb database'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-8854059846902198564</id><published>2011-01-06T19:09:00.000-08:00</published><updated>2011-01-07T04:56:43.264-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="blogging"/><title type='text'>My resolutions for 2011</title><content type='html'>First of all, I wish all of you a very happy new year 2011!&lt;br /&gt;&lt;br /&gt;My regular readers may have noticed that I did not publish a lot of posts in the last months. I&#39;ve been quite busy at work and wrote a number of articles on &lt;a href=&quot;http://blog.nuecho.com/&quot;&gt;Nu Echo&#39;s blog&lt;/a&gt; instead. And most of all, I have not done as much Scheme or Erlang programming as I would have liked to do.&lt;br /&gt;&lt;br /&gt;But I played a bit with a number of different technologies in the past months (&lt;a href=&quot;http://ruby-lang.org/&quot;&gt;Ruby&lt;/a&gt;, &lt;a href=&quot;http://groovy.codehaus.org/&quot;&gt;Groovy&lt;/a&gt;, &lt;a href=&quot;http://couchdb.apache.org/&quot;&gt;CouchDB&lt;/a&gt;, &lt;a href=&quot;http://nodejs.org/&quot;&gt;NodeJS&lt;/a&gt;, websockets, etc.) and it be would worthwhile to write down my observations on these technologies. So my resolution for this new year (as far as this blog is concerned) is to write on a more regular basis about them. For example, I will try to explain:&lt;div&gt;&lt;ul&gt;&lt;li&gt;what I think of Ruby and Groovy for writing DSLs from a Scheme perspective (you know I&#39;m a big fan of macros and DSLs);&lt;/li&gt;&lt;li&gt;what makes Erlang a great language for writing voice applications;&lt;/li&gt;&lt;li&gt;my (very) personal take on NodeJS&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;and many other things.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Also, there seems to be a growing interest for SchemeScript in the last 6 months. The number of downloads on SourceForge has surged. For this reason, I will take some time to write tutorials and make some screencasts on how to use SchemeScript effectively.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Happy New Year! &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/8854059846902198564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2011/01/my-plan.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/8854059846902198564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/8854059846902198564'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2011/01/my-plan.html' title='My resolutions for 2011'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-5870750292776636282</id><published>2010-08-24T19:43:00.000-07:00</published><updated>2010-08-25T06:42:00.541-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><title type='text'>ECMAScript - turning a binary function into a variadic one</title><content type='html'>In my &lt;a href=&quot;http://theschemeway.blogspot.com/2010/08/small-exercise-with-html5-canvas-and.html&quot;&gt;previous post&lt;/a&gt;, I mentioned that it&#39;s easy to take a binary JavaScript function and turn it into a variadic one. Here&#39;s the helper function to do that:&lt;pre&gt;&lt;div&gt;&lt;div&gt;function variadic(fun, val0f, val1f) {&lt;/div&gt;&lt;div&gt;  return function() {&lt;/div&gt;&lt;div&gt;    var len = arguments.length;&lt;/div&gt;&lt;div&gt;    if (len == 0) {&lt;/div&gt;&lt;div&gt;       return val0f();&lt;/div&gt;&lt;div&gt;    } else if (len == 1) {&lt;/div&gt;&lt;div&gt;       if (val1f != undefined) {&lt;/div&gt;&lt;div&gt;         return val1f(arguments[0]);&lt;/div&gt;&lt;div&gt;       }&lt;/div&gt;&lt;div&gt;       else {&lt;/div&gt;&lt;div&gt;         return arguments[0];&lt;/div&gt;&lt;div&gt;       }&lt;/div&gt;&lt;div&gt;    } else {&lt;/div&gt;&lt;div&gt;      var tmp = fun(arguments[0], arguments[1]);&lt;/div&gt;&lt;div&gt;      for (index = 2; index &amp;lt; len; index++) {&lt;/div&gt;&lt;div&gt;        tmp = fun(tmp, arguments[index]);&lt;/div&gt;&lt;div&gt;      }&lt;/div&gt;&lt;div&gt;      return tmp;&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;  };&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;div&gt;The &#39;variadic&#39; function takes three parameters:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;the binary function;&lt;/li&gt;&lt;li&gt;a function that returns the value for the variadic version when called with zero arguments&lt;/li&gt;&lt;li&gt;a function that returns the value for the variadic version when called on a single. If not specified, the first argument to the variadic function is returned as is when called on a single argument.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;For example, the summation operator is defined as&lt;/div&gt;&lt;/div&gt;&lt;pre&gt;&lt;div&gt;var sum = variadic(function(x,y) {return x+y;},&lt;/div&gt;&lt;div&gt;                   function() { return 0;},&lt;/div&gt;&lt;div&gt;                   function(x) { return x;});&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;div&gt;while the equivalent of Scheme&#39;s / function is defined as&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;div&gt;var div = variadic(function(x,y) {return x/y; },&lt;/div&gt;&lt;div&gt;                   function() { throw &quot;not enough arguments to div&quot;; },&lt;/div&gt;&lt;div&gt;                   function(x) { return 1/x;});&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;It is now possible to call&lt;pre&gt;&lt;div&gt;div.apply(this, [1,2,3,4,5])&lt;/div&gt;&lt;/pre&gt;&lt;div&gt;to get 0.008333333333333333. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/5870750292776636282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2010/08/ecmascript-turning-binary-function-into.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/5870750292776636282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/5870750292776636282'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2010/08/ecmascript-turning-binary-function-into.html' title='ECMAScript - turning a binary function into a variadic one'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-335198108456352140</id><published>2010-08-24T16:54:00.000-07:00</published><updated>2010-08-25T06:47:26.868-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="html5"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="scheme"/><title type='text'>A small experiment with HTML5 canvas and Scheme to JavaScript conversion</title><content type='html'>&lt;div style=&quot;text-align: left;&quot;&gt;Lately, I&#39;ve been playing around with some of the upcoming features of HTML5. Last week, I decided to try the HTML canvas. In order to make a realistic test, I tried to port the parse tree viewer in &lt;a href=&quot;http://nugram.nuecho.com/&quot;&gt;NuGram IDE&lt;/a&gt;, one of &lt;a href=&quot;http://www.nuecho.com/&quot;&gt;Nu Echo&lt;/a&gt;&#39;s products, to JavaScript and the HTML canvas.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To debug a speech recognition grammar with NuGram IDE, an &lt;a href=&quot;http://www.eclipse.org/&quot;&gt;Eclipse&lt;/a&gt; plugin, the developer simply enters a test sentence and get a parse tree in the Interpretation view:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeMIAF4Hsq1Slg4DSEP3w_a3fFe-fJgZHb1IkaYaMp4b6ex_Aj44bgFrGV2WWm4cCk3SMBNrn4pk06lFLiks7xZoN1RCoqXheZeT0_LdglUTr7Uiq8NBKb9Os1xVbAr2KSdpzV6A/s1600/interpretation.png&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeMIAF4Hsq1Slg4DSEP3w_a3fFe-fJgZHb1IkaYaMp4b6ex_Aj44bgFrGV2WWm4cCk3SMBNrn4pk06lFLiks7xZoN1RCoqXheZeT0_LdglUTr7Uiq8NBKb9Os1xVbAr2KSdpzV6A/s320/interpretation.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5509135120792568082&quot; style=&quot;display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 320px; height: 214px; &quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;NuGram IDE is written almost entirely in Kawa Scheme. The parse tree viewer does not use any graph layout toolkit, the layout algorithm has been written from scratch in Scheme (about 200 lines of commented code).  It was a good candidate for a rewrite in JavaScript. Here is what I ended up with (in Chrome):&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 238); -webkit-text-decorations-in-effect: underline; &quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJGKqt0IUu-agl2iKAsVHPjE0D5rNEG2LuufOZIBoO2VrGx99rsVwTrxNRh_rbxUqPOGosu6b8CDGHzi4uCPjsFu56LUTY1WAQ_-EXeNQAiqTskXjnX9gHvMYY1g6VGo0jqU1UjQ/s320/canvas-chrome.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5509138115531478482&quot; style=&quot;display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 320px; height: 186px; &quot; /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 238); -webkit-text-decorations-in-effect: underline; &quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 238); -webkit-text-decorations-in-effect: underline; &quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;The conversion process&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;I translated the whole layout algorithm by hand. I did not use (or develop) any automatic translation tool. I wanted to see how different the JavaScript code would look like compared to the original Scheme code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I knew that JavaScript/ECMAScript is one of Scheme&#39;s very close cousins, but it was amazingly easy to convert the Scheme code into very similarly looking JavaScript code. For instance, take this procedure definition:&lt;/div&gt;&lt;pre&gt;&lt;div&gt;&lt;div&gt;(define (compute-nodes-size! gc tree-node level)&lt;/div&gt;&lt;div&gt;  (compute-node-size! gc (get-graph-node tree-node))&lt;/div&gt;&lt;div&gt;  (set-level! tree-node level)&lt;/div&gt;&lt;div&gt;  (for-each (lambda (child)&lt;br /&gt;       (compute-nodes-size! gc child (+ level 1)))&lt;/div&gt;&lt;div&gt;            (get-node-children tree-node)))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;div&gt;It translates to the following JavaScript definition:&lt;/div&gt;&lt;pre&gt;&lt;div&gt;&lt;div&gt;function computeNodesSize(ctx, treeNode, level) {&lt;/div&gt;&lt;div&gt;    computeNodeSize(ctx, treeNode.graphnode);&lt;/div&gt;&lt;div&gt;    treeNode.level = level;&lt;/div&gt;&lt;div&gt;    treeNode.children.forEach(function(child) { &lt;/div&gt;&lt;div&gt;          computeNodesSize(ctx, child, level + 1); &lt;/div&gt;&lt;div&gt;    });&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;div&gt;Granted, it&#39;s a very simple example. There were some pieces of code that demanded a more complex rewrite. Uses of the Scheme apply procedure is an example. I had to translate the call&lt;/div&gt;&lt;pre&gt;&lt;div&gt;(apply max nodes-y)&lt;/div&gt;&lt;/pre&gt;&lt;div&gt;to&lt;/div&gt;&lt;pre&gt;&lt;div&gt;&lt;div&gt;var maxY = 0;&lt;/div&gt;&lt;div&gt;nodesY.forEach(function(y) { if (y &gt; maxY) { maxY = y; } });&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;div&gt;In JavaScript, the max function is not variadic function. It accepts exactly two arguments. It would have been possible to write a function that takes a function of two arguments and turns it into a variadic version of it. But it wasn&#39;t worth it, since there was only a single usage of apply and max in the whole algorithm.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Update:&lt;/b&gt; &lt;i&gt;I was completely mistaken here, as pointed out by Jon-Carlos Rivera in another post. the max function &lt;/i&gt;&lt;b&gt;&lt;i&gt;is&lt;/i&gt;&lt;/b&gt;&lt;i&gt; variadic. I could instead have written:&lt;/i&gt;&lt;/div&gt;&lt;pre&gt;&lt;div&gt;&lt;i&gt;Math.max.apply(this, nodesY)&lt;/i&gt;&lt;/div&gt;&lt;/pre&gt;&lt;div&gt;&lt;i&gt;My mistake was to not use apply properly. The first argument to apply must be an object, and not the list of arguments. I should have RTFM before writing such nonsense. &lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Canvas Support&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;I tried my parse tree viewer on 3 different browsers (Chrome 5.0.375.29 beta, Firefox 3.6.8, Opera 10.61) on Ubuntu 9.04. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How portable is the resulting widget? Not as much as advertised. I know, HTML5 is not a standards yet, but most of the major browsers claim to support HTML5 canvases. There were two majors aspects that differed between browsers: rendering and user experience.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On the rendering side, Firefox is the worst. Here is what I get:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikgrtffsm2BfQI0yVMZ0mzWJhSGwHDPNKkBC1Old6RiF_BZlsWgqvMoDNNBc-EmR7tkISwUh5XDG0V4zt-c677CApw3gzNZBRJbv8bGBmjsOrKGEa2RCW5jpXITMqt8xCIqWD5zg/s1600/canvas-ff.png&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikgrtffsm2BfQI0yVMZ0mzWJhSGwHDPNKkBC1Old6RiF_BZlsWgqvMoDNNBc-EmR7tkISwUh5XDG0V4zt-c677CApw3gzNZBRJbv8bGBmjsOrKGEa2RCW5jpXITMqt8xCIqWD5zg/s320/canvas-ff.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5509149624472606034&quot; style=&quot;display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 320px; height: 138px; &quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Some lines appear on top of the nodes (boxes), even though they were drawn before.  Opera is not bad, but the texts are not always rendered properly for some font sizes. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On the user experience side, Opera seems the fastest of the three. Chrome comes close. In Firefox, however, the canvas is not redrawn while dragging the parse tree. The parse tree is redrawn only when the button is released. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In conclusion, I&#39;ve been fairly pleased by the overall experience. The conversion from Scheme to JavaScript was painless, and the result was nice looking. However, and even though it&#39;s only based on anecdotal evidence or my lack of experience with the HTML5 canvas, portability is clearly not there yet. My guess is that we&#39;ll have to devote a lot of our development time fixing portability issues (we&#39;re already spending too much time doing exactly that for plain HTML, right?).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Update:&lt;/b&gt; &lt;i&gt;I put the canvas demo online &lt;/i&gt;&lt;a href=&quot;http://schemeway.dyndns.org/html-canvas&quot;&gt;&lt;i&gt;here&lt;/i&gt;&lt;/a&gt;&lt;i&gt;. Try it and let me know if portability can be improved, if I did things the wrong way, etc.&lt;/i&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/335198108456352140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2010/08/small-exercise-with-html5-canvas-and.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/335198108456352140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/335198108456352140'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2010/08/small-exercise-with-html5-canvas-and.html' title='A small experiment with HTML5 canvas and Scheme to JavaScript conversion'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeMIAF4Hsq1Slg4DSEP3w_a3fFe-fJgZHb1IkaYaMp4b6ex_Aj44bgFrGV2WWm4cCk3SMBNrn4pk06lFLiks7xZoN1RCoqXheZeT0_LdglUTr7Uiq8NBKb9Os1xVbAr2KSdpzV6A/s72-c/interpretation.png" height="72" width="72"/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-5264434132377450914</id><published>2010-07-16T06:52:00.000-07:00</published><updated>2010-07-16T07:07:48.521-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="blogging"/><category scheme="http://www.blogger.com/atom/ns#" term="schemescript"/><title type='text'>A blog post on SchemeScript in Russian</title><content type='html'>Pavel Samolisov wrote a very good &lt;a href=&quot;http://samolisov.blogspot.com/2010/07/schemescript-scheme-eclipse.html&quot;&gt;blog post&lt;/a&gt; on how to get started with &lt;a href=&quot;http://schemeway.sf.net/&quot;&gt;SchemeScript&lt;/a&gt;. It&#39;s in Russian, but Google can translate it to English (the translation is definitely not very good, but it is better than nothing).&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pavel noted that SchemeScript does not work well on Eclipse Helios. I just pushed a fix on the github repository (and the sourceforge git repository as well) that makes the interpreters work. If you find problems with Eclipse Helios and SchemeScript, please let me know. &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/5264434132377450914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2010/07/blog-post-schemescript-is-russian.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/5264434132377450914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/5264434132377450914'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2010/07/blog-post-schemescript-is-russian.html' title='A blog post on SchemeScript in Russian'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-2145692627381254634</id><published>2010-05-25T05:43:00.000-07:00</published><updated>2010-05-25T05:53:39.367-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="montreal"/><category scheme="http://www.blogger.com/atom/ns#" term="scheme"/><category scheme="http://www.blogger.com/atom/ns#" term="workshop"/><title type='text'>2010 Workshop on Scheme and Functional Programming</title><content type='html'>This year&#39;s Workshop on Scheme and Functional Programming will be held in Montreal on August 21-22. The &lt;a href=&quot;http://www.iro.umontreal.ca/~sfp2010&quot;&gt;call for papers&lt;/a&gt; is out and papers are due in three weeks (June 14th). Even for those of you not in the research community, it is possible to submit a 6-page paper on practical experience on using Scheme or functional programming.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/2145692627381254634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2010/05/2010-workshop-on-scheme-and-functional.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/2145692627381254634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/2145692627381254634'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2010/05/2010-workshop-on-scheme-and-functional.html' title='2010 Workshop on Scheme and Functional Programming'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-6960774346819236466</id><published>2010-05-14T21:41:00.000-07:00</published><updated>2010-05-14T18:44:08.440-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="asterisk"/><category scheme="http://www.blogger.com/atom/ns#" term="skype"/><category scheme="http://www.blogger.com/atom/ns#" term="voip"/><title type='text'>My VoIP setup at home</title><content type='html'>Recently, I had to work from home a bit more. Email and IM is great for communicating with my colleagues and friends, but sometimes talking to them is much more effective. So I decided to finalize my VoIP setup.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Skype&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Of course, Skype is the obvious choice for calling friends and relatives. It works great for voice and video on both Windows and my Ubuntu 9.04 (yes, I&#39;m still on Jaunty). My webcam (a cheap Microsoft LifeCam VX-100) is not that well supported on Ubuntu, but it&#39;s not so bad. And I use a FreeTalk Everyman USB headset (I got it free at ITExpo in January, thanks to &lt;a href=&quot;http://www.disruptiveconversations.com/&quot;&gt;Dan York&lt;/a&gt;!).&lt;br /&gt;&lt;br /&gt;But Skype itself is not the ultimate answer, at least not for me. Not all my colleagues use Skype at work. So why use Skype Out and pay for local calls when I already have a land line? And I don&#39;t like holding a (traditional) phone for one hour when I&#39;m on a conference call with customers or other people at the office. I want to be able to put both of my hands on my laptop keyboard to take notes.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;SIP at home&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://www.cisco.com/en/US/prod/voicesw/ps6790/gatecont/ps10024/ps10027/SPA3102-200x160.jpg&quot;&gt;&lt;img style=&quot;float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 160px;&quot; src=&quot;http://www.cisco.com/en/US/prod/voicesw/ps6790/gatecont/ps10024/ps10027/SPA3102-200x160.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The answer to this is SIP, and three components:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;A VoIP adapter. Mine is a &lt;a href=&quot;http://www.blogger.com/post-edit.g?blogID=7061944&amp;amp;postID=6960774346819236466&amp;amp;pli=1&quot;&gt;Linksys SPA 3102 ATA&lt;/a&gt;, a VoIP adapter and gateway from Cisco. This little box converts ordinary (land line) calls into VoIP (SIP) calls, and vice-versa.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=&quot;http://www.blogger.com/www.asterisk.org&quot;&gt;Asterisk&lt;/a&gt;, a free open-source software PBX. A PBX is the kind of system that can play messages to callers, ask for input, route calls, hold conference calls, queue calls, etc. PBXs are usually costly pieces of hardware that you don&#39;t want to buy just for you personal needs.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A SIP softphone.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;So my land line is connected directly to the VoIP gateway, which is itself connected to my wired network. When I receive a call on my land line, if I do not answer after a predetermined amount of time, the call is converted to a VoIP call and transferred to Asterisk on my Linux server. Asterisk tries to transfer the call to my SIP phone. If I ignore the call or when I&#39;m not available, the call is simply sent to Asterisk&#39;s voice mail module, which will send me a notification email with the recorded message attached to it.&lt;br /&gt;&lt;br /&gt;When I want to place a call, I simply enter the number on my softphone, press ENTER, &lt;i&gt;et voilà&lt;/i&gt;!&lt;br /&gt;&lt;br /&gt;Of course, this whole setup requires a bit of configuration and dialplan programming.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Receiving SIP calls&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The only thing that I did not explain is how I can receive SIP calls from outside my home network. I sometimes need the ability to receive calls when I test outbound telephony applications on platforms like &lt;a href=&quot;http://tropo.com/&quot;&gt;Tropo&lt;/a&gt; or &lt;a href=&quot;http://www.teleku.com/&quot;&gt;Teleku&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In order to do this, I created an account on &lt;a href=&quot;http://ekiga.net/&quot;&gt;Ekiga.net&lt;/a&gt;, a free VoIP service provider. I then configured Asterisk to automatically register (login) to my Ekiga.net account and transfer all calls to my SIP phone when I&#39;m available.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;SIP phones&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I mainly use two different SIP phones, depending on which OS I boot. On Windows, I use &lt;a href=&quot;http://www.counterpath.com/x-lite.html&quot;&gt;X-Lite&lt;/a&gt; free edition. It has a lot of features, has video, but it only supports one account. On Linux, I use &lt;a href=&quot;http://www.twinklephone.com/&quot;&gt;Twinkle&lt;/a&gt;, which is also free. It does not support video, but it is more stable than the Ekiga softphone on my machine, supports two lines, and has some basic voicemail support.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/6960774346819236466/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2010/04/my-voip-setup-at-home.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/6960774346819236466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/6960774346819236466'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2010/04/my-voip-setup-at-home.html' title='My VoIP setup at home'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-1544455628517984930</id><published>2010-04-13T06:12:00.000-07:00</published><updated>2010-04-13T06:23:23.267-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><title type='text'>RabbitMQ acquired by SpringSource</title><content type='html'>&lt;a href=&quot;http://www.rabbitmq.com/about.html&quot;&gt;Rabbit Technologies&lt;/a&gt;, a spin out of &lt;a href=&quot;http://www.lshift.net/&quot;&gt;LShift Ltd.&lt;/a&gt; and &lt;a href=&quot;http://www.cohesiveft.com/&quot;&gt;Cohesive FT&lt;/a&gt;, has just been acquired by SpringSource, a division of &lt;a href=&quot;http://www.vmware.com/&quot;&gt;VMWare&lt;/a&gt;. Rabbit Technologies is the company behind RabbitMQ, a high-performance open-source enterprise messaging system based on the AMPQ protocol. &lt;br /&gt;&lt;br /&gt;For me, the most interesting thing about this acquisition is the fact that RabbitMQ is an Erlang-based product. This shows once again that Erlang is not an esoteric language anymore, that even large companies are not afraid of using it. This is another great success story for Erlang! And I wish the Rabbit Technologies team the best for the upcoming years.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/1544455628517984930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2010/04/rabbitmq-acquired-by-springsource.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/1544455628517984930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/1544455628517984930'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2010/04/rabbitmq-acquired-by-springsource.html' title='RabbitMQ acquired by SpringSource'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-2202182296949668157</id><published>2010-03-10T18:09:00.000-08:00</published><updated>2010-03-10T18:20:41.436-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="github"/><category scheme="http://www.blogger.com/atom/ns#" term="schemescript"/><title type='text'>SchemeScript on Github</title><content type='html'>In addition to moving all the development of &lt;a href=&quot;http://schemeway.sourceforge.net/schemescript&quot;&gt;SchemeScript&lt;/a&gt; to git a few months ago, I just pushed my development repository to github. The repository is here:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &lt;a href=&quot;http://github.com/schemeway/SchemeScript&quot;&gt;http://github.com/schemeway/SchemeScript&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I did this essentially because &lt;a href=&quot;http://github.com&quot;&gt;github&lt;/a&gt; really rocks. It offers a lot of excellent features for tracking parallel development. I also happen to have a number of other projects hosted there.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/2202182296949668157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2010/03/schemescript-on-github.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/2202182296949668157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/2202182296949668157'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2010/03/schemescript-on-github.html' title='SchemeScript on Github'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-8160394783501430482</id><published>2010-02-20T20:20:00.000-08:00</published><updated>2010-02-20T20:27:42.004-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="eclipse"/><category scheme="http://www.blogger.com/atom/ns#" term="schemescript"/><title type='text'>SchemeScript used in the Scheme4edu project</title><content type='html'>Here is a &lt;a href=&quot;http://www.youtube.com/watch?v=i1BJrptWPfA&amp;feature=player_embedded&quot;&gt;short screencast&lt;/a&gt; of &lt;a href=&quot;http://wiki.eclipse.org/Eclipse_IDE_for_Education&quot;&gt;Scheme4Edu&lt;/a&gt;, a version of Eclipse streamlined specifically for use by university and college students, featuring the SchemeScript plugin.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/8160394783501430482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2010/02/schemescript-used-in-scheme4edu-project.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/8160394783501430482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/8160394783501430482'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2010/02/schemescript-used-in-scheme4edu-project.html' title='SchemeScript used in the Scheme4edu project'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-6477880658985413539</id><published>2009-12-25T15:56:00.001-08:00</published><updated>2009-12-25T15:57:50.734-08:00</updated><title type='text'>Best wishes</title><content type='html'>I&#39;d like to wish you all a Merry Christmas and a Happy New Year!</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/6477880658985413539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2009/12/best-wishes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/6477880658985413539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/6477880658985413539'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2009/12/best-wishes.html' title='Best wishes'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-4423545105187958435</id><published>2009-11-18T16:47:00.000-08:00</published><updated>2009-11-18T18:08:57.593-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="architecture"/><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="nugram"/><title type='text'>1-session-per-process - some further comments on the NuGram architecture</title><content type='html'>In response to my &lt;a href=&quot;http://theschemeway.blogspot.com/2009/11/architecture-of-nugram-hosted-server.html&quot;&gt;previous post&lt;/a&gt; on the &lt;a href=&quot;http://www.grammarserver.com&quot;&gt;NuGram&lt;/a&gt; architecture, Ben Simon wrote a &lt;a href=&quot;http://benjisimon.blogspot.com/2009/11/nugram-architecture-worth-pondering.html&quot;&gt;post&lt;/a&gt; in which he focused most exclusively on the idea of using a single process for handling all the requests for a given session. I wanted to add a few comments about this approach.&lt;br /&gt;&lt;br /&gt;First, the idea is not new at all. In fact, I&#39;d say that this is a pretty standard approach in Erlang and the language facilitates its implementation. For instance, the open-source &lt;a href=&quot;http://www.process-one.net/en/ejabberd/&quot;&gt;ejabberd&lt;/a&gt; XMPP server uses this approach. &lt;br /&gt;&lt;br /&gt;Also, it is true that it is completely transparent to the system whether the session&#39;s process runs in the same Erlang VM or on a remote machine. The syntax is exactly the same: &lt;code&gt;Process ! Message&lt;/code&gt;. That&#39;s it. In the case of NuGram Server, the database (which replicates the session table on all nodes) holds references to Erlang processes. Once it has obtained the reference to the session&#39;s process, it simply sends a message encapsulating the request to that process (using the &lt;code&gt;!&lt;/code&gt; notation).  &lt;br /&gt;&lt;br /&gt;Of course, there are some complications if the node on which the process runs suddenly crashes or becomes unavailable. Session replication is less trivial to implement. In our case, the system maintains, together with the session table, a table holding all the relevant data to recreate a session if needed. This was fairly easy to do in our server given our requirements and the nature of the API. For more complex APIs, this could be much more challenging.&lt;br /&gt;&lt;br /&gt;Although I&#39;m a big fan of the &lt;i&gt;1-session-per-process&lt;/i&gt; approach (it is a very effective one for the implementation of comet-like servers), it has some limitations that the continuation-based approach do not suffer. The back-button/bookmarking problem immediately comes to mind. Serializable continuations can be put in a database for later retrieval. But the question remains whether this is a practical approach. For instance, for how long do you retain continuations in the database? What happens when the code changes? &lt;br /&gt;&lt;br /&gt;Another benefit of using the continuation-based approach is the fact that the code handling the request is written in a more direct style. By this, I mean that the application flow is coded in a more sequential way: do this, then do that, etc. You don&#39;t have to code using state machines or callbacks. &lt;br /&gt;&lt;br /&gt;But this can be achieved in Erlang as well using two processes per session. (Processes are so cheap in Erlang!) This approach can be used to implement dialog-based applications and providing the illusion of a synchronous API, à la &lt;a href=&quot;http://www.tropo.com&quot;&gt;Tropo&lt;/a&gt;). I&#39;ll talk more about this in another post very soon.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/4423545105187958435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2009/11/1-session-per-process-some-comments-on.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/4423545105187958435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/4423545105187958435'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2009/11/1-session-per-process-some-comments-on.html' title='1-session-per-process - some further comments on the NuGram architecture'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-8167865147024234653</id><published>2009-11-11T16:31:00.000-08:00</published><updated>2009-11-12T07:12:35.715-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="grammarserver"/><category scheme="http://www.blogger.com/atom/ns#" term="kawa"/><category scheme="http://www.blogger.com/atom/ns#" term="nuecho"/><category scheme="http://www.blogger.com/atom/ns#" term="scheme"/><category scheme="http://www.blogger.com/atom/ns#" term="yaws"/><title type='text'>The architecture of NuGram Hosted Server</title><content type='html'>In the comments section of one of my &lt;a href=&quot;http://theschemeway.blogspot.com/2009/10/dynamically-setting-yaws-log-level.html&quot;&gt;previous post&lt;/a&gt;, I mentioned that NuGram Hosted Server (&lt;a href=&quot;http://www.grammarserver.com/&quot;&gt;www.grammarserver.com&lt;/a&gt;) is implemented in a mix of Erlang/Yaws, Java and Kawa Scheme. Alexandre Abreu then asked a few questions about some architectural aspects:&lt;quote style=&quot;font-style: italic;&quot;&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;how do erlang and kawa scheme interop? http / json ? ffi ?&lt;/li&gt;  &lt;li&gt;to follow up on that, why erlang / yaws and not scala / lift to have a better integration with the jvm ? &lt;/li&gt;  &lt;li&gt;the server part if hosted on 1 machine ? how do you handle the load (both the connection load and the computation load since grammar and the services provided by NuGram seem pretty heavy computation-wise)? Maybe you don&#39;t need to do much given the amount of people that uses your service and I know you don&#39;t offer any guarantees with people using this service in a commercial setup but I am just wondering&lt;/li&gt;&lt;/ul&gt;&lt;/quote&gt;These questions prompted for a long answer. So in the following sections I describe some aspects of the NuGram Hosted Server architecture at 10,000 feet high.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1. Context&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;NuGram Hosted Server is a grammar hosting server for use by communication applications (VoiceXML applications, IM bots, etc.). It provides various grammar-related services through a RESTful API, like dynamic grammar generation and semantic interpretation of text-based sentences (and it will soon provide robust parsing capabilities). It also provides a community-based HTML application to management and share grammars, consult application logs, etc., using standard AJAX techniques.&lt;br /&gt;&lt;br /&gt;When we started the project, we had some ambitious requirements in mind: &lt;ul&gt;  &lt;li&gt;High-performance HTTP server.&lt;/li&gt;  &lt;li&gt;Scalability. (We needed the possibility of dynamically adding nodes to our cluster without interruption of service.)&lt;/li&gt;  &lt;li&gt;Fault-tolerance.&lt;/li&gt;  &lt;li&gt;Hot code swapping.&lt;/li&gt;  &lt;li&gt;Distributed database.&lt;/li&gt;&lt;/ul&gt;Since I already had some experience with Erlang, I pushed the idea to the management team, after getting the buy-in from my development team. We decided  to use this project to evaluate Erlang in the context of a real project.&lt;br /&gt;&lt;br /&gt;To answer Alexandre&#39;s question more specifically, we did not consider Scala/lift mainly for the same reason we did not choose Java itself. Essentially, we could not use the usual session tracking mechanisms found in J2EE environments (jsessionid, cookies) for our RESTful API. Implementing a clustered solution would have required too much work. And using Erlang was a far better (and more elegant) approach.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2. The architecture&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;At a very high level, grammarserver.com is composed of two subsystems:&lt;ul&gt;  &lt;li&gt;&lt;i&gt;An Erlang/Yaws front-end.&lt;/i&gt;&lt;br /&gt;This is the part handling the HTTP requests. &lt;/li&gt;&lt;li&gt;&lt;i&gt;A number of Java/Kawa workers.&lt;/i&gt;&lt;/li&gt; These workers implement the grammar-related services. There can be many workers running on a single machine. These workers implement the more computation-intensive stuff (parsing of text sentences, grammar template instantation, etc.)&lt;/ul&gt; Let me describe each subsystem separately.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Erlang/Yaws front-end&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This subsystem handles all the HTTP requests. It currently consists of a single Erlang node, but it has been designed to support the clustering of many Erlang nodes. In this case, we would need a load-balancer in front of the Erlang cluster.&lt;br /&gt;&lt;br /&gt;The Erlang system follows most OTP principles. It is a real Erlang application and provides a supervisor and a number of gen_servers. The application also starts an embedded yaws serving requests for several virtual hosts (the HTML websites at www.grammarserver.com, nugram.nuecho.com, with and without SSL support, and the RESTful API at www.grammarserver.com:8082).&lt;br /&gt;&lt;br /&gt;Most requests to the RESTful API are done in the context of a session. Each session is associated with an Erlang process and the application keeps a mapping between the session ID and the process for the session in the &lt;a href=&quot;http://www.erlang.org/doc/apps/mnesia/index.html&quot;&gt;Mnesia&lt;/a&gt; database (it is rather cool to store things like process IDs in a database!). So when the application receives a request, it extracts the session ID from the request URI, finds the corresponding process in the database, and simply forwards the request to that process.&lt;br /&gt;&lt;br /&gt;When multiple Erlang nodes are running in a cluster, forwarding a request can involve sending the request to a different Erlang node. This is done completely transparently  in Erlang.&lt;br /&gt;&lt;br /&gt;Another interesting consequence of using processes to represent sessions is the fact that implementing session timeout becomes trivial. Each session process makes an explicit &lt;code&gt;receive&lt;/code&gt; ... &lt;code&gt;after&lt;/code&gt;. When the timeout is reached, the session is automatically terminated and removed from the database.&lt;br /&gt;&lt;br /&gt;The application also uses Mnesia for other purposes:&lt;ul&gt;  &lt;li&gt;It holds the user accounts, of course. &lt;/li&gt;  &lt;li&gt;All the instantiated grammars are held in the database.&lt;/li&gt;  &lt;li&gt;It holds the node IDs of the available Java/Kawa workers. Keeping that information in a persistent (disk-based) table of Mnesia makes it possible to shut down the Erlang application and reconnect it automatically to the Java nodes when we restart it. More on this below.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;Java/Kawa workers&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The Java/Kawa workers implement the basic NuGram services. They are written in a mix of Java and Kawa Scheme because most of the code is also shared with NuGram IDE, an Eclipse plugin.&lt;br /&gt;&lt;br /&gt;The workers use &lt;a href=&quot;http://www.erlang.org/doc/apps/jinterface/index.html&quot;&gt;jinterface&lt;/a&gt; to interface with Erlang. This has the advantage of exposing the workers as standard nodes to the Erlang application. In other words, the Erlang application does not even know that the workers are implemented in Java. This is completely transparent.&lt;br /&gt;&lt;br /&gt;Many workers can be started, independently of the number of Erlang nodes. The first thing they do is try to find an Erlang node and register with it. If they cannot find an Erlang node, they wait for a specified amount of time, then try again. After a number of retries, they simply stop with an error.&lt;br /&gt;&lt;br /&gt;Each grammar is assigned to a single worker. To distribute the load as evenly as possible across the workers, the Erlang system uses a round-robin strategy to assign workers to new grammars (if a session uses a grammar already loaded in a worker, requests are sent directly to that worker, of course).&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;3. Conclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Overall, our experience with Erlang has been excessively positive. (I have to confess that my team members already had some prior exposure to functional programming and Prolog, which helped a lot). Of course, we had to learn some things the hard way, we found some bugs in Yaws. But in the end the platform delivered on its promises. We have an architecture that can scale, we can hot swap code, dynamically change the database schema, add nodes dynamically, etc.&lt;br /&gt;&lt;br /&gt;Since NuGram Hosted Server is a free service, we do not guarantee any quality of service, but the platform is really robust and fast and that is very important for communication applications (especially telephony applications where latency translates to &lt;span style=&quot;font-style: italic;&quot;&gt;dead-air&lt;/span&gt; during a conversation).</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/8167865147024234653/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2009/11/architecture-of-nugram-hosted-server.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/8167865147024234653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/8167865147024234653'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2009/11/architecture-of-nugram-hosted-server.html' title='The architecture of NuGram Hosted Server'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-2346551101530272067</id><published>2009-11-06T19:44:00.000-08:00</published><updated>2009-11-06T19:49:13.491-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="lisp"/><category scheme="http://www.blogger.com/atom/ns#" term="mslug"/><category scheme="http://www.blogger.com/atom/ns#" term="network servers"/><title type='text'>Vladimir Sedach on high-performance network servers in Lisp</title><content type='html'>At our upcoming meeting of the &lt;a href=&quot;http://schemeway.dyndns.org/mslug&quot;&gt;Montreal Scheme/Lisp User Group&lt;/a&gt; (MSLUG) on Tuesday, November 17th, &lt;a href=&quot;http://carcaddar.blogspot.com/&quot;&gt;Vladimir Sedach&lt;/a&gt; will talk about developing high-performance network servers in Lisp. Here is the abstract:&lt;br /&gt;&lt;blockquote&gt;This talk will cover techniques for developing high-performance network servers in Lisp, with examples and lessons from the TPD2, Antiweb, and the speaker&#39;s own soon-to-be-released&lt;br /&gt;Common Lisp HTTP servers. Topics covered will include techniques for efficient input handling and output generation, vectored IO, thread pool design, and asynchronous IO management using continuations and state machines.&lt;/blockquote&gt;&lt;br /&gt;See you there!</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/2346551101530272067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2009/11/vladimir-sedach-on-high-performance.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/2346551101530272067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/2346551101530272067'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2009/11/vladimir-sedach-on-high-performance.html' title='Vladimir Sedach on high-performance network servers in Lisp'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-2835252166172525712</id><published>2009-10-25T18:28:00.000-07:00</published><updated>2009-10-27T07:16:10.712-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="debugging"/><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="web server"/><category scheme="http://www.blogger.com/atom/ns#" term="yaws"/><title type='text'>Dynamically setting the Yaws log level</title><content type='html'>Debugging a web-based application is more often than not done by first analyzing log files. Even when you can attach a REPL to a running application. They are an integral part of the developer&#39;s tool set.&lt;br /&gt;&lt;br /&gt;But production applications usually do not enable tracing by default, because this could degrade performance and waste essential resources (memory, CPU time, disk, etc.). Would you dump the content of every HTTP request received by a web server on disk? Of course, when problems occur, trace level is simply raised, with the hope that the logs will contain some useful debugging info.&lt;br /&gt;&lt;br /&gt;With the &lt;a href=&quot;http://yaws.hyber.org/&quot;&gt;Yaws&lt;/a&gt; Erlang-based web server, the log level can be set programmatically like this:&lt;br /&gt;&lt;pre&gt;-module(my_yaws_utils).&lt;br /&gt;-export([set_yaws_trace_level/1]).&lt;br /&gt;&lt;br /&gt;set_yaws_trace_level(Level) -&gt;&lt;br /&gt;  {ok, GC, Groups} = yaws_api:getconf(),&lt;br /&gt;  yaws_config:hard_setconf(GC#gconf{trace=Level}, Groups).&lt;/pre&gt;&lt;br /&gt;with &lt;code&gt;Level&lt;/code&gt; being either &lt;code&gt;none&lt;/code&gt;, &lt;code&gt;{true, http}&lt;/code&gt;, or &lt;code&gt;{true, traffic}&lt;/code&gt;. The first value disables tracing, the second enables tracing of the HTTP requests in file &lt;code&gt;trace.http&lt;/code&gt;, while the last enables tracing of the whole traffic (requests and responses).&lt;br /&gt;&lt;br /&gt;It is certainly possible to attach to the Yaws server from another Erlang node to call this function. But if your application is administered by someone not really used to Erlang, it may be more appropriate to provide a command-line script for that purpose.&lt;br /&gt;&lt;br /&gt;Basically, the script would connect to the Yaws node (named &lt;code&gt;yaws_daemon@lelouch&lt;/code&gt;) and invoke the function with the appropriate log level:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#!/bin/sh&lt;br /&gt;node=yaws_daemon@lelouch&lt;br /&gt;# we should check the number of arguments to the script here...&lt;br /&gt;case $1 in&lt;br /&gt;  none) level=none;;&lt;br /&gt;  http) level=&quot;{true, http}&quot;;;&lt;br /&gt;  traffic) level=&quot;{true, traffic}&quot;&lt;br /&gt;esac&lt;br /&gt;&lt;br /&gt;erl -sname trace_script -noinput \&lt;br /&gt;    -setcookie &lt;span style=&quot;font-style: italic;&quot;&gt;ErlangCookie&lt;/span&gt; \&lt;br /&gt;    -eval &quot;rpc:call($node, my_yaws_utils, set_yaws_trace_level, [$level]).&quot; \&lt;br /&gt;    -s init stop&lt;/pre&gt;&lt;br /&gt;The call to &lt;code&gt;rpc:call&lt;/code&gt; does the actual RPC call to set the log level on the Yaws server.&lt;br /&gt;&lt;br /&gt;The cool thing is the fact that this technique can be applied to a whole bunch of other utility tools, like scripts to stop the server, to reload the application configuration, etc. And this applies to all Erlang applications as well, this is in no way specific to Yaws. &lt;br /&gt;&lt;br /&gt;And there are probably other ways to do the same thing. Let me know if you have a better solution.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/2835252166172525712/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2009/10/dynamically-setting-yaws-log-level.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/2835252166172525712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/2835252166172525712'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2009/10/dynamically-setting-yaws-log-level.html' title='Dynamically setting the Yaws log level'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-9086556124156397561</id><published>2009-10-19T16:32:00.000-07:00</published><updated>2009-10-20T06:07:53.181-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="schemescript"/><title type='text'>SchemeScript 1.3.0.alpha9</title><content type='html'>On the &lt;a href=&quot;http://schemeway.sourceforge.net/&quot;&gt;SchemeWay&lt;/a&gt; blog, I posted an &lt;a href=&quot;http://sourceforge.net/apps/wordpress/schemeway/2009/10/19/schemescript-1-3-0-alpha9/&quot;&gt;entry&lt;/a&gt; describing the latest features I have added to SchemeScript. In particular, I have modified the indentation strategy for comments. SchemeScript now behaves more like the Emacs Scheme mode. I have also added some support for the Clojure maps syntax. I wrote some Clojure code lately and desperately needed that feature.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/9086556124156397561/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2009/10/schemescript-130alpha9.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/9086556124156397561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/9086556124156397561'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2009/10/schemescript-130alpha9.html' title='SchemeScript 1.3.0.alpha9'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061944.post-918813913847143044</id><published>2009-09-11T17:34:00.000-07:00</published><updated>2009-09-11T19:02:00.826-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="json"/><category scheme="http://www.blogger.com/atom/ns#" term="python"/><category scheme="http://www.blogger.com/atom/ns#" term="ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="web service"/><title type='text'>Accessing HTTP/JSON services with JVM-based languages</title><content type='html'>Lately, I have been working on a number of client APIs for a REST-like service &lt;a href=&quot;http://www.nuecho.com/&quot;&gt;Nu Echo&lt;/a&gt; offers for &lt;a href=&quot;http://www.grammarserver.com/&quot;&gt;managing dynamic speech recognition grammars&lt;/a&gt;. (The APIs will soon be available on github.) This experience made me realize how difficult it is to provide an API in different programming languages using only the core language (i.e. without having to depend on third-party libraries).&lt;br /&gt;&lt;br /&gt;To put you in context, my goal was to provide the same API for accessing an web-based, REST-like service in Java, JavaScript (ECMAScript), Python/Jython, Ruby/JRuby, and eventually Groovy and Clojure.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;First problem: Base64&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Since the web service uses Basic Authorization on most HTTP requests, the username:password string must be encoded using the Base64 algorithm before being added to the HTTP headers. Believe it or not, there is no standard public class in Java to encode/decode Base64 strings. Fortunately, most scripting languages provide one. Except JavaScript (rhino in my case). So I had to include an implementation of the Base64 algorithm in both the Java API and the JavaScript API.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Second problem: JSON&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For simplicity, and the best integration possible with JavaScript, the web service can encode its responses in &lt;a href=&quot;http://json.org&quot;&gt;JSON&lt;/a&gt; format instead of XML. (The service was first intended to be used from VoiceXML applications, whose scripting language is ECMAScript.) I thought it would be relatively easy to encode/decode data structures in JSON in all the languages I wanted to support. WRONG!&lt;br /&gt;&lt;br /&gt;Of course, Java does not have native JSON support. But I knew that from the start. So no surprise there. And JavaScript, through the &lt;span style=&quot;font-family: courier new;&quot;&gt;eval&lt;/span&gt; function, supports JSON natively. Again, no surprise.&lt;br /&gt;&lt;br /&gt;The first real surprise came from Python. There is no default JSON library that comes with Python 2.5/2.6 (I haven&#39;t tried Python 3). I had to install the &lt;a href=&quot;http://code.google.com/p/simplejson&quot;&gt;simplejson&lt;/a&gt; library (which is very nice btw). Unfortunately, it cannot run on Jython 2.2, only on Jython 2.5. Since one of my goals was to run the APIs on &lt;a href=&quot;http://tropo.com&quot;&gt;Tropo&lt;/a&gt;, which only supports Jython 2.2, I had a difficult choice to make. I even tried to simply convert Python dictionaries to strings. But although the Python syntax for constant values is very close to JSON, it uses single quotes instead of double quotes for encoding dictionary keys. (The Python constant {&#39;a&#39;: 1, &#39;b&#39;: 2} is written as {&quot;a&quot;:1, &quot;b&quot;: 2} in JSON.)&lt;br /&gt;&lt;br /&gt;In the end, I decided to stick with simplejson for greater portability. (The Tropo guys will probably upgrade to Jython 2.2 one of these days.)&lt;br /&gt;&lt;br /&gt;On the Ruby side, there is no standard JSON library. You have to install the &#39;json&#39; Ruby gem. But it is really easy to install in both Ruby and JRuby. My main complaint is that it is not installed by default with [J]Ruby. And services like Tropo do not necessarily provide all the Ruby gems. (They do provide the &#39;json&#39; gem, to my greatest surprise.)&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Conclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When designing NuGram Hosted Server&#39;s web service, I thought it would really straightforward to provide APIs in most (scripting) languages running on the JVM. HTTP + Basic Authentication + JSON seemed so &lt;span style=&quot;font-style: italic;&quot;&gt;en vogue&lt;/span&gt;... But clearly, it was harder than expected and the code had to depend on classes/modules that don&#39;t come with the core language or the standard library.&lt;br /&gt;&lt;br /&gt;I strongly believe that JSON should be more widely supported (natively) by all the major scripting languages, much as XML is. Their own syntax for constant data structures (maps, strings, arrays) is so close to JSON that they should encourage people to use JSON instead of XML. Or at least not discourage its use.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Disclaimer:&lt;/span&gt; I am fairly new to most JVM-based scripting languages: Python, Ruby, Groovy. I may have missed something trivial. If so, please let me know.</content><link rel='replies' type='application/atom+xml' href='http://theschemeway.blogspot.com/feeds/918813913847143044/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://theschemeway.blogspot.com/2009/09/accessing-httpjson-services-with-jvm.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/918813913847143044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061944/posts/default/918813913847143044'/><link rel='alternate' type='text/html' href='http://theschemeway.blogspot.com/2009/09/accessing-httpjson-services-with-jvm.html' title='Accessing HTTP/JSON services with JVM-based languages'/><author><name>Dominique Boucher</name><uri>http://www.blogger.com/profile/18059572110310581530</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVnesfkBhQE7SFal1Ls8NulvApwhlzszFjA2-TgioGPMElivuaeQCJwD33voC4k7oacchahgHsELJK8gnjA0xZb0P0EQsvIQZJ6z222LFkas_IqMqRiupvXsEihfM198/s1600/a0834622166089423c3ebb7e5bbada88%3Fs%3D80'/></author><thr:total>4</thr:total></entry></feed>