<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5236266522633912942</id><updated>2012-01-26T07:23:33.246-08:00</updated><category term='end-user programming'/><category term='Python'/><category term='wikileaks'/><category term='SWDC2010'/><category term='Mobile'/><category term='GTUG'/><category term='refactoring'/><category term='MobileLua'/><category term='Sikuli'/><category term='Amber'/><category term='Clojure'/><category term='Dynamic languages'/><category term='Happiness'/><category term='MoSync'/><category term='Kawa'/><category term='CoffeScript'/><category term='test'/><category term='Scala'/><category term='DroidScript'/><category term='ComiKit'/><category term='msc'/><category term='MagicWords'/><category term='JRuby'/><category term='Rhino'/><category term='Ruby'/><category term='Smalltalk'/><category term='DSL'/><category term='Eclipse'/><category term='Squeak'/><category term='wikilieaks'/><category term='Lua'/><category term='JavaScript'/><category term='Android'/><category term='Dart'/><category term='Scheme'/><category term='Rosenmetoden'/><category term='Erlang'/><title type='text'>Divine Programmer</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>46</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-3402468896796484782</id><published>2011-10-17T06:16:00.000-07:00</published><updated>2011-10-17T06:16:55.295-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Smalltalk'/><category scheme='http://www.blogger.com/atom/ns#' term='MobileLua'/><category scheme='http://www.blogger.com/atom/ns#' term='Lua'/><category scheme='http://www.blogger.com/atom/ns#' term='CoffeScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Dart'/><category scheme='http://www.blogger.com/atom/ns#' term='Amber'/><title type='text'>Dart, CoffeScript and Amber</title><content type='html'>I have really been looking forward to learning about Dart, Google's new "JavaScript replacement" language. Recently the Dart web site went on-line, and on this page you can find some sample code: &lt;a href="http://www.dartlang.org/articles/idiomatic-dart/"&gt;http://www.dartlang.org/articles/idiomatic-dart/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It goes without saying that Dart takes the fun out of JavaScript and potentially ruins your programming experience by introducing templates and other nonproductive constructs. Last thing the programming world needs is yet another language bogged down by type declarations. To me, Dart feels more like a replacement for Java than for JavaScript. I would, however, prefer Dart over Java any day ;-) Dart looks like dynamic language bliss by comparison.&lt;br /&gt;&lt;br /&gt;Anyway, if you wish to read a balanced analysis of Dart, here is a blog post I found interesting: &lt;a href="http://alanknightsblog.blogspot.com/2011/10/dart.html"&gt;http://alanknightsblog.blogspot.com/2011/10/dart.html&lt;/a&gt; I wonder if you can dynamically compile Dart to JavaScript? So that you can do live coding in a web browser. Need to read up on this.&lt;br /&gt;&lt;br /&gt;If you you wish to look beyond JavaScript, there are several alternatives to Dart.  One of them is the wonderfully simplified language &lt;a href="http://jashkenas.github.com/coffee-script/"&gt;CoffeeScript&lt;/a&gt;. This is what Google language designers should have aimed for. It is quite a paradox, and also quite typical, that an individual, Jeremy Ashkenas, goes to design a language vastly more beautiful than the one produced by Google, one of the world's leading web technology companies.&lt;br /&gt;&lt;br /&gt;Another JavaScript alternative is &lt;a href="http://amber-lang.net/"&gt;Amber Smalltalk&lt;/a&gt; by &lt;a href="https://github.com/NicolasPetton"&gt;Nicolas Petton&lt;/a&gt;. Formerly known as Jtalk, Amber is a Smalltalk implementation that compiles to JavaScript. In the tradition of for example &lt;a href="http://squeak.org/"&gt;Squeak&lt;/a&gt;, Amber is written in itself, a very powerful and elegant way to implement a language.&lt;br /&gt;&lt;br /&gt;I am looking forward to try out Amber for programming mobile devices. By making a client run a WebView with Amber, connect over a socket to a remote editor, you can interactively live code the program running on device, in Smalltalk :-) This would be very similar to the LuaLive Editor in the &lt;a href="https://github.com/divineprog/mobilelua"&gt;MobileLua&lt;/a&gt; project I am working on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-3402468896796484782?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/3402468896796484782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2011/10/dart-coffescript-and-amber.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3402468896796484782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3402468896796484782'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2011/10/dart-coffescript-and-amber.html' title='Dart, CoffeScript and Amber'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-6374175278682493746</id><published>2011-01-24T09:13:00.000-08:00</published><updated>2011-01-24T09:13:58.489-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MoSync'/><category scheme='http://www.blogger.com/atom/ns#' term='GTUG'/><category scheme='http://www.blogger.com/atom/ns#' term='MobileLua'/><category scheme='http://www.blogger.com/atom/ns#' term='Lua'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Upcoming talk on MoSync at GTUG Stockholm</title><content type='html'>I have been working at MoSync for eight months now, and I really love it. Today I had a very creative lunch with Peter Svensson, organizer of &lt;a href="ttp://swdc-central.com/dyncon2011/"&gt;Dyncon 2011&lt;/a&gt; a very cool conference on Dynamic Languages in Stockholm, March 12-13. Peter is also the organizer of&lt;a href="http://sites.google.com/site/stockholmgtug/"&gt; GTUG Stockholm&lt;/a&gt; (the Google Technology User Group meetings). We started talking about &lt;a href="http://www.mosync.com/"&gt;MoSync&lt;/a&gt;, which is a cross platform mobile development toolkit, and came up with the idea of doing a presentation of MoSync at the next GTUG meeting, coming up in Stockholm on February 10.&lt;br /&gt;&lt;br /&gt;So how does MoSync relate to Google technologies? With MoSync you build mobile applications in a platform independent way, for Android, iOS, JavaME, Symbian, and other platforms. If you specifically want to target Android, is there any point in using MoSync? Yes, for various reasons, this can be the case.&lt;br /&gt;&lt;br /&gt;First, Android is itself becoming a multi-target ("fragmented") platform, and using MoSync can help with such things as handling differences between different Android versions. MoSync is tested on a variety of devices, which means that it is tested on different brands of the Android OS. Platforms have subtle differences, and these are handled by MoSync. This can take away some of the problems an Android developer may encounter.&lt;br /&gt;&lt;br /&gt;Second, MoSync is based on C/C++. This means that porting applications and games written in C/C++ to Android is feasable. You do not have to install the Android NDK (Native Development Kit) or even the Android SDK. The MoSync Eclipse IDE supports Android out of the box. For example, &lt;a href="http://www.youtube.com/watch?v=UUjwSzFuk7w"&gt;Another World (Out of this World)&lt;/a&gt; has been ported to MoSync, as has the libraries &lt;a href="http://www.youtube.com/watch?v=CW7B0UcDsf8"&gt;Box2D&lt;/a&gt; and &lt;a href="http://www.libsdl.org/"&gt;SDL&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Third, if you think C/C++ is too low level, or if you think Java is cumbersome, other languages can run on top of MoSync. So far, there are MoSync ports of &lt;a href="http://code.google.com/p/mobilelua/"&gt;Lua&lt;/a&gt; and &lt;a href="http://code.google.com/p/python-on-a-chip/"&gt;Python&lt;/a&gt;, and they run with satisfactory performance (MoSync recompiles to machine code on the fly). In the upcoming NativeUI support for MoSync, one component is a WebView, which implements a WebKit browser running JavaScript. From JavaScript you can call MoSync code, and the other way around.&lt;br /&gt;&lt;br /&gt;Finally, if you are an Android developer who plans to target also iPhone/iPad, you can do so with one code base.&lt;br /&gt;&lt;br /&gt;Personally, I see a bright future for using dynamic languages for mobile development. Lua has quickly became one of my favourite languages, and I am very happy to see also Python coming to MoSync. I hope that this can contribute to new groups of people developing applications for their mobile devices, such as teenagers and hobbyist programmers. Today's application market is much too focused on users as consumers, rather than users as innovators. Developing and publishing a simple app should be as easy as publishing a blog post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-6374175278682493746?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/6374175278682493746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2011/01/upcoming-talk-on-mosync-at-gtug.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/6374175278682493746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/6374175278682493746'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2011/01/upcoming-talk-on-mosync-at-gtug.html' title='Upcoming talk on MoSync at GTUG Stockholm'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-8021289630645680014</id><published>2010-12-08T12:34:00.001-08:00</published><updated>2010-12-08T12:34:40.341-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wikileaks'/><title type='text'>No Censorship</title><content type='html'>&lt;img src="https://www.eff.org/files/filenode/button_master.jpg"&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-8021289630645680014?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/8021289630645680014/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/12/no-censorship.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8021289630645680014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8021289630645680014'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/12/no-censorship.html' title='No Censorship'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-9198184792360839842</id><published>2010-12-06T13:42:00.000-08:00</published><updated>2010-12-06T13:45:34.326-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wikilieaks'/><title type='text'>Wikileaks</title><content type='html'>I strongly feel that now is the time when it happens. Governments call for actions outside of law to stop the free word from spreading. But the Internet community is strong, people who have lived and grown up with a free Internet will resist and fight back, I am certain of that.&lt;br /&gt;&lt;br /&gt;For many people this must be the first time to experience what it is like to live under censorship and dictatorship. It is for me, at least. The past days, I have seen the naked faces of representatives for world governments attacking and threatening Free Speech. It is not a pretty sight. &lt;br /&gt;&lt;br /&gt;Visit &lt;a href="http://wlcentral.org/"&gt;http://wlcentral.org/&lt;/a&gt;. Google for Niels Harrit. Take action by making choices. Get synchronised. You can vote. In Sweden the Pirate Party got less that a percent of the votes in the recent election. Now look at what we have! Freedom is more important than money, and money is on its way to lose its value. Freedom will soon prove be what is truly valuable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-9198184792360839842?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/9198184792360839842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/12/wikileaks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/9198184792360839842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/9198184792360839842'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/12/wikileaks.html' title='Wikileaks'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-6213188714102752087</id><published>2010-12-05T11:18:00.000-08:00</published><updated>2010-12-05T11:18:45.192-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wikileaks'/><title type='text'>Arrest Senator Joe Lieberman</title><content type='html'>As a citizen of the free world, I call for the immediate prosecution of Senator Joe Lieberman, who illegally censors web content by means of threat.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://wlcentral.org/node/459"&gt;http://wlcentral.org/node/459&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-6213188714102752087?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/6213188714102752087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/12/arrest-senator-joe-lieberman.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/6213188714102752087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/6213188714102752087'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/12/arrest-senator-joe-lieberman.html' title='Arrest Senator Joe Lieberman'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-4979574847815063907</id><published>2010-10-04T09:00:00.000-07:00</published><updated>2010-10-07T02:19:45.868-07:00</updated><title type='text'>Mobile Lua</title><content type='html'>&lt;a href="http://code.google.com/p/mobilelua/"&gt;MobileLua&lt;/a&gt; is a port of &lt;a href="http://www.lua.org/"&gt;Lua&lt;/a&gt; to &lt;a href="http://www.mosync.com/"&gt;MoSync&lt;/a&gt;, a cross-platform mobile development tool. One goal with MobileLua is to make it really easy to write mobile applications for hobbyist programmers.&lt;br /&gt;&lt;br /&gt;MobileLua features a browser application that downloads and runs Lua apps over the Internet. Lua apps are published as text files, and to make it easy to publish applications on any web page, like on this blog, MobileLua&amp;nbsp;recognises a begin and end tag. This is an example of a simple painting app published using these tags:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;MOBILELUA_BEGIN&lt;br /&gt;-- Paint example&lt;br /&gt;function OnInit()&lt;br /&gt;  SetColor(255, 0, 0)&lt;br /&gt;  FillRect(0, 0, ScreenWidth(), ScreenHeight())&lt;br /&gt;  UpdateScreen()&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;function OnTouchDown(x, y)&lt;br /&gt;  SetColor(0, 0, 0)&lt;br /&gt;  FillRect(x - 5, y - 5, 10, 10)&lt;br /&gt;  UpdateScreen()&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;function OnTouchDrag(x, y)&lt;br /&gt;  OnTouchDown(x, y)&lt;br /&gt;end&lt;br /&gt;MOBILELUA_END&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If you download and build MobileLua, you can enter the address of this page into the browser application, and the above app is launched.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-4979574847815063907?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/4979574847815063907/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/10/mobile-lua.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/4979574847815063907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/4979574847815063907'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/10/mobile-lua.html' title='Mobile Lua'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-2885011181655285883</id><published>2010-09-28T13:41:00.000-07:00</published><updated>2010-10-06T23:47:34.575-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='MoSync'/><category scheme='http://www.blogger.com/atom/ns#' term='DroidScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='Lua'/><title type='text'>Dynamic Languages on Android - Talk at AndroidOnly 2010</title><content type='html'>The following are notes from my talk at &lt;a href="http://swdc-central.com/androidonly/index.html"&gt;Android Only&lt;/a&gt;, Stockholm September 29-30, 2010.&lt;br /&gt;&lt;div class="centered"&gt;&lt;h1&gt;Dynamic Languages on Android&lt;/h1&gt;Mikael Kindborg&lt;br /&gt;MoSync AB&lt;br /&gt;mikael.kindborg@mosync.com&lt;br /&gt;http://divineprogrammer.se&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Early bound vs. Late bound&lt;/h2&gt;&lt;pre&gt;When you&lt;br /&gt;                                learn this...&lt;br /&gt;----------------------------------------!------&amp;gt;&lt;br /&gt;            ^&lt;br /&gt;Can you go back&lt;br /&gt;and change this?&lt;br /&gt;&lt;br /&gt;The answer is "Yes", if you late bind...&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Outline of talk&lt;/h2&gt;Dynamic languages on Android&lt;br /&gt;JavaScript in Rhino&lt;br /&gt;DroidScript&lt;br /&gt;JavaScript in WebKit&lt;br /&gt;MobileLua and MoSync&lt;br /&gt;Hobbyist programming - making app development easy &amp;amp; fun&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Why use dynamic Languages?&lt;/h2&gt;Incremental development - no build process&lt;br /&gt;Less code, less syntactic noise&lt;br /&gt;Dynamic typing and polymorphism - refactoring friendly&lt;br /&gt;Higher level programming constructs&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Dynamic languages on Android&lt;/h2&gt;Scripting Layer for Android (SL4A) - Python, Lua, JavaScript, Ruby, Perl, BeanShell, ...&lt;br /&gt;Interpreter embedded in a native Java app - JavaScript (Rhino), JRuby, BeanShell, Kawa, Clojure, ...&lt;br /&gt;JavaScript running in WebKit&lt;br /&gt;Stand-alone authoring tool/engine - Flash, Corona, AppInventor, Squeak, MobileLua, ...&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Mozilla Rhino&lt;/h2&gt;JavaScript system written in Java&lt;br /&gt;Has both interpreter/runtime engine and bytecode compiler&lt;br /&gt;Mature project&lt;br /&gt;Moderate footprint (DroidScript is around 360KB)&lt;br /&gt;Good performance&lt;/div&gt;&lt;div&gt;&lt;h2&gt;DroidScript&lt;/h2&gt;JavaScript on Android&lt;br /&gt;Micke's project for learning Android&lt;br /&gt;Experimental open-source project (MIT)&lt;br /&gt;Based on Mozilla Rhino JavaScript engine&lt;br /&gt;Full access to the Android API (minus subclassing)&lt;br /&gt;Remote browser-based editor built with CodeMirror&lt;br /&gt;Goal: Interactive programming, developing Android applications without a heavyweight IDE&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Code example - display a Toast&lt;/h2&gt;&lt;pre&gt;var Toast = Packages.android.widget.Toast;&lt;br /&gt;Toast.makeText(&lt;br /&gt;    Activity,&lt;br /&gt;    "Hello World!", &lt;br /&gt;    Toast.LENGTH_SHORT).show();&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Ways DroidScript can be used&lt;/h2&gt;Write code in the on-device editor (works crappy).&lt;br /&gt;Load/Run JavaScript files from the SD card or over the Internet.&lt;br /&gt;Load/Run JavaScript code embedded on a web page within DROIDSCRIPT_BEGIN and DROIDSCRIPT_END tags - this means that programs can be published on a blog page, for example.&lt;br /&gt;Do remote programming via the built-in web server that accepts PUT requests with JavaScript code.&lt;br /&gt;Build a native app that embeds JavaScript files as assets.&lt;/div&gt;&lt;div&gt;&lt;h2&gt;JavaScript advantages&lt;/h2&gt;Late binding&lt;br /&gt;Reduced syntactic noise&lt;br /&gt;High-level language constructs&lt;br /&gt;Closures&lt;br /&gt;Compact event callback functions&lt;br /&gt;Flexible object model (prototypes)&lt;br /&gt;More of a language for everyone compared to Java&lt;br /&gt;JavaScript is the new 'machine language'; old and new languages compile to JavaScript, e.g. CoffeeScript&lt;/div&gt;&lt;div&gt;&lt;h2&gt;JavaScript drawbacks&lt;/h2&gt;Poor tool support (editor, debugger)&lt;br /&gt;Almost no static code checking - lots of runtime errors&lt;br /&gt;No dynamic byte code generation&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Scripting Java from Rhino - what works and what doesn't&lt;/h2&gt;Can use Java packages&lt;br /&gt;Can instantiate Java classes&lt;br /&gt;Can call methods and access instance variables&lt;br /&gt;Data types are automatically converted between Java and JavaScript&lt;br /&gt;Can instantiate interfaces that have one method (similar to an anonymous inner class in Java, but shorther syntax)&lt;br /&gt;Must code a bit to implement multi-method interfaces&lt;br /&gt;Cannot generate Dalvik byte code on the fly&lt;br /&gt;Cannot subclass&lt;br /&gt;Must run in interpreted mode&lt;br /&gt;Android resource XML is early bound; some classes need resource ids, e.g. ArrayAdapter, means you cannot dynamically specify views as list items.&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Code example - making a clickable button&lt;/h2&gt;&lt;pre&gt;// Short names for packages.&lt;br /&gt;var widget = Packages.android.widget;&lt;br /&gt;var graphics = Packages.android.graphics;&lt;br /&gt;&lt;br /&gt;// onCreate is called when the script has been loaded.&lt;br /&gt;function onCreate(bundle)&lt;br /&gt;{&lt;br /&gt;    var font = graphics.Typeface.create(&lt;br /&gt;        graphics.Typeface.SANS_SERIF, &lt;br /&gt;        graphics.Typeface.BOLD);&lt;br /&gt;&lt;br /&gt;    // Activity is a global variable that refers&lt;br /&gt;    // to the Android activity.&lt;br /&gt;    var button = new widget.Button(Activity);&lt;br /&gt;    button.setText("Hello World!");&lt;br /&gt;    button.setTypeface(font);&lt;br /&gt;    button.setTextSize(26);&lt;br /&gt;    button.setBackgroundColor(graphics.Color.rgb(0, 0, 64));&lt;br /&gt;    button.setTextColor(graphics.Color.rgb(255, 255, 255));&lt;br /&gt;    &lt;br /&gt;    // One method interface implemented as a function.&lt;br /&gt;    button.setOnClickListener(function() { &lt;br /&gt;        button.setText("You Clicked Me!"); });&lt;br /&gt;        &lt;br /&gt;    Activity.setContentView(button);&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Refering to packages and classes&lt;/h2&gt;&lt;pre&gt;// Packages is a global variable that contains&lt;br /&gt;// all packages and classes."),&lt;br /&gt;&lt;br /&gt;// Write out full package path.&lt;br /&gt;var button = new Packages.android.widget.Button(Activity);"),&lt;br /&gt;&lt;br /&gt;// Use variable to refer to a package.&lt;br /&gt;var widget = Packages.android.widget;&lt;br /&gt;var button = new widget.Button(Activity);&lt;br /&gt;&lt;br /&gt;// Use variable to refer to a class.&lt;br /&gt;var Button = Packages.android.widget.Button;&lt;br /&gt;var button = new Button(Activity);&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Interfaces, closures, and polymorphism&lt;/h2&gt;&lt;pre&gt;// You implement a single method interface as a function.&lt;br /&gt;// Example interface: View.OnClickListener.onClick(View v)&lt;br /&gt;&lt;br /&gt;// Variable button is contained in the function closure.&lt;br /&gt;// Method parameters need not to be spelled out.&lt;br /&gt;button.setOnClickListener(function() { &lt;br /&gt;    button.setText("You Clicked Me!"); });&lt;br /&gt;&lt;br /&gt;// Using the supplied parameter, note the use of&lt;br /&gt;// dynamic typing and polymorphism.&lt;br /&gt;button.setOnClickListener(function(view) { &lt;br /&gt;    view.setText("You Clicked Me!"); });&lt;br /&gt;&lt;br /&gt;// First example in Java, variable button must be final.&lt;br /&gt;button.setOnClickListener(new View.OnClickListener() {&lt;br /&gt;    public void onClick(View view) {&lt;br /&gt;        button.setText("You Clicked Me!"); } });&lt;br /&gt;&lt;br /&gt;// Second example in Java, you must type cast.&lt;br /&gt;button.setOnClickListener(new View.OnClickListener() {&lt;br /&gt;    public void onClick(View view) {&lt;br /&gt;        ((Button)view).setText("You Clicked Me!"); } });&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Code example - a counting button&lt;/h2&gt;&lt;pre&gt;var widget = Packages.android.widget;&lt;br /&gt;var graphics = Packages.android.graphics;&lt;br /&gt;&lt;br /&gt;function onCreate(bundle)&lt;br /&gt;{&lt;br /&gt;    var font = graphics.Typeface.create(&lt;br /&gt;        graphics.Typeface.SANS_SERIF, &lt;br /&gt;        graphics.Typeface.BOLD);&lt;br /&gt;    var button = new widget.Button(Activity);&lt;br /&gt;    button.setText("Hello World!");&lt;br /&gt;    button.setTypeface(font);&lt;br /&gt;    button.setTextSize(26);&lt;br /&gt;    button.setBackgroundColor(graphics.Color.rgb(0, 0, 64));&lt;br /&gt;    button.setTextColor(graphics.Color.rgb(255, 255, 255));&lt;br /&gt;&lt;br /&gt;    var counter = 0;&lt;br /&gt;    button.setOnClickListener(function() {&lt;br /&gt;        counter++;&lt;br /&gt;        button.setText("Click count: " + counter); });&lt;br /&gt;    &lt;br /&gt;    Activity.setContentView(button);&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;How to implement multi-method interfaces&lt;/h2&gt;&lt;pre&gt;// Program that displays images from the camera.&lt;br /&gt;&lt;br /&gt;var Camera = Packages.android.hardware.Camera;&lt;br /&gt;var SurfaceHolder = Packages.android.view.SurfaceHolder;&lt;br /&gt;var SurfaceView = Packages.android.view.SurfaceView;&lt;br /&gt;var Window = Packages.android.view.Window;&lt;br /&gt;&lt;br /&gt;function onCreate(bundle)&lt;br /&gt;{&lt;br /&gt;    Activity.requestWindowFeature(Window.FEATURE_NO_TITLE);&lt;br /&gt;    var preview = createPreviewSurface();&lt;br /&gt;    Activity.setContentView(preview.getSurfaceView());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function createPreviewSurface()&lt;br /&gt;{&lt;br /&gt;    var camera = null;&lt;br /&gt;    var surface = new SurfaceView(Activity);&lt;br /&gt;&lt;br /&gt;    // JavaScript object that implements the interface&lt;br /&gt;    // android.view.SurfaceHolder.Callback&lt;br /&gt;    var object = {&lt;br /&gt;        getSurfaceView: function() {&lt;br /&gt;            return surface; },&lt;br /&gt;        surfaceCreated: function(holder) {&lt;br /&gt;            camera = Camera.open();&lt;br /&gt;            try {&lt;br /&gt;                camera.setPreviewDisplay(holder); }&lt;br /&gt;            catch (exception) {&lt;br /&gt;                camera.release();&lt;br /&gt;                camera = null; } },&lt;br /&gt;        surfaceDestroyed: function(holder) {&lt;br /&gt;            camera.stopPreview();&lt;br /&gt;            camera.release();&lt;br /&gt;            camera = null; },&lt;br /&gt;        surfaceChanged: function(holder, format, w, h) {&lt;br /&gt;            var parameters = camera.getParameters();&lt;br /&gt;            parameters.setPreviewSize(w, h);&lt;br /&gt;            // Causes camera to fail on Nexus One&lt;br /&gt;            //camera.setParameters(parameters);&lt;br /&gt;            camera.startPreview(); }&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    // Create the instance of the interface.&lt;br /&gt;    var callback = createInstance(&lt;br /&gt;        // Must use full package name for some reason...&lt;br /&gt;        Packages.android.view.SurfaceHolder.Callback, &lt;br /&gt;        object);&lt;br /&gt;    &lt;br /&gt;    // Set the callback for the surface.&lt;br /&gt;    surface.getHolder().addCallback(callback);&lt;br /&gt;    surface.getHolder().setType(&lt;br /&gt;        SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);&lt;br /&gt;&lt;br /&gt;    return object;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Create an instance of a Java interface.&lt;br /&gt;//   javaInterface - the interface type&lt;br /&gt;//   object - JS object that will receive messages&lt;br /&gt;//     sent to the instance&lt;br /&gt;function createInstance(javaInterface, object)&lt;br /&gt;{&lt;br /&gt;    // Local function to convert a Java array to&lt;br /&gt;    // a JavaScript array&lt;br /&gt;    function javaArrayToJsArray(javaArray) {&lt;br /&gt;        var jsArray = [];&lt;br /&gt;        for (var i = 0; i &amp;lt; javaArray.length; ++i) {&lt;br /&gt;            jsArray[i] = javaArray[i]; }&lt;br /&gt;        return jsArray; }&lt;br /&gt;&lt;br /&gt;    // Short name for lang package.&lt;br /&gt;    var lang = Packages.java.lang;&lt;br /&gt;&lt;br /&gt;    // Interface we implement.&lt;br /&gt;    var interfaces = &lt;br /&gt;        lang.reflect.Array.newInstance(lang.Class, 1);&lt;br /&gt;    interfaces[0] = javaInterface;&lt;br /&gt;&lt;br /&gt;    // Create proxy object.&lt;br /&gt;    var obj = lang.reflect.Proxy.newProxyInstance(&lt;br /&gt;        lang.ClassLoader.getSystemClassLoader(),&lt;br /&gt;        interfaces,&lt;br /&gt;        // This function is called on method invocation.&lt;br /&gt;        // Note that args is a Java array.&lt;br /&gt;        function(proxy, method, args) {&lt;br /&gt;            // Apply JavaScript function to arguments.&lt;br /&gt;            return object[method.getName()].apply(&lt;br /&gt;                null,&lt;br /&gt;                javaArrayToJsArray(args)); });&lt;br /&gt;    return obj;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;DroidScript architecture&lt;/h2&gt;DroidScriptActivity.java - basic Android activity that embeds the Rhino engine&lt;br /&gt;DroidScriptApp.java - extends DroidScriptActivity, provides the starting point of the application&lt;br /&gt;DroidScriptApp.js - The actual code for the DroidScript application, all of the user interface and application logic is here&lt;br /&gt;DroidScriptServer.java - tiny web server that can be used from JavaScript&lt;br /&gt;DroidScriptServer.js - The user interface and logic for the server activity&lt;br /&gt;Limitation: require is currently not implemented, but you can load JavaScript code into the global scope&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Event handling functions (called from DroidScriptActivity.java)&lt;/h2&gt;onCreate&lt;br /&gt;onStart&lt;br /&gt;onRestart&lt;br /&gt;onResume&lt;br /&gt;onPause&lt;br /&gt;onStop&lt;br /&gt;onDestroy&lt;br /&gt;onCreateContextMenu&lt;br /&gt;onContextItemSelected&lt;br /&gt;onCreateContextMenu&lt;br /&gt;onCreateOptionsMenu&lt;br /&gt;onPrepareOptionsMenu&lt;br /&gt;onOptionsItemSelected&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Evaluating JavaScript (methods in DroidScriptActivity.java)&lt;/h2&gt;eval(String code)&lt;br /&gt;evalFileOrUrl(String fileNameOrUrl)&lt;br /&gt;evalAssetFile(String fileName)&lt;br /&gt;&lt;pre&gt;// These can be called from JavScript, for example:&lt;br /&gt;Activity.evalFileOrUrl("http://www.mydomain.se/MyCode.js");&lt;/pre&gt;Or use eval in JavaScript&lt;/div&gt;&lt;div&gt;&lt;h2&gt;How to build a native JavaScript app&lt;/h2&gt;DroidScriptActivity.java - use as is&lt;br /&gt;MyApp.java - extend DroidScriptActivity, and load your JavaScript code from asset files, or download over the Internet and optionally cache files on the device&lt;br /&gt;MyApp.js - the JavaScript code of the application, place in the assets folder in the Eclipse project&lt;br /&gt;&lt;pre&gt;// MyApp.java - example of a stand alone DroidScript app.&lt;br /&gt;package mydomain.myapp;&lt;br /&gt;&lt;br /&gt;import android.content.Intent;&lt;br /&gt;import android.os.Bundle;&lt;br /&gt;&lt;br /&gt;public class MyApp extends comikit.droidscript.DroidScriptActivity&lt;br /&gt;{&lt;br /&gt;    @Override&lt;br /&gt;    public void onCreate(Bundle bubble)&lt;br /&gt;    {&lt;br /&gt;        Intent intent = getIntent();&lt;br /&gt;        intent.putExtra("ScriptAsset", "MyApp.js");&lt;br /&gt;        super.onCreate(bubble);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;As a starting point, check out DroidZine (project by Jonas Beckman and Mikael Kindborg): &lt;a href="http://github.com/kamidev/droidzine/" target="_blank"&gt;http://github.com/kamidev/droidzine/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;JavaScript in WebKit&lt;/h2&gt;This example shows how to access Java from JavaScript in WebKit, via DroidScript.&lt;br /&gt;&lt;pre&gt;function onCreate(bundle)&lt;br /&gt;{&lt;br /&gt;    var WebView = Packages.android.webkit.WebView;&lt;br /&gt;&lt;br /&gt;    var webview = new WebView(Activity);&lt;br /&gt;    webview.getSettings().setJavaScriptEnabled(true);&lt;br /&gt;    webview.addJavascriptInterface(Activity, "activity");&lt;br /&gt;    Activity.setContentView(webview);   &lt;br /&gt;    &lt;br /&gt;    var content =&lt;br /&gt;    """&amp;lt;html&amp;gt;&lt;br /&gt;        &amp;lt;body&amp;gt;&lt;br /&gt;            &amp;lt;script&amp;gt;&lt;br /&gt;            function showToast(message) {&lt;br /&gt;                activity.eval(&lt;br /&gt;                    "var Toast = Packages.android.widget.Toast;" +&lt;br /&gt;                    "Toast.makeText(Activity, '" + message + "', " +&lt;br /&gt;                    "Toast.LENGTH_SHORT).show();"); }&lt;br /&gt;            &amp;lt;/script&amp;gt;&lt;br /&gt;            &amp;lt;h1&amp;gt;Take the pill&amp;lt;/h1&amp;gt;&lt;br /&gt;            &amp;lt;input &lt;br /&gt;                type="button" &lt;br /&gt;                value="Take pill" &lt;br /&gt;                onclick="showToast('You have taken the red pill!')"&amp;gt;&lt;br /&gt;        &amp;lt;/body&amp;gt;&lt;br /&gt;    &amp;lt;/html&amp;gt;""";&lt;br /&gt;    &lt;br /&gt;    webview.loadData(content, "text/html", "utf-8");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;MobileLua - An easy way to create Android apps (developed with MoSync)&lt;/h2&gt;Minimal painting app in Lua:&lt;br /&gt;&lt;pre&gt;function OnInit()&lt;br /&gt;  SetColor(255, 255, 255)&lt;br /&gt;  FillRect(0, 0, ScreenWidth(), ScreenHeight())&lt;br /&gt;  UpdateScreen()&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;function OnTouchDown(x, y)&lt;br /&gt;  SetColor(0, 0, 0)&lt;br /&gt;  FillRect(x - 5, y - 5, 10, 10)&lt;br /&gt;  UpdateScreen()&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;function OnTouchDrag(x, y)&lt;br /&gt;  OnTouchDown(x, y)&lt;br /&gt;end&lt;/pre&gt;&lt;a href="http://code.google.com/p/mobilelua/" target="_blank"&gt;http://code.google.com/p/mobilelua/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Links&lt;/h2&gt;&lt;a href="http://www.mosync.com/" target="_blank"&gt;http://www.mosync.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://brickartist.com/" target="_blank"&gt;http://brickartist.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.mozilla.org/rhino/" target="_blank"&gt;http://www.mozilla.org/rhino/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://codemirror.net/" target="_blank"&gt;http://codemirror.net&lt;/a&gt;&lt;br /&gt;&lt;a href="http://droidscript.se/" target="_blank"&gt;http://droidscript.se&lt;/a&gt;&lt;br /&gt;&lt;a href="http://droidscript.blogspot.com/" target="_blank"&gt;http://droidscript.blogspot.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://droidzine.org/" target="_blank"&gt;http://droidzine.org/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://github.com/kamidev/droidzine/" target="_blank"&gt;http://github.com/kamidev/droidzine/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/mobilelua/" target="_blank"&gt;http://code.google.com/p/mobilelua/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://divineprogrammer.se/" target="_blank"&gt;http://divineprogrammer.se&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-2885011181655285883?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/2885011181655285883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/09/dynamic-languages-on-android-talk-at.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/2885011181655285883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/2885011181655285883'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/09/dynamic-languages-on-android-talk-at.html' title='Dynamic Languages on Android - Talk at AndroidOnly 2010'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-8087018504698453967</id><published>2010-06-02T13:58:00.000-07:00</published><updated>2010-06-22T02:34:17.950-07:00</updated><title type='text'>Notes from Talk at SWDC2010</title><content type='html'>These are notes from my talk at &lt;a href="http://swdc-central.com/"&gt;SWDC2010&lt;/a&gt;, April 3, 2010.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-large;"&gt;The New Mobile Web&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Mikael Kindborg&lt;br /&gt;MoSync AB&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;My Favourite languages are Lisp, Smalltalk, and C&lt;br /&gt;&lt;br /&gt;I also like JavaScript, and CoffeeScript looks very promising!&lt;br /&gt;&lt;br /&gt;JavaScript:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;function square(x) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return x * x;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;CoffeeScript:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;square: (x) -&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x * x&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Early Bound vs. Late Bound&lt;/span&gt;&lt;br /&gt;The theme of this talk is Early Bound vs. Late Bound Thinking &amp;amp; Technologies.&lt;br /&gt;&lt;br /&gt;Ready made toys like model cars are early bound, that is, the design is set ("in stone") early on in the design/production process and cannot easily be altered when manufactured, neither by the designer nor by the end user.&lt;br /&gt;&lt;br /&gt;Going Late Bound means that the design/product can be altered at "run time".&lt;br /&gt;&lt;br /&gt;For example, a model car kit is a bit less early bound than a ready made car model, but once assembled an painted, it is not as straightforward to alter and experiment with.&lt;br /&gt;&lt;br /&gt;By contrast. LEGO is a truely late bound type of toy. Children can assemble, alter and disassemble LEGO designs in endless ways.&lt;br /&gt;&lt;br /&gt;Nathan Sawaya is an example of an artist that has taken LEGO-designs to new heights of creativity, see &lt;a href="http://brickartist.com/"&gt;http://brickartist.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Going late bound enables both Dynamic Development and Dynamic Deployment.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Dynamic Development&lt;/span&gt;&lt;br /&gt;Characteristics of dynamic development:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Incremental coding&lt;/li&gt;&lt;li&gt;No Build&lt;/li&gt;&lt;li&gt;Edit/Run cycle blurred&lt;/li&gt;&lt;li&gt;Edit the running program&lt;/li&gt;&lt;li&gt;Edit code during debugging&lt;/li&gt;&lt;li&gt;Dynamic languages enable incremental evaluation&lt;/li&gt;&lt;/ul&gt;Examples of Dynamic/Late Bound Tools&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Spreadsheets&lt;/li&gt;&lt;li&gt;Smalltalk&lt;/li&gt;&lt;li&gt;Seaside&lt;/li&gt;&lt;li&gt;Live JavaScript&lt;/li&gt;&lt;li&gt;Greasemonkey and Extensions&lt;/li&gt;&lt;li&gt;The work at http://vpri.org&lt;/li&gt;&lt;li&gt;DroidScript&lt;/li&gt;&lt;li&gt;Magic Words (interactive toy)&lt;/li&gt;&lt;/ul&gt;Smalltalk/Seaside:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Squeak: &lt;a href="http://squeak.org/"&gt;http://squeak.org/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Pharo: &lt;a href="http://pharo-project.org/"&gt;http://pharo-project.org/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Clamato: &lt;a href="http://clamato.net/"&gt;http://clamato.net/&lt;/a&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;Seaside - Web application framework: &lt;a href="http://seaside.st/"&gt;http://seaside.st/&lt;/a&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;VisualWorks/WebVelocity: &lt;a href="http://cincomsmalltalk.com/"&gt;http://cincomsmalltalk.com&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Live JavaScript:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://metatoys.org/propella/js/workspace.cgi/Tennis"&gt;http://metatoys.org/propella/js/workspace.cgi/Tennis&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://metatoys.org/propella/js/workspace.cgi/Home/"&gt;http://metatoys.org/propella/js/workspace.cgi/Home/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://droidscript.se/jsedit.html"&gt;http://droidscript.se/jsedit.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Influence of Self and Strongtalk:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;To: self-interest@self.smli.com&lt;br /&gt;Subject: Sun buys Java compiler technology based upon Self!!!&lt;br /&gt;From: keith@uniteq.com (Keith Hankin)&lt;br /&gt;Date: Tue, 18 Feb 1997 17:38:17 -0800&lt;br /&gt;&lt;br /&gt;Sun has just announced that they are buying Animorphic &lt;br /&gt;Systems, which for the last 2+ years has been developing &lt;br /&gt;JIT compiler technology for Java and Smalltalk. &lt;br /&gt;And, guess what?&amp;nbsp; It's based upon the Self project!!!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.merlintec.com/old-self-interest/msg01011.html"&gt;http://www.merlintec.com/old-self-interest/msg01011.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Strongtalk and Google V8:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;From: Dave Griswold &lt;david.griswold....@gmail.com&gt;&lt;br /&gt;Date: Tue, 2 Sep 2008 12:14:32 -0700 (PDT)&lt;br /&gt;Local: Tues, Sep 2 2008 9:14 pm&lt;br /&gt;Subject: Chrome and V8&lt;br /&gt;&lt;br /&gt;Hi everyone,&lt;br /&gt;&lt;br /&gt;It's been a while, but now that Google has announced &lt;br /&gt;Chrome and V8, I can finally make a little clearer a &lt;br /&gt;major reason why I haven't been pushing Strongtalk &lt;br /&gt;development for quite a while: Chrome's new JavaScript &lt;br /&gt;engine V8.&lt;br /&gt;&lt;br /&gt;The V8 development team has multiple members of the &lt;br /&gt;original Animorphic team; it is headed by Lars Bak, &lt;br /&gt;who was the technical lead for both Strongtalk and the &lt;br /&gt;HotSpot Java VM (as well as a huge contributor to the &lt;br /&gt;original Self VM).&amp;nbsp;&amp;nbsp; I think that you will find that V8 &lt;br /&gt;has a lot of the creamy goodness of the Strongtalk and &lt;br /&gt;Self VMs, with many big architectural improvements&lt;/david.griswold....@gmail.com&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://groups.google.com/group/strongtalk-general/browse_thread/thread/40eb8f405fbd3041/0abb010f0eac18e9"&gt;http://groups.google.com/group/strongtalk-general/browse_thread/thread/40eb8f405fbd3041/0abb010f0eac18e9&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Strongtalk type system:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Type System: It contains the first fully developed &lt;br /&gt;strong, static type system for Smalltalk (hence the &lt;br /&gt;name Strongtalk). The type system is both optional &lt;br /&gt;and incremental, and operates completely independently &lt;br /&gt;of the compiler technology (which means that normal &lt;br /&gt;untyped Smalltalk code runs just as fast as typed code).&lt;/i&gt;&lt;br /&gt;&lt;a href="http://www.strongtalk.org/"&gt;http://www.strongtalk.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dynamic Deployment:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Update application at any point - even while it is running&lt;/li&gt;&lt;li&gt;User modifiable applications&lt;/li&gt;&lt;li&gt;Networked/linked/browsable apps (web of applications)&lt;/li&gt;&lt;li&gt;Security! (*x*)&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;Mobile Apps compared to Web Apps&lt;/span&gt;&lt;br /&gt;Mobile  Apps:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Early bound&lt;/li&gt;&lt;li&gt;Manual install&lt;/li&gt;&lt;li&gt;Manual updates&lt;/li&gt;&lt;li&gt;Isolated&lt;/li&gt;&lt;li&gt;Developed in static languages (Java, Objective C/C++)&lt;/li&gt;&lt;li&gt;Native access&lt;/li&gt;&lt;/ul&gt;Web Apps:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A bit more late bound&lt;/li&gt;&lt;li&gt;Automatic install&lt;/li&gt;&lt;li&gt;Automatic updates&lt;/li&gt;&lt;li&gt;Networked&lt;/li&gt;&lt;li&gt;Developed in dynamic language (JavaScript)&lt;/li&gt;&lt;li&gt;Restricted native access&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;DroidScript&lt;/span&gt;&lt;br /&gt;What it is:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;JavaScript on Android&lt;/li&gt;&lt;li&gt;Experimental open-source project&lt;/li&gt;&lt;li&gt;Based on Mozilla Rhino&lt;/li&gt;&lt;li&gt;Full access to the Android API (minus subclassing)&lt;/li&gt;&lt;li&gt;&lt;a href="http://droidscript.se/"&gt;http://droidscript.se/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://droidscript.blogspot.com/"&gt;http://droidscript.blogspot.com&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;DroidScript Development:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Edit on computer, copy files to device, run on device&lt;/li&gt;&lt;li&gt;Edit on device, run on device&lt;/li&gt;&lt;li&gt;Edit on device, run incrementally on device (like a REPL)&lt;/li&gt;&lt;li&gt;Edit in browser, run incrementally on device&lt;/li&gt;&lt;/ul&gt;DroidScript Deployment:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Copy files to device&lt;/li&gt;&lt;li&gt;Publish JavaScript files and open on device&lt;/li&gt;&lt;li&gt;&lt;a href="http://droidscript.blogspot.com/2010/04/android-camerapreview-sample-in.html"&gt;Publish inlined JavaScript on any web page&lt;/a&gt; and open on device &lt;/li&gt;&lt;li&gt;Open JavaScript from an application (web of applications)&lt;/li&gt;&lt;li&gt;Distribute as native application (with or without dynamic updates)&lt;/li&gt;&lt;li&gt;Security! (*x*)&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;The Future&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;HTML5 and other web-based techniques will become increasingly powerful&lt;/li&gt;&lt;li&gt;Dynamic languages enable dynamic development and dynamic distribution of mobile applications&lt;/li&gt;&lt;li&gt;Going late bound boosts creativity and user participation (LEGO)&lt;/li&gt;&lt;li&gt;A mobile web browser based on a dynamic programming language (NoHTML) would be cool&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;Contact&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;mikael.kindborg (at) mobilesorcery.com&lt;/li&gt;&lt;li&gt;&lt;a href="http://mosync.com/"&gt;http://mosync.com&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-8087018504698453967?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/8087018504698453967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/06/notes-from-talk-at-swdc2010.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8087018504698453967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8087018504698453967'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/06/notes-from-talk-at-swdc2010.html' title='Notes from Talk at SWDC2010'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-7579472260251186776</id><published>2010-05-30T11:39:00.000-07:00</published><updated>2010-05-30T11:39:28.528-07:00</updated><title type='text'>Hört</title><content type='html'>Hört på tunnelbanan av tjejer i övre tonåren:&lt;br /&gt;&lt;br /&gt;"Man får inte vara med sina pojkvänner, det är förbjudet. Man får inte ha pojkvänner."&lt;br /&gt;&lt;br /&gt;"Helt underbart att mina vänner ger mig flyktvägar!"&lt;br /&gt;&lt;br /&gt;"Vissa dagar ser man saker som man inte borde se under en hel livstid."&lt;br /&gt;&lt;br /&gt;Samtal med äldre man:&lt;br /&gt;&lt;br /&gt;Mannen: Det är inte alla som dör.&lt;br /&gt;Jag: Vilka?&lt;br /&gt;Mannen: De som väljer att inte födas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-7579472260251186776?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/7579472260251186776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/05/hort.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/7579472260251186776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/7579472260251186776'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/05/hort.html' title='Hört'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-5073110970512066799</id><published>2010-05-02T13:44:00.001-07:00</published><updated>2010-05-02T13:44:47.762-07:00</updated><title type='text'>Jorden</title><content type='html'>Tack jorden för att jag får gå på dig. Jag ska vara så varsam som möjligt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-5073110970512066799?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/5073110970512066799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/05/jorden.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/5073110970512066799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/5073110970512066799'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/05/jorden.html' title='Jorden'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-819040062595087281</id><published>2010-04-27T15:02:00.000-07:00</published><updated>2010-04-28T13:19:59.216-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Smalltalk'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><title type='text'>Slides from seminar on Dynamic Languages</title><content type='html'>&lt;div&gt;&lt;p&gt;The following are slides from a seminar on Dynamic programming langauges, given at MSC Konsult, Stockholm, April 28, 2010.&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;h1&gt;Better Software with Dynamic Languages&lt;/h1&gt;&lt;p&gt;Mikael Kindborg&lt;/p&gt;&lt;p&gt;2010-04-28&lt;/p&gt;&lt;p&gt;License: Creative Commons Attribution-Noncommercial-Share Alike 2.5 Sweden License&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Programming background&lt;/h2&gt;&lt;p&gt;Programming languages I have used:&lt;/p&gt;&lt;pre&gt;ASTA 1982&lt;br /&gt;Cobol 1982&lt;br /&gt;Simula 1983-1984&lt;br /&gt;CS4 1983&lt;br /&gt;Lisp 1983-1990, 2000-2003 *&lt;br /&gt;Logo 1983-1984 *&lt;br /&gt;Prolog 1984-1985&lt;br /&gt;Pascal 1985-1986 *&lt;br /&gt;C 1985-1999 *&lt;br /&gt;Scheme 1987-1988&lt;br /&gt;Smalltalk 1985-1989, 2003-2010 *&lt;br /&gt;HyperTalk/SuperTalk 1997-1991 *&lt;br /&gt;Lingo 1990-1994, 1997 *&lt;br /&gt;C++ 1993-1999, 2006-2008 *&lt;br /&gt;PowerBuilder 1995-1996 *&lt;br /&gt;Visual Basic 1996 *&lt;br /&gt;Java 1995-2010 *&lt;br /&gt;JavaScript 1995-1999, 2009-2010 *&lt;br /&gt;ToonTalk 1999-2006&lt;br /&gt;PHP 2001-2010 *&lt;br /&gt;Erlang 2002, 2004, 2008&lt;br /&gt;Oz 2003-2005&lt;br /&gt;Python 2003-2010 *&lt;br /&gt;Ruby 2005, 2008&lt;br /&gt;(* = paid work)&lt;/pre&gt;&lt;p&gt;Children's programming tools I have developed:&lt;/p&gt;&lt;pre&gt;Concurrent Comics&lt;br /&gt;Magic Words&lt;/pre&gt;&lt;p&gt;Favourite languages:&lt;/p&gt;&lt;pre&gt;C&lt;br /&gt;Lisp&lt;br /&gt;Smalltalk&lt;br /&gt;Python&lt;br /&gt;JavaScript (CoffeScript)&lt;/pre&gt;&lt;p&gt;Language I would like to learn:&lt;/p&gt;&lt;pre&gt;Factor&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Habits, conciousness, awareness&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Who has decided which language you are using in your project?&lt;/li&gt;&lt;li&gt;Why is it used?&lt;/li&gt;&lt;li&gt;What are the alternatives?&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;World's most popular programming environment&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Dynamic typing&lt;/li&gt;&lt;li&gt;Strong typing&lt;/li&gt;&lt;li&gt;Incremental&lt;/li&gt;&lt;li&gt;Modeless (no build cycle)&lt;/li&gt;&lt;li&gt;Visual/spatial&lt;/li&gt;&lt;li&gt;Image-based&lt;/li&gt;&lt;li&gt;Functional&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This happens to be the spreadsheet!&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Resolver - Spreadsheet in Python&lt;/h2&gt;&lt;p&gt;This is an advanced spreadsheet that uses Python:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://code.google.com/p/resolver/" target="_blank"&gt;http://code.google.com/p/resolver/&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.resolversystems.com/" target="_blank"&gt;http://www.resolversystems.com/&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Prototyping vs Production&lt;/h2&gt;&lt;p&gt;Dynamic languages are good for prototyping because they are fast to develop in.&lt;/p&gt;&lt;p&gt;Static languages are good for production because they are slow to develop in?&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Myths&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Dynamic languages are slow (Scheme/Lisp, Erlang, Node.js (JavaScript) are fast)&lt;/li&gt;&lt;li&gt;Dynamic languages cannot scale (Erlang, Smalltalk, GemStone/S scale)&lt;/li&gt;&lt;li&gt;Dynamic languages are not safe (Erlang is for real-time systems)&lt;/li&gt;&lt;li&gt;Dynamic languages are harder to code in, inexperienced programmers can screw up too easily&lt;/li&gt;&lt;li&gt;Dynamic languages are a new trend. (Dynamic languages were big in 1980, &lt;br /&gt;boosted by AI-research, Lisp, Smalltalk, Prolog, Concurrent Logic Programming, Logo)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Benchmarks: &lt;a href="http://shootout.alioth.debian.org/" target="_blank"&gt;http://shootout.alioth.debian.org/&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;History&lt;/h2&gt;&lt;p&gt;Modern languages and user interfaces have one big influence, Smalltalk and Alan Kay's team at Xerox PARC 1970-1980&lt;/p&gt;&lt;ul&gt;&lt;li&gt;DynaBook&lt;/li&gt;&lt;li&gt;Object-oriented programming&lt;/li&gt;&lt;li&gt;Overlapping windows&lt;/li&gt;&lt;li&gt;Bitmapped graphics&lt;/li&gt;&lt;li&gt;Mouse interaction&lt;/li&gt;&lt;li&gt;Networking (Ethernet)&lt;/li&gt;&lt;li&gt;Font technology&lt;/li&gt;&lt;li&gt;Printing technology&lt;/li&gt;&lt;li&gt;Desktop publishing&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href="http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html" target="_blank"&gt;http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Alan Kay Quotes &lt;/h2&gt;&lt;p&gt;"Actually I made up the term 'object-oriented', and I can tell you I did not have C++ in mind."&lt;/p&gt;&lt;p&gt;"I'm not against types, but I don't know of any type systems that aren't a complete pain, so I still like dynamic typing."&lt;/p&gt;&lt;p&gt;"Java is the most distressing thing to hit computing since MS-DOS."&lt;/p&gt;&lt;p&gt;&lt;a href="http://c2.com/cgi-bin/wiki?AlanKayQuotes" target="_blank"&gt;http://c2.com/cgi-bin/wiki?AlanKayQuotes&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://en.wikiquote.org/wiki/Alan_Kay" target="_blank"&gt;http://en.wikiquote.org/wiki/Alan_Kay&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Demo of Squeak/Pharo&lt;/h2&gt;&lt;p&gt;&lt;a href="http://www.squeak.org" target="_blank"&gt;http://www.squeak.org&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pharo-project.org/home" target="_blank"&gt;http://www.pharo-project.org/home&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Code example:&lt;/p&gt;&lt;pre&gt;Morph subclass: #Drawing&lt;br /&gt; instanceVariableNames: ''&lt;br /&gt; classVariableNames: ''&lt;br /&gt; poolDictionaries: ''&lt;br /&gt; category: 'MyClasses'&lt;br /&gt;&lt;br /&gt;initialize&lt;br /&gt;    super initialize.&lt;br /&gt;    self color: Color white.&lt;br /&gt;    self borderColor: Color black.&lt;br /&gt;    self borderWidth: 2.&lt;br /&gt;    self extent: 600@400.&lt;br /&gt;    self position: 50@50.&lt;br /&gt;    self clipSubmorphs: true.&lt;br /&gt;    self on: #mouseDown send: #createCircle: to: self.&lt;br /&gt;&lt;br /&gt;createCircle: event&lt;br /&gt;    | circle |&lt;br /&gt;    circle := EllipseMorph new.&lt;br /&gt;    circle color: Color red.&lt;br /&gt;    circle borderColor: Color black.&lt;br /&gt;    circle borderWidth: 2.&lt;br /&gt;    circle extent: 100@100.&lt;br /&gt;    circle center: event position.&lt;br /&gt;    self addMorphFront: circle.&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;StrongTalk and the history of the Java Jitter&lt;/h2&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;To: self-interest@self.smli.com&lt;br /&gt;Subject: Sun buys Java compiler technology based upon Self!!!&lt;br /&gt;From: keith@uniteq.com (Keith Hankin)&lt;br /&gt;Date: Tue, 18 Feb 1997 17:38:17 -0800&lt;br /&gt;&lt;br /&gt;Sun has just announced that they are buying Animorphic Systems, which for the &lt;br /&gt;last 2+ years has been developing JIT compiler technology for Java and &lt;br /&gt;Smalltalk.  And, guess what?  It's based upon the Self project!!!&lt;br /&gt;---&lt;br /&gt;Source: http://www.merlintec.com/old-self-interest/msg01011.html&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;From: Dave Griswold &amp;lt;David.Griswold....@gmail.com&amp;gt;&lt;br /&gt;Date: Tue, 2 Sep 2008 12:14:32 -0700 (PDT)&lt;br /&gt;Local: Tues, Sep 2 2008 9:14 pm&lt;br /&gt;Subject: Chrome and V8&lt;br /&gt;&lt;br /&gt;Hi everyone,&lt;br /&gt;&lt;br /&gt;It's been a while, but now that Google has announced Chrome and V8, I&lt;br /&gt;can finally make a little clearer a major reason why I haven't been&lt;br /&gt;pushing Strongtalk development for quite a while: Chrome's new&lt;br /&gt;JavaScript engine V8.&lt;br /&gt;&lt;br /&gt;The V8 development team has multiple members of the original&lt;br /&gt;Animorphic team; it is headed by Lars Bak, who was the technical lead&lt;br /&gt;for both Strongtalk and the HotSpot Java VM (as well as a huge&lt;br /&gt;contributor to the original Self VM).   I think that you will find&lt;br /&gt;that V8 has a lot of the creamy goodness of the Strongtalk and Self&lt;br /&gt;VMs, with many big architectural improvements&lt;br /&gt;---&lt;br /&gt;Source: http://groups.google.com/group/strongtalk-general/browse_thread/thread/40eb8f405fbd3041/0abb010f0eac18e9&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="http://www.strongtalk.org/history.html" target="_blank"&gt;http://www.strongtalk.org/history.html&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;On the StrongTalk Type System: It contains the first fully developed strong, static type system for Smalltalk (hence the name Strongtalk). &lt;br /&gt;The type system is both optional and incremental, and operates completely independently of the compiler &lt;br /&gt;technology (which means that normal untyped Smalltalk code runs just as fast as typed code).&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.strongtalk.org/" target="_blank"&gt;http://www.strongtalk.org/&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Readability&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Shorter code is easier to read and to maintain and refactor&lt;/li&gt;&lt;li&gt;Need balance between cryptic and expressive&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Smalltalk:&lt;/p&gt;&lt;pre&gt;square&lt;br /&gt;    ^self * self&lt;/pre&gt;&lt;p&gt;JavaScript:&lt;/p&gt;&lt;pre&gt;function square(x) {&lt;br /&gt;    return x * x;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;CoffeeScript:&lt;/p&gt;&lt;pre&gt;square: (x) -&amp;gt; &lt;br /&gt;    x * x&lt;/pre&gt;&lt;p&gt;Java:&lt;/p&gt;&lt;pre&gt;public int square(int x) {&lt;br /&gt;    return x * x;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;CoffeeScript: &lt;a href="http://jashkenas.github.com/coffee-script/" target="_blank"&gt;http://jashkenas.github.com/coffee-script/&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;More examples&lt;/h2&gt;&lt;p&gt;Smalltalk:&lt;/p&gt;&lt;pre&gt;self on: #mouseDown send: #createCircle: to: self.&lt;/pre&gt;&lt;pre&gt;button on: #mouseDown send: #value to: [Object inform: 'You clicked me'].&lt;/pre&gt;&lt;p&gt;JavaScript:&lt;/p&gt;&lt;pre&gt;button.setOnClickListener(function (view) {&lt;br /&gt;    view.setText("You Clicked Me!"); &lt;br /&gt;});&lt;/pre&gt;&lt;p&gt;CoffeeScript:&lt;/p&gt;&lt;pre&gt;button.setOnClickListener((view) -&amp;gt; view.setText("You Clicked Me!"))&lt;/pre&gt;&lt;p&gt;Java:&lt;/p&gt;&lt;pre&gt;button.setOnClickListener(new View.OnClickListener() {&lt;br /&gt;    public void onClick(View view) {&lt;br /&gt;        (Button) view).setText(""You Clicked Me!")&lt;br /&gt;    }&lt;br /&gt;});&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;More CoffeeScript&lt;/h2&gt;&lt;p&gt;CoffeeScript:&lt;/p&gt;&lt;pre&gt;mood: greatly_improved if singing&lt;br /&gt;&lt;br /&gt;if happy and knows_it&lt;br /&gt;  claps_hands()&lt;br /&gt;  cha_cha_cha()&lt;br /&gt;&lt;br /&gt;date: if friday then sue else jill&lt;br /&gt;&lt;br /&gt;expensive: or do_the_math()&lt;/pre&gt;&lt;p&gt;Compiles to JavaScript:&lt;/p&gt;&lt;pre&gt;var date, expensive, mood;&lt;br /&gt;if (singing) {&lt;br /&gt;  mood = greatly_improved;&lt;br /&gt;}&lt;br /&gt;if (happy &amp;&amp; knows_it) {&lt;br /&gt;  claps_hands();&lt;br /&gt;  cha_cha_cha();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;date = friday ? sue : jill;&lt;br /&gt;expensive = expensive || do_the_math();&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Things that make life difficult&lt;/h2&gt;&lt;p&gt;Source code analysis is clearly helpful, and optional type &lt;br /&gt;declarations can add value, but in static languages that is not all you get. &lt;br /&gt;You also get some less desirable things:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Static inheritance relation - cannot be changed at runtime&lt;/li&gt;&lt;li&gt;Type hierarchy lock in, not true polymorphism&lt;/li&gt;&lt;li&gt;Interfaces are not protocol specifications, they are hierarchical types&lt;/li&gt;&lt;li&gt;Primitive types&lt;/li&gt;&lt;li&gt;Modifiers&lt;/li&gt;&lt;li&gt;Generics&lt;/li&gt;&lt;li&gt;Extreme line noise&lt;/li&gt;&lt;li&gt;Things change, and static types, as the name implies, are not friendly to change&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This:&lt;/p&gt;&lt;pre&gt;public static final synchronized &lt;br /&gt;List&amp;lt;Map&amp;lt;String, Product&amp;gt;&amp;gt; getProductList() {&lt;br /&gt;    List&amp;lt;Map&amp;lt;String, Product&amp;gt;&amp;gt; productList = &lt;br /&gt;        new ArrayList&amp;lt;Map&amp;lt;String, Product&amp;gt;&amp;gt;();&lt;br /&gt;    ...&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;Can be:&lt;/p&gt;&lt;pre&gt;def getProductList():&lt;br /&gt;    productList = []&lt;br /&gt;    ...&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Strong points of dynamically typed languages&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Fast to develop&lt;/li&gt;&lt;li&gt;Late binding&lt;/li&gt;&lt;li&gt;Incremental development (no build cycles)&lt;/li&gt;&lt;li&gt;Shorter code&lt;/li&gt;&lt;li&gt;Easier to read code&lt;/li&gt;&lt;li&gt;Easier to maintain/refactor code&lt;/li&gt;&lt;li&gt;Aggressive Jitting possible with late binding&lt;/li&gt;&lt;li&gt;Polymorphism/Duck typing&lt;/li&gt;&lt;li&gt;High-level constructs, e.g. first-class functions and closures&lt;/li&gt;&lt;li&gt;Syntax for data structures (tuples, lists)&lt;/li&gt;&lt;li&gt;DSL-friendly&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As one participant at the seminar pointed out, many of these points are also true of functional languages based on type inference, like Haskell and Ocaml.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Duck typing: "If it walks like a duck and talks like a duck, it must be a duck"&lt;/p&gt;&lt;p&gt;&lt;a href="http://c2.com/cgi/wiki?DuckTyping" target="_blank"&gt;http://c2.com/cgi/wiki?DuckTyping&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Duck_typing" target="_blank"&gt;http://en.wikipedia.org/wiki/Duck_typing&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;What makes Smalltalk special?&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Truly incremental development&lt;/li&gt;&lt;li&gt;Late binding taken to the extreme&lt;/li&gt;&lt;li&gt;Source code at your fingertips&lt;/li&gt;&lt;li&gt;Innovative keyword syntax&lt;/li&gt;&lt;li&gt;Succinct closure syntax&lt;/li&gt;&lt;li&gt;Rich programming environment (doit, debugger, inspector, senders/implementors, refactoring browser...)&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Weak points&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Type declarations serves as documentation&lt;/li&gt;&lt;li&gt;Type declarations make refactoring tools more reliable&lt;/li&gt;&lt;li&gt;Weak typing is a source of mistakes&lt;/li&gt;&lt;li&gt;Implicit variable declarations are error prone&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;Demo of JavaScript on Android&lt;/h2&gt;&lt;p&gt;&lt;a href="http://droidscript.se" target="_blank"&gt;http://droidscript.se&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://droidscript.blogspot.com" target="_blank"&gt;http://droidscript.blogspot.com&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-819040062595087281?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/819040062595087281/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/04/slides-from-seminar-on-dynamic.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/819040062595087281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/819040062595087281'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/04/slides-from-seminar-on-dynamic.html' title='Slides from seminar on Dynamic Languages'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-2906988115016976582</id><published>2010-04-06T13:38:00.000-07:00</published><updated>2010-04-06T14:10:33.064-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><title type='text'>Y Combinator explained</title><content type='html'>I have spent some time to look into the Y Combinator, a function for defining recursive functions without using conventional recursion support.&lt;br /&gt;&lt;br /&gt;The Y Combinator is quite legendary in functional programming, and appears in "&lt;a href="http://www.ccs.neu.edu/home/matthias/BTLS/"&gt;The Little Schemer&lt;/a&gt;", by Daniel P. Friedman and Matthias Felleisen. The idea is to show how recursion can be expressed in a language that does not support recursion (but has support for higher-order functions). As implementation language I will use JavaScript, and I will also show how Y can be expressed in Smalltalk and in Erlang.&lt;br /&gt;&lt;br /&gt;A good article on Y written by James Coglan can be found here: &lt;a href="http://blog.jcoglan.com/2008/01/10/deriving-the-y-combinator/"&gt;http://blog.jcoglan.com/2008/01/10/deriving-the-y-combinator/&lt;/a&gt;. Like James Coglan, I write this blog article to better understand Y, and I use a somewhat different approach to explain it. A tool you can use to interactively experiment with the functions below, is this live browser-based JavaScript editor: &lt;a href="http://droidscript.se/jsedit.html"&gt;http://droidscript.se/jsedit.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Typically a recursive function is said to "call itself", like this recursive definition of the factorial function in JavaScript:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;function factorial(n) {&lt;br /&gt;    if (n == 0) { return 1; }&lt;br /&gt;    else { return n * factorial(n - 1); }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The trick to understand recursion, and the Y Combinator, is that a recursive function actually does not "call itself", it calls an instance of a function that has the same function body, but with its own values for the actual parameters. Thus, recursion is not iterative, but consists of a chain of function calls lined up waiting for each other to return (unless you have optimised tail recursion, but that is another story). When the recursion has reached the end and returns, the function calls that wait return one by one, each using their local variable values to compute their result in the call chain.&lt;br /&gt;&lt;br /&gt;If I could draw a diagram of this (not easily done with primitive blog tools!), it would become more clear than using plain words. But we can picture the call chain like this:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;factorial(3)&lt;/code&gt;&lt;/pre&gt;is the same as:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;3 * (2 * (1 * (1)))&lt;/code&gt;&lt;/pre&gt;This is what we get if we substitute the calls with the actual variable values in each function instance. The innermost 1 is the number returned by the factorial function when the value of n is zero.&lt;br /&gt;&lt;br /&gt;The point of Y Combinator is to show that recursion can be expressed without referring to the name of the recursive function. Of little practical relevance, but an interesting exploration of recursive functional structures.&lt;br /&gt;&lt;br /&gt;Lets start by this recursive JavaScript function:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;function repeat() {&lt;br /&gt;    if (confirm("Continue?")) { repeat(); }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;How can this be written without referring to the name of the function? To do this, we will use an anonymous function that takes another anonymous function as a parameter.&lt;br /&gt;&lt;br /&gt;Anonymous functions are functions that do not have a name, here is a quick example before we continue.&lt;br /&gt;&lt;br /&gt;This:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;function twice(n) { return n * 2; }&lt;br /&gt;alert(twice(22));&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Can be written as:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;fun = function(n) { return n * 2 };&lt;br /&gt;alert(fun(22));&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Or, if we substitute the variable fun with the expression it refers to:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;result = (function(n) { return n * 2 }) (22);&lt;br /&gt;alert(result);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Now back to the version of repeat written with anonymous functions:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;(function(fun) { fun(fun); }) &lt;br /&gt;(function(fun) { &lt;br /&gt;    if (confirm("Continue?")) { fun(fun); });&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;What happens here is that the function (function(fun) { fun(fun); }) gets called and "kick-starts" the recursion. This is an anonymous function that takes another function as a parameter. It then calls that function with the very same function as the argument. The actual function being called is the other anonymous function, which is a variation of our continue function. Inside that function, the function is again called, with the very same function as its argument! This means that we will get an endless chain of function calls until the user chooses not to continue, in which case the recursive function application is not called, and the call stack unwinds and the function call chain terminates.&lt;br /&gt;&lt;br /&gt;Another way to write the same thing:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;repeat = (function(fun) { &lt;br /&gt;    if (confirm("Continue?")) { fun(fun); });&lt;br /&gt;repeat(repeat);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Here we use a variable to refer to the anonymous function, and apply it to itself. Note that this is not cheating, it is not a named recursive function call, and we could just as well have replaced the occurrences of repeat in the call on the second line with the function expression it refers to.&lt;br /&gt;&lt;br /&gt;This "trick" of calling a function with another function as a parameter (which happens to be the same function), is at the heart of the Y Combinator.&lt;br /&gt;&lt;br /&gt;Before showing Y, we will use one more intermediate step. The above example does not take a parameter, and does not return anything useful. To recursively compute something, say the factorial of a number, we need to be able to supply parameters to and return values from the recursive function applications.&lt;br /&gt;&lt;br /&gt;Here is factorial written as a "kick-started" anonymous recursive function; then we call the function using the variable factorial, which refers to the expression that starts the computation:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;factorial = (function(fun) { return fun(fun); })&lt;br /&gt;    (function(fun) {&lt;br /&gt;        return function(n) {&lt;br /&gt;            return n == 0 ? 1 : n * fun(fun)(n - 1); } } );&lt;br /&gt;alter(factorial(9));&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Tadam! Here we have proper recursion without using named functions. But what does the variable factorial in the above piece of code refer to? It refers to an instance of the anonymous function that starts on line 3, with the local variable fun referring to the anonymous function that starts on line 2. The function returned on line 3 is an example of a closure; a function instance that has some of its local variables initialised, but has not yet started to execute. On line 5, that function gets called with the argument value 9. And on line 4 the same process continues and drives the recursion.&lt;br /&gt;&lt;br /&gt;It is still a bit cumbersome and non-general to have to apply fun to itself inside factorial. It would be nicer to have something that looks like a proper recursive function call, and this is what Y accomplishes.&lt;br /&gt;&lt;br /&gt;Finally, here is the definition of Y Combinator, using a style similar to the one we have used above:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;Y = function(fun) {&lt;br /&gt;    return (function(recurse) { return recurse(recurse); })&lt;br /&gt;       (function(recurse) { return function(x) { &lt;br /&gt;           return fun(recurse(recurse))(x); }; });&lt;br /&gt;};&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Y neatly packages the recursive function application into one single closure; the function that is returned on line 3 above. The difference from the previous example is that we have separated the function fun that does the specific computation (factorial in our example below) from the function that does the recursive application (recurse). It should also be noted that this definition of Y is limited to recursive functions that take one argument.&lt;br /&gt;&lt;br /&gt;Y is used with functions that have this form:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;factorial = function(recurse) {&lt;br /&gt;    return function(n) {&lt;br /&gt;        return n == 0 ? 1 : n * recurse(n - 1); } };&lt;br /&gt;};&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;And here is how to call it:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;alert(Y(factorial)(9));&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Y can (as far as I know) be written in any language that supports higher-order functions and closures. Here is a version in Smalltalk that uses block closures:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;y := [:fun | [:recurse | recurse value: recurse] value:&lt;br /&gt;    [:recurse | [:x | (fun value: &lt;br /&gt;        (recurse value: recurse)) value: x]]].&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Example on use (produces a pretty big number):&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;factorial := [:recurse | [:n | n = 0 &lt;br /&gt;    ifTrue: [1] &lt;br /&gt;    ifFalse: [n * (recurse value: n - 1)]]].&lt;br /&gt;   &lt;br /&gt;(y value: factorial) value: 5000.&lt;/code&gt;&lt;/pre&gt;Erlang is a cool functional language, and here goes two variations of Y:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;Y = fun(Function) -&amp;gt; &lt;br /&gt;    (fun(Recurse) -&amp;gt; Recurse(Recurse) end)&lt;br /&gt;    (fun(Recurse) -&amp;gt; fun(X) -&amp;gt; &lt;br /&gt;        (Function(Recurse(Recurse)))(X) end end) end.&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Somewhat simplified with a variable that refers to the recursive function:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;Y = fun(Function) -&amp;gt; &lt;br /&gt;    Go = fun(Recurse) -&amp;gt; fun(X) -&amp;gt; &lt;br /&gt;        (Function(Recurse(Recurse)))(X) end end,&lt;br /&gt;    Go(Go) end.&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;And how to use (Erlang too can handle big numbers):&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;Factorial = fun(Recurse) -&amp;gt; &lt;br /&gt;    fun(0) -&amp;gt; 1; &lt;br /&gt;       (N) -&amp;gt; N * Recurse(N - 1) end end.&lt;br /&gt;&lt;br /&gt;(Y(Factorial))(5000).&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;A good way to understand how the above code examples work is to draw diagrams on paper of how the anonymous functions are instantiated and called.&lt;br /&gt;&lt;br /&gt;Y Combinator is also the name of a &lt;a href="http://ycombinator.com/"&gt;start-up venture firm&lt;/a&gt; funded by &lt;a href="http://paulgraham.com/"&gt;Paul Graham&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-2906988115016976582?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/2906988115016976582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/04/y-combinator-explained.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/2906988115016976582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/2906988115016976582'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/04/y-combinator-explained.html' title='Y Combinator explained'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-8249244979995502550</id><published>2010-04-05T11:20:00.001-07:00</published><updated>2010-04-05T11:20:48.453-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='DroidScript'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>New version of DroidScript - JavaScript on Android</title><content type='html'>There is a new version of DroidScript available, see the DroidScript blog:&lt;br /&gt;&lt;a href="http://droidscript.blogspot.com/2010/04/version-4-of-droidscript.html"&gt;http://droidscript.blogspot.com/2010/04/version-4-of-droidscript.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-8249244979995502550?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/8249244979995502550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/04/new-version-of-droidscript-javascript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8249244979995502550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8249244979995502550'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/04/new-version-of-droidscript-javascript.html' title='New version of DroidScript - JavaScript on Android'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-241070218340286254</id><published>2010-03-26T15:06:00.000-07:00</published><updated>2010-03-26T15:06:47.083-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='test'/><category scheme='http://www.blogger.com/atom/ns#' term='Sikuli'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Sikuli - Python source code with pictures</title><content type='html'>I love Sikuli! What I like most is that the source code contains pictures! Since I have a background in visual programming and programming languages based on comic strips, one might have guessed that I would fall for Sikuli :-) Even better, the programming language is Python (Jython), which makes for really clean code. &lt;br /&gt;&lt;br /&gt;Now, what is Sikuli? It is a tool for scripting user interfaces, and it is based on matching images (for example an image of a button in the ui). I introduced Sikuli to a client the other day, and now they are using it to create automated ui tests for a web application.&lt;br /&gt;&lt;br /&gt;I have one hint, importing modules with Python's standard import statement does not work, instead use execfile to load your Python modules (see link below).&lt;br /&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;a href="http://groups.csail.mit.edu/uid/sikuli/"&gt;http://groups.csail.mit.edu/uid/sikuli/&lt;/a&gt; &lt;br /&gt;&lt;a href="https://answers.launchpad.net/sikuli/+question/102003"&gt;https://answers.launchpad.net/sikuli/+question/102003&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-241070218340286254?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/241070218340286254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/03/sikuli-python-source-code-with-pictures.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/241070218340286254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/241070218340286254'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/03/sikuli-python-source-code-with-pictures.html' title='Sikuli - Python source code with pictures'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-6128723162847930333</id><published>2010-03-24T09:00:00.000-07:00</published><updated>2010-03-24T09:00:34.312-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='SWDC2010'/><category scheme='http://www.blogger.com/atom/ns#' term='DroidScript'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Talk on dynamic Android apps at SWDC2010</title><content type='html'>I will be giving a talk on dynamic languages on Android at the &lt;a href="http://swdc-central.com/" target="_blank"&gt;Scandinavian Web Developer Conference 2010&lt;/a&gt;. It goes without saying that I am proud of being invited to speak at this high-profile conference. I am looking forward to Marcus Ahnve talking about TDD and Android, and to Nikolai Onken's talk on accessing hardware from the browser, to name a few.&lt;br /&gt;&lt;br /&gt;It is interesting to note that after years of having a trend towards browser based applications, the popularity of iPhone and Android has shifted focus back to "fat clients" in the form of mobile apps. Obviously, native apps have the potential for a richer user interface experience than what is possible with today's browser based apps.&lt;br /&gt;&lt;br /&gt;But mobile apps tend to be a bit heavy going. In the case of iPhone, this is especially noteworthy. Not only is there a substantial development cycle (edit, compile, run) for native apps, Apple's notorious process for accepting apps to the app store stretches the deployment cycle to the magnitude of weeks.&lt;br /&gt;&lt;br /&gt;Android development and deployment is quite smooth, thanks to the Eclipse plugin for Android, and to the fact that one can easily and legally deploy the app on any web site (you are not restricted to Android Market). Still there is some effort involved in deploying and installing new versions of an app. And the development process is still based on the build centric edit-compile-run cycle.&lt;br /&gt;&lt;br /&gt;When it comes to web development, there is no need to rebuild and redeploy the application on every edit-run cycle. Thanks to JavaScript being a dynamic language, you can edit and reload only the part that has been updated. A web application is also trivial to deploy and upgrade (ahem, well in theory that is ;-). &lt;br /&gt;&lt;br /&gt;In my talk at SWDC2010, I will discuss how dynamic languages like JavaScript can be used as a basis for a platform where applications can be deployed and updated with the same ease as for browser based applications. Furthermore, I will discuss how to take advantage of the dynamic nature of JavaScript for incremental development of applications, and demo the interactive editor in DroidScript, which is a simplistic but illustrative example of a Smalltalk inspired programming tool for Android.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-6128723162847930333?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/6128723162847930333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/03/talk-on-scripted-android-apps-at.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/6128723162847930333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/6128723162847930333'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/03/talk-on-scripted-android-apps-at.html' title='Talk on dynamic Android apps at SWDC2010'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-8549905776381048619</id><published>2010-03-21T14:36:00.000-07:00</published><updated>2010-03-21T14:36:54.664-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='DroidScript'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>More DroidScript</title><content type='html'>I have written a couple of code examples that illustrate how to create ListViews in JavaScript on Android. See the DroidScript blog: &lt;a href="http://droidscript.blogspot.com/"&gt;http://droidscript.blogspot.com&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-8549905776381048619?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/8549905776381048619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/03/more-droidscript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8549905776381048619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8549905776381048619'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/03/more-droidscript.html' title='More DroidScript'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-3880953484724657228</id><published>2010-03-03T14:34:00.000-08:00</published><updated>2010-03-03T14:38:31.669-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><title type='text'>Google Closure</title><content type='html'>These are notes for a talk on &lt;a href="http://code.google.com/closure/"&gt;Google Closure&lt;/a&gt; I will give tomorrow at &lt;a href="http://sites.google.com/site/stockholmgtug/"&gt;GTUG Stockholm&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Note that Google Closure is a JavaScript library and toolkit, not to be confused with the Lisp dialect &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt; (which happens to be pronounced as "closure").&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;Overview&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;The Closure toolkit consists of the following parts:&lt;br /&gt;&lt;ul style="background-color: white;"&gt;&lt;li&gt;Closure Compiler - JS to JS compiler; optimises and checks your JavaScript code.&lt;/li&gt;&lt;li&gt;Closure Library - very comprehensive; UI widgets, graphics, modules, packaging, DOM manipulation, communication, test framework, and much more.&lt;/li&gt;&lt;li&gt;Closure Templates - dynamic generation of HTML using a template language; "small components that you compose to form your user interface"; for both client side (JavaScript) and server side (Java). &lt;/li&gt;&lt;li&gt;Closure is used by large-scale web applications; it is the foundation for Gmail, Calendar, Docs, Blogger, and other Google products.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;Closure Compiler&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;The compiler is an optimising JavaScript to JavaScript compiler. There is an &lt;a href="http://closure-compiler.appspot.com/home"&gt;interactive compiler tool&lt;/a&gt; available that is very cool, just paste in your JavaScript and optimise it. There is also Service API for calling the compiler from a program. One feature of the compiler is the optional use of doc tags annotations and type expressions for providing type hints etc.&lt;br /&gt;&lt;br /&gt;As an experiment I ran the &lt;a href="http://jquery.com/"&gt;jQuery library&lt;/a&gt; through the compiler. Here are the numbers:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Compiling &lt;a href="http://code.jquery.com/jquery-1.4.2.js"&gt;http://code.jquery.com/jquery-1.4.2.js&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;Original Size: 160.01KB (45.04KB gzipped)&lt;br /&gt;Compiled Size: 63.86KB (22.75KB gzipped)&lt;br /&gt;Saved 60.09% off the original size (49.49% off the gzipped size)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Compiling &lt;a href="http://code.jquery.com/jquery-1.4.2.min.js"&gt;http://code.jquery.com/jquery-1.4.2.min.js&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;Original Size: 70.48KB (24.03KB gzipped)&lt;br /&gt;Compiled Size: 63.84KB (22.75KB gzipped)&lt;br /&gt;Saved 9.42% off the original size (5.33% off the gzipped size)&lt;br /&gt;&lt;br /&gt;The Google optimiser generates a bit more compact code than the minimised jQuery library. I have not done any performance tests, so I cannot say how the Google version performs compared to the original jQuery code.&lt;br /&gt;&lt;br /&gt;Personally, I think it is a bit sad with the tendency to deliver optimised JavaScript code, because one of the truly great things with the web was to be able to view the source of any web page. That boosted knowledge about HTML and web design, and I would prefer if the JavaScript engine would take care of the optimisation. To always have the source code available is a huge advantage. This is one of the things that makes Smalltalk so productive; the code for the whole library and even the compiler is available to study and learn from.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;Closure Templates&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Closure includes a template language. It provides a common language for both JavaScript (client-side) and Java (server-side), and the idea is to write small, composable units that are used to build web applications. The syntax is based on curly-bracket tags, not as painful for the eye as XML, but it goes without saying that it is a freaky syntax, and one might indeed ask what motivates template languages in general. I have never understood the benefits of having a half-done semi-markup and semi-programing language when you can have the full power of a dynamic language with internal DSLs if needed. A strong point of XML and other markup languages is that they describe structure and content in a declarative way. But you have always had this for free in Lisp, and with proper DSL-design and other language extensions, the same can be done in Python, Ruby, JavaScript, Smalltalk, et. al.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;Closure Library&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;The JavaScript library is the heart of Closure, and it is a massive library that covers most aspects you could ask for when developing advanced web applications. There is a module system, with proper namespaces, and it is easy do define your own namespaces and modules.&lt;br /&gt;&lt;br /&gt;A hint; as an alternative to download the entire library from Google's Subversion repository, you can refer to the base file in a script tag, using this url: http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;JavaScript Live Editor&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;To get started and dive into the Closure library, I decided to create a web-based JavaScript editor that could interactively evaluate Closure code. I would also use Closure itself when writing the editor. I already had the &lt;a href="http://droidscript.se/"&gt;DroidScript live editor&lt;/a&gt; for programming JavaScript on Android, which is implemented using jQuery and CodeMirror. So I took that editor and rewrote it using Google Closure. It is a very small project, just one web page with some embedded JavaScript that evaluates code, but it was an useful experience. The editor, which contains a number of Closure code examples, is here: &lt;a href="http://droidscript.se/jseditor"&gt;http://droidscript.se/jseditor&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The editor works like a Smalltalk workspace; select a piece of code and evaluate it. This proved to be a useful tool for experimenting with the Closure library, and it should be equally usable for interactive exploration of jQuery, or any JavaScript library, or JavaScript programming in general. I have never understood why most REPLs are command-line oriented. Long time since we used paper-based teletype terminals ;-) &lt;br /&gt;&lt;br /&gt;Finally, I wish to give massive amounts of cred. to Marijn Haverbeke, the author of &lt;a href="http://marijn.haverbeke.nl/codemirror/"&gt;CodeMirror&lt;/a&gt;, a syntax highlighting code editor written in JavaScript (note that it is *not* part of the Closure library). It is the best web-based code editor I have seen, with a clean API that is very easy to use.&lt;br /&gt;&lt;br /&gt;To sum up on Closure, it is definitely seems like a very capable library. Heavier and more complex than for example jQuery, but for large applications it provides much more support and features. It feels like GWT without Java, and using JavaScript rather than Java is by definition a good thing ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-3880953484724657228?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/3880953484724657228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/03/google-closure.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3880953484724657228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3880953484724657228'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/03/google-closure.html' title='Google Closure'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-6549641130075213413</id><published>2010-02-20T14:54:00.000-08:00</published><updated>2010-02-20T15:02:30.780-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='DroidScript'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>DroidScript - JavaScript for Android</title><content type='html'>I have published a post at my &lt;a href="http://droidscript.blogspot.com/2010/02/droidscript-live-javascript-on-android.html"&gt;DroidScript blog&lt;/a&gt; that describes a tool for programming Android devices interactively in a web browser using JavaScript.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-6549641130075213413?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/6549641130075213413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/02/droidscript-javascript-for-android.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/6549641130075213413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/6549641130075213413'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/02/droidscript-javascript-for-android.html' title='DroidScript - JavaScript for Android'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-1606747577532625591</id><published>2010-02-20T14:51:00.000-08:00</published><updated>2010-02-20T14:51:46.324-08:00</updated><title type='text'>Utvecklingen av tunnelbananedramat</title><content type='html'>Historien om Jesper Nilsson som blev utsatt för tveksamma metoder från två civilpoliser i tunnelbanan fortsätter. Jesper har &lt;a href="http://tuggarna.posterous.com/polisen-som-mitt-i-tunnelbanan-star"&gt;uppdaterat sin blogg&lt;/a&gt; med vad som hänt efter händelsen. Jag hoppas att inte media och andra inblandade tappar intresset. Tvärtom ser det ut som att både jurister och media följer fallet med intresse. Hoppas Jesper fortsätter skriva om fallet på sin blogg. Händelsen känns som toppen på ett isberg, och det känns viktigt att den följs upp.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-1606747577532625591?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/1606747577532625591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/02/utveckingen-av-tunnelbananedramat.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/1606747577532625591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/1606747577532625591'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/02/utveckingen-av-tunnelbananedramat.html' title='Utvecklingen av tunnelbananedramat'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-8573472990986468710</id><published>2010-02-13T01:48:00.000-08:00</published><updated>2010-02-13T01:54:01.724-08:00</updated><title type='text'>Villkor för fotografering i Stockholms tunnelbana (in Swedish)</title><content type='html'>Dagens stora samhällsrättsliga nyhet är det förmodade polisövergreppet mot Jesper Nilsson som &lt;a href="http://tuggarna.posterous.com/polisen-som-mitt-i-tunnelbanan-star" target="_blank"&gt;fotograferade och filmade&lt;/a&gt; två civilpoliser i Stockholms tunnelbana (se bland annart &lt;a href="http://www.dn.se/sthlm/poliser-trakasserar-debattor-1.1044619" target="_blank"&gt;artikel i DN&lt;/a&gt;). &lt;br /&gt;&lt;br /&gt;Efter att ha sett en hänvisning till en uppseendeväckande formulering i de villkor för fotografering i tunnelbanan som MTR (företaget som driver Stockholms tunnelbana) har ställt ut, letade jag upp &lt;a href="http://www.mtrstockholm.se/om-oss/fota-i-tunnelbanan.aspx" target="_blank"&gt;texten med villkoren&lt;/a&gt; på MTRs hemsida. Här är de intressanta avsnitten (markeringen med kursiv stil är min egen):&lt;br /&gt;&lt;br /&gt;"&lt;b&gt;För privat bruk&lt;/b&gt;&lt;br /&gt;Privatpersoner som vill fotografera eller filma i SLs miljöer för enskilt bruk behöver inte söka tillstånd. Detta förutsatt att de inte på något sätt påverkar eller stör den dagliga verksamheten.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;I kommersiellt syfte&lt;/b&gt;&lt;br /&gt;När syftet med filmning eller fotografering i SL-trafiken är kommersiellt skall gällande lagar och förordningar följas. Generellt tillämpas Internationella handelskammarens (ICC) regler.&lt;br /&gt;Detta innebär att SLs miljöer inte får förekomma i sammanhang som gör reklam för tobak, alkoholhaltiga drycker, reklam som kan uppfattas som stötande, sedlighetssårande eller sårande mot folkgrupp, reklam riktad mot kollektivtrafiken och reklam som kan anses strida mot god marknadsföringssed.&lt;br /&gt;&lt;i&gt;Det är heller inte tillåtet att filma eller fotografera vandalisering eller graffiti, så kallad plankning, våld mot resenärer eller personal, rökning eller användande av illegala droger eller personer som vistas i SL-trafiken utan giltig biljett. Allmänt gäller att SL och SLs miljöer inte ska figurera i sammanhang som uppfattas som störande eller stötande&lt;/i&gt;."&lt;br /&gt;&lt;br /&gt;Min tolkning av ovanstående är att för privat bruk är det i princip fritt fram att fotografera i tunnelbanan utan restriktioner, men för kommersiellt bruk är det inte tillåtet att fotografera till exempel polisövergrepp eller misshandel (då denna forumlering faller under rubriken "I kommersiellt syfte"). Om det inte skulle vara tillåtet (åtalbart) för en privatperson att dokumentera brott innebär det att bevisläget vid t.ex. polisövergrepp och andra misshandelsbrott kraftigt försämras till den drabbades nackdel.&lt;br /&gt;&lt;br /&gt;Dessa villkor öppnar för många frågor beträffande vad lagen egentligen säger, och vilken rätt ett företag har att ställa upp egna villkor inom detta område. Intressant är också frågor kring relationen mellan SL och MTR. Vem äger SL? På SLs hemsida står att "Stockholms läns landsting äger aktiebolaget SL". Går skattemedel till att finsanisera verksamheten? (Ja via landstingsskatten.) Kan MTR som privat, ej landstingsägt företag utfärda sina egna villkor utan att SL (och ägaren landstinget) godkänner dessa?&lt;br /&gt;&lt;br /&gt;Utvecklingen av rättsläget i Sverige känns inte lovande. Intrång i den personliga integriteten, lobbyingorganisationer som påverkar lagstiftningen på området, polisövergrepp, och andra tveksamma händelser ger en mörk bild av vart vårt samhälle är på väg. Jag är tacksam för att det än så länge finns ett fritt internet där fria människor kan rapportera, exponera och diskutera rättsläget i vår demokrati. Att en demokrati förblir en demokrati är inte alls självklart, vilket bland andra &lt;a href="http://www.youtube.com/watch?v=RjALf12PAWc"&gt;Naomi Wolf&lt;/a&gt; kan berätta om.&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-8573472990986468710?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/8573472990986468710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/02/villkor-for-fotografering-i-stockholms.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8573472990986468710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8573472990986468710'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/02/villkor-for-fotografering-i-stockholms.html' title='Villkor för fotografering i Stockholms tunnelbana (in Swedish)'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-7773929735456887530</id><published>2010-02-11T12:36:00.000-08:00</published><updated>2010-02-11T12:38:04.785-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Book Review: "Beginning Android"</title><content type='html'>Book Review: "Beginning Android"&lt;br /&gt;Mark L. Murphy&lt;br /&gt;Apress, 2009&lt;br /&gt;ISBN: 978-1-4302-2419-8&lt;br /&gt;&lt;br /&gt;I got a review copy of this book from Apress. Here is the review.&lt;br /&gt;&lt;br /&gt;This is a book for programmers who have a basic knowledge of Java and want to get an introduction to the elements of Android programming. The book should be useful for both professionals and hobbyists. It is easy to read and well structured, and not too extensive, which makes it comprehensible. The 350 pages do a good job at covering a fair amount of the Android API. One area that is not covered is development tools, here the book refers to the Android web site (&lt;a href="http://www.android.com/" target="_blank"&gt;www.android.com&lt;/a&gt;). Setting up a development environment for Android can be tricky if you are new to programming, so this is an area where less experienced readers are left on their own.&lt;br /&gt;&lt;br /&gt;The book covers Android 1.5, which is an old version by now. I however found the text and the code examples useful also for Android 2.1 development. The back inside cover mentions that there is a companion eBook available. An updated eBook would be of great added value, but it should be provided for free to customers who have purchased the book, not at additional cost as seems to currently be the case.&lt;br /&gt;&lt;br /&gt;The style of writing is clear and the text is easy to read. The book is structured into several short chapters, where each chapter covers an aspect of Android development and the related parts of the API. Each chapter begins with an introduction that explains the topics covered in the chapter. Then follows a complete, runnable, and often short and concise code example that illustrates the chapter topic. This makes the book useful as a cookbook.&lt;br /&gt;&lt;br /&gt;One not-so-nice aspect of the text is the use of supposedly funny section titles. I find titles like “Mother, May I”, “Halt! Who Goes There?”, ”When IPC Attacks!”, and “Seeing Pestering in Action”, to be quite irritating and distracting. The subject is interesting on its own merits, and the silly section titles actually make it harder to find what you are looking for in the book. There may, however, be readers who will find the titles entertaining. Another less good aspect of the book is the code style used, with no blanks between the parts of an expression. The first chapters use the correctly spaced Java-code style, but the majority of the chapters do not, and this is bad since it can establish bad coding practices among readers (especially beginners).&lt;br /&gt;&lt;br /&gt;It is quite common for programming books to list classes and methods in the APIs covered, something which I find superfluous since the most current API documentation is available online. This book does not provide API listings, which is positive because it makes the text more coherent and flowing. It also saves pages, and makes room for more code examples and explanatory texts, which are added values compared to the online API documentation, and a reason for buying a book.&lt;br /&gt;&lt;br /&gt;For me, the major value of the book has been as a cookbook of code examples. The examples in the book are often short, clear, useful, and on the spot on what you want to do.&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-7773929735456887530?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/7773929735456887530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/02/book-review-beginning-android.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/7773929735456887530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/7773929735456887530'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/02/book-review-beginning-android.html' title='Book Review: &quot;Beginning Android&quot;'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-1673463492576771461</id><published>2010-02-09T21:48:00.000-08:00</published><updated>2010-02-09T21:52:48.855-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rosenmetoden'/><title type='text'>Talk on Rosenmetoden in Stockholm</title><content type='html'>This Saturday (Feb 13) there will be a talk and demo of Rosenmetoden in Stockholm: &lt;a href="http://jeanette.nu/"&gt;http://jeanette.nu/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm studying to become a Rosen Method practitioner, hence my interest in the subject. When I first met Marion Rosen, the physical therapist who has developed the method (and given it its name), I was quite taken. The first thing she said was, "Protection is not necessary". At that point it became clear to me that many problems and conflicts in the world, both on a personal and global level (they interrelate, people's actions shape the world), spring from our habits of protecting ourselves from people, emotions, and future misfortune (however unlikely to happen). I realized that my default attitude was that strangers can mean problems, better be on guard. And I think that attitude is draining you on energy. &lt;br /&gt;&lt;br /&gt;Then I discovered the Rosen Method Movements, a truly lovely and relaxing way of moving. I'm completely hooked on it, and take classes every week now.&lt;br /&gt;&lt;br /&gt;Read more at:&lt;br /&gt;&lt;a href="http://www.rosenmethod.org/"&gt;http://www.rosenmethod.org/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://jeanette.nu/rosenmetoden.html"&gt;http://jeanette.nu/rosenmetoden.html&lt;/a&gt; (Swedish text)&lt;br /&gt;&lt;br /&gt;Rosen Movement videos  (with Theresa Garcia, a great instructor and teacher; Marion Rosen is also participating in the class, sitting on a chair):&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=oKkBUfblww4"&gt;http://www.youtube.com/watch?v=oKkBUfblww4&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=jkZP1beeFHE"&gt;http://www.youtube.com/watch?v=jkZP1beeFHE&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=H540bw1ERBU"&gt;http://www.youtube.com/watch?v=H540bw1ERBU&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=U108U3wVgyY"&gt;http://www.youtube.com/watch?v=U108U3wVgyY&lt;/a&gt;&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-1673463492576771461?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/1673463492576771461/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/02/talk-on-rosenmetoden-in-stockholm.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/1673463492576771461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/1673463492576771461'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/02/talk-on-rosenmetoden-in-stockholm.html' title='Talk on Rosenmetoden in Stockholm'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-4790160748395400889</id><published>2010-01-19T13:21:00.000-08:00</published><updated>2010-01-19T13:21:20.354-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Smalltalk'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Twitter and refactoring (totally unrelated!)</title><content type='html'>I am now on &lt;a href="http://twitter.com/divineprog"&gt;Twitter&lt;/a&gt; @divineprog - but don't expect frequent updates, I am not the Twitter type really ;-) But perhaps I will grow fond of it once I learn how to use the Twitter infrastructure.&lt;br /&gt;&lt;br /&gt;A couple of days ago, when renaming a bunch of methods in Eclipse using the refactoring function, it struck me, why not make changing the name of something do an automatic refactoring by default? It seems reasoable that if I change the name of en existing object, I would like everyone using the name of that object to update their references, right? It would make sense to ditch source text files and go all the way and manage the source code in an presistent in-memory database (I guess Eclipse maintains some kind of database-like view of the source code). Smalltalk has of course had this since the 70:ies ;-) &lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-4790160748395400889?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/4790160748395400889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/01/twitter-and-refactoring-totally.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/4790160748395400889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/4790160748395400889'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/01/twitter-and-refactoring-totally.html' title='Twitter and refactoring (totally unrelated!)'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-1622582540102165739</id><published>2010-01-06T04:07:00.000-08:00</published><updated>2010-01-06T04:07:04.863-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Happiness'/><title type='text'>Things that make me happy</title><content type='html'>&lt;a href="http://6doi.net/lifestyle/the-true-seven-wonders-of-the-world.html"&gt;Seven true wonders of the world&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=Q3tk2Atn2vE"&gt;Les Negresses Vertes&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=9wVH1kxqT9k"&gt;Jussi Marttinen Mikkeli playing Säkkijärven Polkka&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=V3gp7B8WC4Q"&gt;Ukulele Orchestra of Great Britain&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.43things.com/things/view/97781/identify-100-things-that-make-me-happy-besides-money"&gt;Identify 100 things that make me happy&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-1622582540102165739?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/1622582540102165739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2010/01/things-that-make-me-happy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/1622582540102165739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/1622582540102165739'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2010/01/things-that-make-me-happy.html' title='Things that make me happy'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-9099580000088313089</id><published>2009-12-29T13:28:00.000-08:00</published><updated>2009-12-29T13:33:40.429-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Interactive development with Clojure</title><content type='html'>Here is a very nice video demo that illustrates &lt;a href="http://paulbarry.com/articles/2008/07/11/interactive-development-with-clojure"&gt;interactive servlet development with Clojure&lt;/a&gt;. Same thing could be done on Android using the techniques referred to in the previous post.&lt;br /&gt;&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-9099580000088313089?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/9099580000088313089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/12/interactive-development-with-clojure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/9099580000088313089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/9099580000088313089'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/12/interactive-development-with-clojure.html' title='Interactive development with Clojure'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-1643067698099470746</id><published>2009-12-28T08:39:00.000-08:00</published><updated>2009-12-29T13:32:05.762-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Smalltalk'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Clojure REPL on Android</title><content type='html'>Found this thread where George Jahad explains how he implemented &lt;a href="http://groups.google.com/group/clojure/browse_thread/thread/14725172c626642c?pli=1"&gt;dynamic evaluation of Clojure on Android&lt;/a&gt;. Very cool how he dexed the dexer!&lt;br /&gt;&lt;br /&gt;Interactive development and experimentation using a Read-Eval-Print-Loop is a great feature of dynamic languages. Really nice to see that Clojure attracts attention, it would be sad if Lisp would be forgotten. Lisp is one of the most productive languages I have ever worked with, and actually the first programming languages I was paid to program in.&lt;br /&gt;&lt;br /&gt;Speaking of REPL, the way you can evaluate text in any window in Smalltalk is truly cool - just select an expression and "doit". I take this feature so for granted that I forget that this is not widely known outside the Smalltalk community. It would be nice to see a programming environment on Android that supports such a style of development, and RhinoDroid is one step on the way. I am working on a web based development tool for interactive programming on Android using JavaScript, hope to have that up and running soon.&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-1643067698099470746?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/1643067698099470746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/12/clojure-repl-on-android.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/1643067698099470746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/1643067698099470746'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/12/clojure-repl-on-android.html' title='Clojure REPL on Android'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-2384672656425063018</id><published>2009-12-09T13:07:00.000-08:00</published><updated>2009-12-09T13:07:28.736-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='DSL'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Domain Specific Languages</title><content type='html'>Today, I made a presentation on Domain Specific Languages at the &lt;a href="http://www.msc.se/"&gt;MSC&lt;/a&gt; Office in Stockholm. The slides are here: &lt;a href="http://www.comikit.se/dsl/dsl_talk_20091209/DSLSlides.html"&gt;http://www.comikit.se/dsl/dsl_talk_20091209/DSLSlides.html&lt;/a&gt; Press S to enter slide show mode, use N for next slide and P for previous slide. Or just scroll the document!&lt;br /&gt;&lt;br /&gt;The presentation is written in a Python Slide Show DSL I made for the presentation, here is the source for the slides: &lt;a href="http://www.comikit.se/dsl/dsl_talk_20091209/DSLSlides.py"&gt;http://www.comikit.se/dsl/dsl_talk_20091209/DSLSlides.py&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The source code for the DSL is here: &lt;a href="http://www.comikit.se/dsl/dsl_talk_20091209/SlideShow.py"&gt;http://www.comikit.se/dsl/dsl_talk_20091209/SlideShow.py&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;My next DSL-related project is an interactive Game Development DSL in JavaScript for Android.&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-2384672656425063018?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/2384672656425063018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/12/domain-specific-languages.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/2384672656425063018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/2384672656425063018'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/12/domain-specific-languages.html' title='Domain Specific Languages'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-5175712426378583240</id><published>2009-12-03T04:36:00.000-08:00</published><updated>2010-04-15T12:42:05.750-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Rhino'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='Squeak'/><title type='text'>RhinoDroid - JavaScript for Android</title><content type='html'>RhinoDroid is an experimental JavaScript app that runs on Android. The app contains a tiny HTTP server that accepts PUT requests with JavaScript as content. The app is based on the Mozilla Rhino Engine and the Android port by &lt;a href="http://brice-lambson.blogspot.com/2009/11/android-rhino.html"&gt;Brice Lambson&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Update: RhinoDroid is now called DroidScript. Get it at GitHub: &lt;a href="http://github.com/divineprog/droidscript"&gt;http://github.com/divineprog/droidscript&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Check ut the browser-based editor for DroidScript: &lt;a href="http://droidscript.se/"&gt;http://droidscript.se&lt;/a&gt;&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-5175712426378583240?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/5175712426378583240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/12/rhinodroid-javascript-for-android.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/5175712426378583240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/5175712426378583240'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/12/rhinodroid-javascript-for-android.html' title='RhinoDroid - JavaScript for Android'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-2487348343154217293</id><published>2009-11-30T14:25:00.000-08:00</published><updated>2009-11-30T14:25:25.732-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='GTUG'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='Squeak'/><title type='text'>Interactive JavaScript on Android</title><content type='html'>I now have working version of a remote JavaScript scripting app running on Android. The app runs a HTTP server that accepts incoming PUT requests with JavaScript code as content. The code is evaluated on the Android, and the result is sent back to the client. Also have a workspace in Squeak/Pharo that I use to evaluate JavaScript on the Android. It is kind of neat to be able to interactively create views, buttons and so on. Will demo this on the upcoming &lt;a href="http://sites.google.com/site/stockholmgtug/agenda_mote_3_12"&gt;GTUG meeting&lt;/a&gt; in Stockholm on Thursday December 3.&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-2487348343154217293?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/2487348343154217293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/11/interactive-javascript-on-android.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/2487348343154217293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/2487348343154217293'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/11/interactive-javascript-on-android.html' title='Interactive JavaScript on Android'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-8518920437496726025</id><published>2009-11-20T15:02:00.000-08:00</published><updated>2009-11-21T01:25:21.491-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>JavaScript (Rhino) on Android</title><content type='html'>Finally I have found a great dynamic language for writing Android apps - Rhino, a JavaScript implementation in Java. Rhino can run in interpreted mode, which makes it suitable for running on Dalvik (since on-the-fly byte code generation on Dalvik isn't implemented by dynamic languages, yet).&lt;br /&gt;&lt;br /&gt;I used the work by &lt;a href="http://brice-lambson.blogspot.com/2009/11/android-rhino.html"&gt;Brice Lambson&lt;/a&gt; as a starting point. He has created a version of Rhino for the &lt;a href="http://code.google.com/p/android-scripting/"&gt;Android Scripting Environment (ASE)&lt;/a&gt;. With &lt;a href="http://www.damonkohler.com/2009/11/ase-r14-released.html"&gt;the new release of the ASE&lt;/a&gt; you can now write scripts using JavaScript.&lt;br /&gt;&lt;br /&gt;Since I want to write applications for Android in a dynamic language, I decided to experiment with embedding Rhino in an Android app. I created a new Android Java project, grabbed the Rhino jar-file from the ASE web site and dropped it in the libs directory. By browsing &lt;a href="http://www.mozilla.org/rhino/tutorial.html"&gt;the documentation&lt;/a&gt; at the &lt;a href="https://developer.mozilla.org/en/Rhino"&gt;Rhino web site&lt;/a&gt;, it was quite straightforward to write a working demo.&lt;br /&gt;&lt;br /&gt;Here is the code:&lt;br /&gt;&lt;br /&gt;package miki.jsapp;&lt;br /&gt;&lt;br /&gt;import android.app.Activity;&lt;br /&gt;import android.os.Bundle;&lt;br /&gt;&lt;br /&gt;import org.mozilla.javascript.*;&lt;br /&gt;&lt;br /&gt;public class JSApp extends Activity&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Override&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void onCreate(Bundle savedInstanceState)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; super.onCreate(savedInstanceState);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; doit(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "var widgets = Packages.android.widget;\n" +&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "var view = new widgets.TextView(TheActivity);\n" +&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "TheActivity.setContentView(view);\n" +&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "var text = 'Hello Android!\\nThis is JavaScript in action!';\n" +&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "view.append(text);"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void doit(String code)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Create an execution environment.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Context cx = Context.enter();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Turn compilation off.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cx.setOptimizationLevel(-1);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Initialize a variable scope with bindnings for&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // standard objects (Object, Function, etc.)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Scriptable scope = cx.initStandardObjects();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Set a global variable that holds the activity instance.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScriptableObject.putProperty(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; scope, "TheActivity", Context.javaToJS(this, scope));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Evaluate the script.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cx.evaluateString(scope, code, "doit:", 1, null); &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Context.exit();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;}&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-8518920437496726025?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/8518920437496726025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/11/javascript-rhino-on-android.html#comment-form' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8518920437496726025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8518920437496726025'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/11/javascript-rhino-on-android.html' title='JavaScript (Rhino) on Android'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-3192986999394520826</id><published>2009-11-05T07:56:00.000-08:00</published><updated>2009-11-05T07:56:24.015-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JRuby'/><category scheme='http://www.blogger.com/atom/ns#' term='Dynamic languages'/><category scheme='http://www.blogger.com/atom/ns#' term='DSL'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Various links</title><content type='html'>Discussion of concurrency and message passing in Erlang and Clojure:&lt;br /&gt;&lt;a href="http://www.tbray.org/ongoing/When/200x/2009/10/26/Messaging"&gt;http://www.tbray.org/ongoing/When/200x/2009/10/26/Messaging&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;DSL links:&lt;br /&gt;&lt;a href="http://dsl09.blogspot.com/"&gt;http://dsl09.blogspot.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://lambda-the-ultimate.org/node/3601"&gt;http://lambda-the-ultimate.org/node/3601&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Atomic install:&lt;br /&gt;&lt;a href="http://gbracha.blogspot.com/2009/10/atomic-install.html"&gt;http://gbracha.blogspot.com/2009/10/atomic-install.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Evaluate JRuby from Java:&lt;br /&gt;&lt;a href="http://jruby-embed.kenai.com/docs"&gt;http://jruby-embed.kenai.com/docs&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Discussion of characteristics of dynamic languages:&lt;br /&gt;&lt;a href="http://lambda-the-ultimate.org/node/1012"&gt;http://lambda-the-ultimate.org/node/1012&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-3192986999394520826?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/3192986999394520826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/11/various-links.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3192986999394520826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3192986999394520826'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/11/various-links.html' title='Various links'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-6978067461346190250</id><published>2009-11-04T07:28:00.000-08:00</published><updated>2009-11-04T07:39:50.519-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>PyConcordion - Writing Concordion tests in Python</title><content type='html'>&lt;a href="http://www.concordion.org/"&gt;Concordion&lt;/a&gt; is an open source test framework that encourages writing tests in a specification driven style. A key aspect is that tests are integrated into the textual specification of the system. This makes it possible to write requirements and tests simultaneously, and from a maintainability point of view, it is a great advantage to have requirements and tests tightly integrated.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/pyconcordion/"&gt;&lt;i&gt;PyConcordion&lt;/i&gt;&lt;/a&gt; allows you to write tests in &lt;a href="http://python.org/"&gt;Python&lt;/a&gt;, rather than Java (a very nice feature from the perspective of this blog!).&lt;br /&gt;&lt;br /&gt;Each PyConcordion test has two parts, and HTML-file and a Python file. Specifications and declarative definitions of the tests are written in HTML. The scripting parts of the test that connects to the system being tested and implements services for the declarative tests are written in Python. Note that the Python code can be written in a declarative DSL-driven fashion,&amp;nbsp;&lt;a href="http://www.concordion.org/Technique.html"&gt;see the discussion on this page&lt;/a&gt;. The principle is to write a specification of a scenario, rather than coding a test script.&lt;br /&gt;&lt;br /&gt;To try out PyConcordion, I downloaded PyConcordion and made an example based on &lt;a href="http://code.google.com/p/pyconcordion/wiki/TwoMinutesExample"&gt;this tutorial&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The example defined a very simplictic bank account object, called Account. Here goes the HTML-part of the specification.&lt;br /&gt;&lt;br /&gt;File: &lt;b&gt;Account.html&lt;/b&gt; &lt;br /&gt;&amp;lt;html xmlns:concordion="http://www.concordion.org/2007/concordion"&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;h1&amp;gt;Account&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;h2&amp;gt;Overview&amp;lt;/h2&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;The Account object supports the following operations:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ul&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;li&amp;gt;Ask for the account balance&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;li&amp;gt;Deposit an amount&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;li&amp;gt;Withdraw an amount&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ul&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;h2&amp;gt;Examples&amp;lt;/h2&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; A new account object has a balance of&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;span concordion:assertEquals="getBalance()"&amp;gt;0&amp;lt;/span&amp;gt;.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If I open a new account and deposit&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;span concordion:execute="deposit(#TEXT)"&amp;gt;1200&amp;lt;/span&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; the balance is&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;span concordion:assertEquals="getBalance()"&amp;gt;1200&amp;lt;/span&amp;gt;.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If I deposit another &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;span concordion:execute="deposit(#TEXT)"&amp;gt;600&amp;lt;/span&amp;gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; the new balance is &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;span concordion:assertEquals="getBalance()"&amp;gt;1800&amp;lt;/span&amp;gt;.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If I withdraw &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;span concordion:execute="withdraw(#TEXT)"&amp;gt;100&amp;lt;/span&amp;gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; the balance is &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;span concordion:assertEquals="getBalance()"&amp;gt;1700&amp;lt;/span&amp;gt;.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/p&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;And here is the Python code that defined the Account class.&lt;br /&gt;&lt;br /&gt;File: &lt;b&gt;AccountTest.py &lt;/b&gt;&lt;br /&gt;#! /usr/bin/python&lt;br /&gt;&lt;br /&gt;class AccountTest:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def __init__(self):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.balance = 0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def getBalance(self):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return str(self.balance)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def deposit(self, amount):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.balance = self.balance + int(amount)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def withdraw(self, amount):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.balance = self.balance - int(amount)&lt;br /&gt;&lt;br /&gt;To run the test, go to the folder that contains these two files, and run the command:&lt;br /&gt;concordion_folder_runner ./&lt;br /&gt;&lt;br /&gt;There are straightforward instructions on the &lt;a href="http://code.google.com/p/pyconcordion/"&gt;PyConcordion web site&lt;/a&gt; on how to install the system under Linux.&lt;br /&gt;&lt;br /&gt;When writing Python methods, remember to use &lt;b&gt;self&lt;/b&gt; rather than &lt;b&gt;this&lt;/b&gt;, especially if you are new to Python, and come from languages like C++, C#, or Java rather than Python. (Actually you can name the self-parameter anything, as it is explictly declared, but the convention is to use self.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-6978067461346190250?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/6978067461346190250/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/11/pyconcordion-writing-concordion-tests.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/6978067461346190250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/6978067461346190250'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/11/pyconcordion-writing-concordion-tests.html' title='PyConcordion - Writing Concordion tests in Python'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-4578058124999242923</id><published>2009-11-01T10:27:00.000-08:00</published><updated>2010-04-05T10:17:40.503-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android development in Scheme - How to build Kawa for Android SDK 2.0</title><content type='html'>If you are into languages like Lisp and Scheme, you will appreciate &lt;a href="http://www.gnu.org/software/kawa/"&gt;Kawa&lt;/a&gt;, a Scheme implementation written in Java. Thanks to the work of &lt;a href="http://per.bothner.com/"&gt;Per Bothner&lt;/a&gt;, Kawa is available for Android.&lt;br /&gt;&lt;br /&gt;The following is a how-to for installing Kawa for Android SDK 2.0 and getting started to write Scheme programs for Android. The how-to is based on a &lt;a href="http://per.bothner.com/blog/2009/AndroidHelloScheme/"&gt;blog entry by Per Bothner&lt;/a&gt;. Note that you need to install Android SDK 2.0 before you proceed. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;First build Kawa:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1) Go to the directory where you want Kawa to be installed. On my machine, this is:&lt;br /&gt;cd /home/miki/android&lt;br /&gt;&lt;br /&gt;Then download the sources from the Kava svn-repository with the command:&lt;br /&gt;svn -q checkout svn://sourceware.org/svn/kawa/trunk kawa&lt;br /&gt;&lt;br /&gt;2) Configure and build Kawa for Android. Go to the kawa directory and run configure, then make. You need to supply the location of the android.jar file in the Android 2.0 SDK. On my machine, the command sequence is:&lt;br /&gt;cd /home/miki/android/kawa&lt;br /&gt;./configure --with-android=/home/miki/android/android-sdk-linux/platforms/android-2.0/android.jar --disable-xquery&lt;br /&gt;make&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Next, create a Scheme project:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;3) We will start by creating a standard Android Java project, and then modify it.&lt;br /&gt;This is how you create a project template:&lt;br /&gt;&lt;br /&gt;android create project \&lt;br /&gt;--target 1 \&lt;br /&gt;--name HelloScheme \&lt;br /&gt;--path /home/miki/android/projects/HelloScheme \&lt;br /&gt;--activity HelloScheme \&lt;br /&gt;--package miki.helloscheme&lt;br /&gt;&lt;br /&gt;4) Now, we will modify the project so that it can compile Scheme files. First of all, delete the generated Java source file (I'm using the full path in these examples, for clarity):&lt;br /&gt;rm /home/miki/android/projects/HelloScheme/src/miki/helloscheme/HelloScheme.java&lt;br /&gt;&lt;br /&gt;Copy the Kawa jar-file to your project's lib-folder (this is where external libs are stored; alternatively you can create a soft link to the kawa-1.9.90.jar):&lt;br /&gt;cp /home/miki/android/kawa/kawa-1.9.90.jar /home/miki/android/projects/HelloScheme/libs/kawa.jar&lt;br /&gt;&lt;br /&gt;Then replace /home/miki/android/projects/HelloScheme/build.xml with this &lt;a href="http://www.comikit.se/android/kawa/build.xml"&gt;customised version of build.xml&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The project is now configured to build Scheme programs.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Finally, write the Scheme version of Hello World:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;5) Open a text editor and create the file: /home/miki/android/projects/HelloScheme/src/miki/helloscheme/HelloScheme.scm&lt;br /&gt;&lt;br /&gt;Enter the following code into the file:&lt;br /&gt;&lt;br /&gt;(module-extends android.app.Activity)&lt;br /&gt;(module-name miki.helloscheme.HelloScheme)&lt;br /&gt;(define (onCreate (savedInstanceState :: android.os.Bundle)) :: void&lt;br /&gt;&amp;nbsp;&amp;nbsp; (invoke-special android.app.Activity (this) 'onCreate savedInstanceState)&lt;br /&gt;&amp;nbsp;&amp;nbsp; (let ((textview :: android.widget.TextView (make android.widget.TextView (this))))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (textview:setText "Hello, Android from Kawa Scheme!")&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((this):setContentView textview)))&lt;br /&gt;&lt;br /&gt;There is a more compact version of this program on Per Bothner's blog, but I didn't get it to work at the time of writing this.&lt;br /&gt;&lt;br /&gt;Build and install on the emulator with:&lt;br /&gt;ant install&lt;br /&gt;&lt;br /&gt;Note that eval does not seem to be supported yet. Hopefully the ability to dynamically compile to Dalvik bytecode will be included into Kawa in the future.&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-4578058124999242923?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/4578058124999242923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/11/android-development-in-scheme-how-to.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/4578058124999242923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/4578058124999242923'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/11/android-development-in-scheme-how-to.html' title='Android development in Scheme - How to build Kawa for Android SDK 2.0'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-3134085183658828097</id><published>2009-11-01T05:54:00.000-08:00</published><updated>2009-11-01T08:39:55.019-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>How to install Android SDK 2.0</title><content type='html'>The following is the procedure I used to install the Android SDK 2.0. It applies to Mac OS X and Linux (in my case Ubuntu). Note that Java SDK 1.6 (1.5 should also work?) must to be installed, before installing the Android SDK.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;First download the SDK (SDK = Software Development Kit):&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1) Download the SDK for your platform at: &lt;a href="http://developer.android.com/sdk/"&gt;http://developer.android.com/sdk/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2) Unzip the SDK and move it to the directory where you want it installed. On my Ubuntu machine, I installed it in my home folder:&lt;br /&gt;/home/miki&lt;my-home-folder&gt;/android/android-sdk-linux/&lt;br /&gt;&lt;br /&gt;3) Add the SDK tools directory to the path by adding the following line to .bashrc. &lt;full-path-to-where-you-installed-the-sdk&gt;On my machine, it is:&lt;br /&gt;export PATH=${PATH}:/home/miki/android/android-sdk-linux/tools&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Next download additional SDK components using the Android SDK and AVD Manager:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;4) Open the terminal and start the Android SDK and AVD Manager with the command:&lt;br /&gt;android&lt;br /&gt;&lt;br /&gt;5) Now a window opens where you can configure the SDK and create virtual devices. I had to force the manager to use http: rather that https: by selecting "Force..." under Settings, to be able to download the SDK components.&lt;br /&gt;&lt;br /&gt;6) Select and install SDK packages under Available Packages. I installed:&lt;br /&gt;&lt;/full-path-to-where-you-installed-the-sdk&gt;&lt;/my-home-folder&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;SDK Platform Android 2.0, API 5, revision 1&lt;/li&gt;&lt;li&gt;Google APIs by Google Inc., Android 2.0, API 5, revision 1&lt;/li&gt;&lt;/ul&gt;Then exit the Manager.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Now we need to create an AVD (AVD = Android Virtual Device):&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;7) I find this to be most convenient to do using the command line, rather than the Manager. This creates a virtual device called myavd:&lt;br /&gt;android create avd -t 2 -n myavd&lt;br /&gt;&lt;br /&gt;8) Start the device on the emulator with this command:&lt;br /&gt;emulator -avd myavd &amp;amp;&lt;br /&gt;&lt;br /&gt;Note that it takes a while for the device to boot (one minute or so). If successful you are presented with the Android desktop (or is it called phonetop? ;-).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Finally, create the Hello World application:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;9) Create a template project with this command:&lt;br /&gt;android create project \&lt;br /&gt;--target 1 \&lt;br /&gt;--name HelloWord \&lt;br /&gt;--path /home/miki/android/projects/HelloWorld \&lt;br /&gt;--activity HelloWorld \&lt;br /&gt;--package miki.hello&lt;br /&gt;&lt;br /&gt;The --target switch specifies the id of the target platform. This command lists available targets:&lt;br /&gt;android list targets&lt;br /&gt;&lt;br /&gt;The reason we specify target 2 for the virtual device and target 1 for the project is that we want to emulate the most advanced device, but we want the project to run on all devices (this is, at least, how I understand it).&lt;br /&gt;&lt;br /&gt;10) The template project created actually is a compilable and runnable application.&lt;br /&gt;Go to the project folder, in my case:&lt;br /&gt;cd /home/miki/android/projects/HelloWorld&lt;br /&gt;&lt;br /&gt;Then compile and install the application on the emulator with the command:&lt;br /&gt;ant install&lt;br /&gt;&lt;br /&gt;Switch to the emulator window, click the tab at the bottom of the screen, and then click on your application, called HelloWorld.&lt;br /&gt;&lt;br /&gt;When you have recovered from the avesome experience of running your app, lets change the text it displays to something more appropriate.&lt;br /&gt;&lt;br /&gt;Go back to your project, open the file res/layout/main.xml in a text editor, and change the content of the android:text attribute (this is the text shown in the window of the application), to something you feel you want to tell the world, for example:&lt;br /&gt;android:text="Oh I wish I could program this is Scheme!"&lt;br /&gt;&lt;br /&gt;That is it! Now you are ready to explore the world of Android development! Google's site &lt;a href="http://developer.android.com/"&gt;http://developer.android.com&lt;/a&gt; has lots of useful information on the Java API, and there are already a number of other sites on the web devoted to Android development.&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-3134085183658828097?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/3134085183658828097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/11/how-to-install-android-sdk-20.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3134085183658828097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3134085183658828097'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/11/how-to-install-android-sdk-20.html' title='How to install Android SDK 2.0'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-5748523707995961015</id><published>2009-10-31T07:05:00.000-07:00</published><updated>2009-10-31T07:08:32.518-07:00</updated><title type='text'>Taking the Red Pill</title><content type='html'>&lt;a href="http://www.prisonplanet.com/fall-of-the-republic-millions-of-people-worldwide-take-the-red-pill.html" target="_blank"&gt;http://www.prisonplanet.com/&lt;wbr&gt;fall-of-the-republic-millions-&lt;wbr&gt;of-people-worldwide-take-the-&lt;wbr&gt;red-pill.html&lt;/a&gt;&lt;div menubottom="0" menuright="0" menutop="0" menuleft="0" activeid="-1" expanded="0" style="display: none;" id="divCleekiAttrib"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-5748523707995961015?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/5748523707995961015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/10/taking-red-pill.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/5748523707995961015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/5748523707995961015'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/10/taking-red-pill.html' title='Taking the Red Pill'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-3709659974369517846</id><published>2009-10-30T02:45:00.001-07:00</published><updated>2009-10-30T03:35:17.510-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Kawa'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Why Android will be a big hit</title><content type='html'>The more I research the Android market and look into Android technologies, the more convinced I am that Android will be the next major computing platform. I view the situation as somewhat similar to 1984, when we had Mac and PC. Mac was a work of art, but a bit closed, and PC was open but rough, and MS-DOS and Windows 1.0 were primitive.&lt;br /&gt;&lt;br /&gt;Today we have iPhone, exclusive and masterfully designed, but closed in several ways (much more closed than the Mac ever was). And we have Android, open and available for everyone, with lots of new devices on the way, in different formats and price categories. The big difference compared to 1984 is that Android is not MS-DOS. It is the complete opposite; carefully designed, fun, and open source. People who speculate when Linux will take over the desktop may now have the answer - Android Linux will take over the mobile device market.&lt;br /&gt;&lt;br /&gt;Android will be the platform of choice, because it is open for developers. The &lt;a href="http://developer.android.com/sdk/"&gt;SDK&lt;/a&gt; is free, and serveral new languages and tools are on their way. &lt;a href="http://code.google.com/p/simple/"&gt;Simple&lt;/a&gt; is a Basic for the Android, developed by Google. The languge seems similar to Visual Basic, and this of course sucks, but I can see the logic here. There are many many Visual Basic programmers, and attracting them to Android is a smart move. There will likely be lots of apps developed, both in-house development at companies and hobby projects. To hobbyists, publising an application on &lt;a href="http://www.android.com/market/"&gt;Android Market&lt;/a&gt;, might be less of a hazzle compared to hosting and providing support for a web app. Plus, some apps and games a better implemeted as native programs.&lt;br /&gt;&lt;br /&gt;Languages like Python, Lua and Perl are running on the &lt;a href="http://code.google.com/p/android-scripting/"&gt;Android Scripting Environment&lt;/a&gt;. This is a very promising and exiting opportunity for developing mini-applications using small script hacks. There are lots of other efforts going on to port popular languages to Android. &lt;a href="http://per.bothner.com/blog/2009/AndroidHelloScheme/"&gt;Kawa Scheme&lt;/a&gt; seems to be a nice choise if you (like me) are fond of the Lisp-family of languages. &lt;a href="http://www.scala-lang.org/search/node/android"&gt;Scala&lt;/a&gt; is also &lt;a href="http://code.google.com/p/scala-android/"&gt;available on Android&lt;/a&gt; (some people say Scala is the next big language on the Java platform). Here is a &lt;a href="http://chneukirchen.org/blog/archive/2009/04/programming-for-android-with-scala.html"&gt;tutorial&lt;/a&gt;. Another interesting initiative is &lt;a href="http://googleresearch.blogspot.com/2009/07/app-inventor-for-android.html"&gt;App Inventor&lt;/a&gt;, a visual programming language for Android &lt;a href="http://googleresearch.blogspot.com/2009/08/under-hood-of-app-inventor-for-android.html"&gt;developed in Kawa Scheme&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Best of all, my collegue Göran Krampe is looking into porting the &lt;a href="http://en.wikipedia.org/wiki/Smalltalk"&gt;Smalltalk&lt;/a&gt; dialect &lt;a href="http://www.squeak.org/"&gt;Squeak&lt;/a&gt; to Android ;-)&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class="on down" style="display: block;" id="formatbar_CreateLink" title="Link" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;img src="http://www.blogger.com/img/blank.gif" alt="Link" class="gl_link" border="0" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-3709659974369517846?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/3709659974369517846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/10/why-android-will-be-big-hit.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3709659974369517846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3709659974369517846'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/10/why-android-will-be-big-hit.html' title='Why Android will be a big hit'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-4935786449267263111</id><published>2009-10-19T07:23:00.001-07:00</published><updated>2009-10-21T02:08:39.257-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MagicWords'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='ComiKit'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>My first Android project</title><content type='html'>I have stared to develop on the Android and my the first project is now on GitHub:&lt;br /&gt;&lt;a href="http://github.com/mikaelkindborg/ComiCard"&gt;http://github.com/mikaelkindborg/ComiCard&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is the starting point of what might become something similar to HyperCard. It would be really cool to have an easy-to-use autoring tool on Android. I hope &lt;a href="http://squeak.org/"&gt;Squeak&lt;/a&gt; will be ported to Android, then &lt;a href="http://comikit.se/"&gt;MagicWords&lt;/a&gt; would be easy to port.&lt;br /&gt;&lt;br /&gt;Meanwhile I experiment with making Java-programming more enjoyable by exploring the design of an internal DSL based on declarative functional Lisp-like style.&lt;br /&gt;&lt;div menubottom="0" menuright="0" menutop="0" menuleft="0" activeid="-1" expanded="0" style="display: none;" id="divCleekiAttrib"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-4935786449267263111?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/4935786449267263111/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/10/my-first-android-project.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/4935786449267263111'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/4935786449267263111'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/10/my-first-android-project.html' title='My first Android project'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-1076800197125133745</id><published>2009-10-06T12:28:00.001-07:00</published><updated>2009-10-21T02:08:29.220-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><title type='text'>PhoneGap</title><content type='html'>Just found &lt;a href="http://phonegap.com/"&gt;PhoneGap&lt;/a&gt;, a JavaScript library for programming Android and iPhone apps in JavaScript. Looks really cool! I'm working on a book about JavaScript game development for children and teenagers (and curious grown-ups!), and PhoneGap could be a good library to use for games on Android and iPhone.&lt;br /&gt;&lt;div menubottom="0" menuright="0" menutop="0" menuleft="0" activeid="-1" expanded="0" style="display: none;" id="divCleekiAttrib"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-1076800197125133745?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/1076800197125133745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/10/phonegap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/1076800197125133745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/1076800197125133745'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/10/phonegap.html' title='PhoneGap'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-8484740633757049556</id><published>2009-10-06T12:00:00.000-07:00</published><updated>2009-10-21T02:08:18.057-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Smalltalk'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><title type='text'>Gwt Smalltalk and Clamato</title><content type='html'>&lt;a href="http://gwtsmalltalk.wordpress.com/"&gt;Gwt Smalltalk&lt;/a&gt; runs in the web browser and interacts with the Google Wave protocol. It is a great thing that Smalltalk is avaliable in the browser! &lt;a href="http://clamato.net/"&gt;Clamato&lt;/a&gt; is another Smalltalk that runs in a web browser. And here is an article that discusses &lt;a href="http://www.infoq.com/news/2009/09/javascript-compilation-target"&gt;languages that compile to JavaScript&lt;/a&gt;.&lt;div menubottom="0" menuright="0" menutop="0" menuleft="0" activeid="-1" expanded="0" style="display: none;" id="divCleekiAttrib"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-8484740633757049556?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/8484740633757049556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/10/gwt-smalltalk-and-clamato.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8484740633757049556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8484740633757049556'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/10/gwt-smalltalk-and-clamato.html' title='Gwt Smalltalk and Clamato'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-8767588652987760838</id><published>2009-09-30T01:55:00.000-07:00</published><updated>2009-10-21T02:08:05.530-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><title type='text'>The Duct Tape Programmer</title><content type='html'>Just read &lt;a href="http://www.joelonsoftware.com/items/2009/09/23.html" target="_blank"&gt;this article&lt;/a&gt; from Joel Spolsky.&lt;br /&gt;&lt;br /&gt;Memorable quote:&lt;br /&gt;"Duct tape programmers don’t give a shit what you think about them. They stick to simple basic and easy to use tools and use the extra brainpower that these tools leave them to write more useful features for their customers."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-8767588652987760838?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/8767588652987760838/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/duct-tape-programmer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8767588652987760838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8767588652987760838'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/duct-tape-programmer.html' title='The Duct Tape Programmer'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-6643995320127189854</id><published>2009-09-30T01:30:00.000-07:00</published><updated>2009-10-21T02:07:44.695-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Scheme on Android</title><content type='html'>Using &lt;a href="http://www.gnu.org/software/kawa/" target="_blank"&gt;Kawa&lt;/a&gt; you can author Android apps in &lt;a href="http://schemers.org/" target="_blank"&gt;Scheme&lt;/a&gt;. This looks promising:&lt;pre&gt;(require 'android-defs)&lt;br /&gt;(activity hello&lt;br /&gt; (on-create-view&lt;br /&gt;  (let ((view (android.widget.TextView (this))))&lt;br /&gt;    (view:setText "Hello World!")&lt;br /&gt;    view)))&lt;/pre&gt;I found this example at &lt;a href="http://per.bothner.com/blog/2009/AndroidHelloScheme/" target="_blank"&gt;Per Bothner's blog&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-6643995320127189854?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/6643995320127189854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/scheme-on-android.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/6643995320127189854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/6643995320127189854'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/scheme-on-android.html' title='Scheme on Android'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-8339891698639761984</id><published>2009-09-18T11:10:00.000-07:00</published><updated>2009-10-21T02:07:24.976-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><title type='text'>Ruby hash map arguments</title><content type='html'>Ruby is a language with divine qualities, and &lt;a href="http://en.wikipedia.org/wiki/Why_the_lucky_stiff" target="_blank"&gt;why the lucky stiff&lt;/a&gt; has shown that Ruby programming is a beatiful art.&lt;br /&gt;&lt;br /&gt;In Ruby you can pass a hash map to a method using a simplified syntax. The cool GUI-framework &lt;a href="http://shoes.heroku.com/" target="_blank"&gt;Shoes&lt;/a&gt; is an example of how this programming technique can be used.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Plain parameter passing&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;def foo(a, b)&lt;br /&gt; puts a, b&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;foo(1, 2)&lt;/pre&gt;&lt;b&gt;Variable number of arguments&lt;/b&gt;&lt;br /&gt;Here the arguments are passed as an array:&lt;br /&gt;&lt;pre&gt;def foo(*args)&lt;br /&gt; puts args[0], args[1]&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;foo(1, 2)&lt;/pre&gt;&lt;b&gt;A mix of the above&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;def foo(a, b, *args)&lt;br /&gt; puts a, b, args[0], args[1]&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;foo(1, 2, 3, 4)&lt;/pre&gt;&lt;b&gt;Hash map arguments&lt;/b&gt;&lt;br /&gt;A hash can be passed as parameter (this is somewhat similar to a variable length parameter list, note that the * is not used):&lt;br /&gt;&lt;pre&gt;def foo(values)&lt;br /&gt; puts values[:a], values[:b]&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;foo(:a =&gt; 1, :b =&gt; 2)&lt;/pre&gt;This also works:&lt;br /&gt;&lt;pre&gt;def foo(a, b, values)&lt;br /&gt; puts a, b, values[:a], values[:b]&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;foo(1, 2,  :a =&gt; 1, :b =&gt; 2)&lt;/pre&gt;However, this does NOT work (the hash map parameter must be the last one):&lt;br /&gt;&lt;pre&gt;def foo(values, a, b)&lt;br /&gt; puts a, b, values[:a], values[:b]&lt;br /&gt;end&lt;/pre&gt;But you can always pass the hash map as normal parameter using the proper syntax:&lt;br /&gt;&lt;pre&gt;def foo(values, a, b)&lt;br /&gt; puts a, b, values[:a], values[:b]&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;foo({:a =&gt; 1, :b =&gt; 2}, 1, 2)&lt;/pre&gt;Also check out the remarkable book &lt;a href="http://cloud.github.com/downloads/shoes/shoes/nks.pdf" target="_blank"&gt;Nobody Knows Shoes&lt;/a&gt; by &lt;a href="http://en.wikipedia.org/wiki/Why_the_lucky_stiff" target="_blank"&gt;why the lucky stiff&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-8339891698639761984?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/8339891698639761984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/ruby-hash-map-arguments.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8339891698639761984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/8339891698639761984'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/ruby-hash-map-arguments.html' title='Ruby hash map arguments'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-3745002989087577017</id><published>2009-09-16T14:09:00.000-07:00</published><updated>2009-10-21T02:07:15.222-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><title type='text'>Tiny Erlang web server - parallel version</title><content type='html'>Here is a version of the tiny web server that spawns a new process for each request. This is where &lt;a href="http://www.erlang.org/" target="_blank"&gt;Erlang&lt;/a&gt; shines. Processes are very lightweight and efficient in Erlang.&lt;br /&gt;&lt;pre&gt;% Filename: mserver3.erl&lt;br /&gt;% Tiny webserver that restarts on error.&lt;br /&gt;% Requests are processed in parallel.&lt;br /&gt;% Author: mikael.kindborg@gmail.com&lt;br /&gt;% Date: September 2008&lt;br /&gt;&lt;br /&gt;-module(mserver3).&lt;br /&gt;-export([start/0, stop/0, supervisor/0, start_server/0, server/1, process_client_request/2]).&lt;br /&gt;&lt;br /&gt;% How to benchmark:&lt;br /&gt;% apache benchmark ab -n 100 -c 10 http://1.1.1.84:4042/hello.html&lt;br /&gt;&lt;br /&gt;start() -&gt;&lt;br /&gt;   spawn(?MODULE, supervisor, []).&lt;br /&gt;  &lt;br /&gt;supervisor() -&gt;&lt;br /&gt;   io:format("Starting server.~n"),&lt;br /&gt;   Pid = spawn(?MODULE, start_server, []),&lt;br /&gt;   link(Pid),&lt;br /&gt;   process_flag(trap_exit, true),&lt;br /&gt;   receive&lt;br /&gt;       {'EXIT', Pid, normal} -&gt;&lt;br /&gt;           io:format("Server exited normally.~n");&lt;br /&gt;       {'EXIT', Pid, stopped} -&gt;&lt;br /&gt;           io:format("Server stopped.~n");&lt;br /&gt;       {'EXIT', Pid, Reason} -&gt;&lt;br /&gt;           io:format("Server exited with code: ~w~n", [Reason]),&lt;br /&gt;           timer:sleep(1000),&lt;br /&gt;           supervisor();&lt;br /&gt;       stop -&gt;&lt;br /&gt;           io:format("Stoppning supervisor.~n");&lt;br /&gt;       Unknown -&gt;&lt;br /&gt;           io:format("Supervisor got an unknown message: ~w~n", [Unknown]),&lt;br /&gt;           supervisor()&lt;br /&gt;   end.&lt;br /&gt;&lt;br /&gt;start_server() -&gt;&lt;br /&gt;   {ok, ServerSocket} = gen_tcp:listen(&lt;br /&gt;       4042, [binary, {packet, 0}, {active, false}, {reuseaddr, true}]),&lt;br /&gt;   on_exit(&lt;br /&gt;       self(),&lt;br /&gt;       fun (Why) -&gt;&lt;br /&gt;           gen_tcp:close(ServerSocket),&lt;br /&gt;           io:format("Exiting server, closing ServerSocket, Why = ~w~n", [Why])&lt;br /&gt;       end),&lt;br /&gt;   server(ServerSocket).&lt;br /&gt;&lt;br /&gt;stop() -&gt;&lt;br /&gt;   ServerAddress = "localhost",&lt;br /&gt;   {ok, Socket} = gen_tcp:connect(ServerAddress, 4042, [binary, {packet, 0}]),&lt;br /&gt;   ok = gen_tcp:send(Socket, &lt;&lt;"stop"&gt;&gt;),&lt;br /&gt;   ok = gen_tcp:close(Socket).&lt;br /&gt;&lt;br /&gt;server(ServerSocket) -&gt;&lt;br /&gt;   {ok, Socket} = gen_tcp:accept(ServerSocket),&lt;br /&gt;   spawn(?MODULE, process_client_request, [Socket, self()]),&lt;br /&gt;   server(ServerSocket).&lt;br /&gt;&lt;br /&gt;process_client_request(Socket, ServerPid) -&gt;&lt;br /&gt;   on_exit(&lt;br /&gt;       self(),&lt;br /&gt;       fun (Why) -&gt;&lt;br /&gt;           gen_tcp:close(Socket)&lt;br /&gt;           % io:format("Exiting client request process, closing Socket, Why = ~w~n", [Why])&lt;br /&gt;       end),&lt;br /&gt;   {ok, BinaryData} = gen_tcp:recv(Socket, 0),   &lt;br /&gt;   case BinaryData of&lt;br /&gt;       &lt;&lt;"stop"&gt;&gt; -&gt;&lt;br /&gt;           exit(ServerPid, stopped),&lt;br /&gt;           io:format("Server stopped~n"),&lt;br /&gt;           ok;&lt;br /&gt;       &lt;&lt;"GET /stop", _/binary&gt;&gt; -&gt;&lt;br /&gt;           ok = gen_tcp:send(Socket, http_reply("Server stopped")),&lt;br /&gt;           exit(ServerPid, stopped),&lt;br /&gt;           io:format("Server stopped~n"),&lt;br /&gt;           ok;&lt;br /&gt;       &lt;&lt;"GET /echo", _/binary&gt;&gt; -&gt;&lt;br /&gt;           ok = gen_tcp:send(&lt;br /&gt;               Socket,&lt;br /&gt;               http_reply(binary_to_list(BinaryData)));&lt;br /&gt;       &lt;&lt;"GET /", Request/binary&gt;&gt; -&gt;&lt;br /&gt;           ok = gen_tcp:send(&lt;br /&gt;               Socket,&lt;br /&gt;               http_reply(&lt;br /&gt;                   readfile(&lt;br /&gt;                       parse_filename(Request))));&lt;br /&gt;       _Unknown -&gt;&lt;br /&gt;           ok = gen_tcp:send(Socket, http_reply("Unknown request")),&lt;br /&gt;           io:format("Unknown request, BinaryData = ~s~n", [BinaryData])&lt;br /&gt;   end.&lt;br /&gt;&lt;br /&gt;parse_filename(Request) -&gt;&lt;br /&gt;   RequestString = binary_to_list(Request),&lt;br /&gt;   StopIndex = string:str(RequestString, " HTTP"),&lt;br /&gt;   Filename = string:substr(RequestString, 1, StopIndex-1),&lt;br /&gt;   Filename.&lt;br /&gt;  &lt;br /&gt;readfile(Filename) -&gt;&lt;br /&gt;       {ok, Binary} = file:read_file(Filename),&lt;br /&gt;       binary_to_list(Binary).&lt;br /&gt;&lt;br /&gt;http_reply(Data) -&gt;&lt;br /&gt;   DataLength = string:len(Data),&lt;br /&gt;   list_to_binary(&lt;br /&gt;       "HTTP/1.1 200 OK\r\n" ++&lt;br /&gt;       "Date: " ++ mdate:date_now_string() ++ "\r\n" ++&lt;br /&gt;       "Server: MServer/0.1\r\n" ++&lt;br /&gt;       "Last-Modified: " ++ mdate:date_now_string() ++ "\r\n" ++&lt;br /&gt;       % Accept-Ranges: bytes&lt;br /&gt;       "Content-Length: " ++ integer_to_list(DataLength) ++ "\r\n" ++&lt;br /&gt;       "Connection: close\r\n" ++&lt;br /&gt;       "Content-Type: text/html; charset=UTF-8\r\n\r\n" ++&lt;br /&gt;       Data).&lt;br /&gt;&lt;br /&gt;% Create an exit handler, a process that traps exit messages&lt;br /&gt;% from another process. This can be used for a try/catch style&lt;br /&gt;% error handling between processes.   &lt;br /&gt;on_exit(Pid, ExitFun) -&gt;&lt;br /&gt;   spawn(&lt;br /&gt;       fun() -&gt;&lt;br /&gt;           process_flag(trap_exit, true),&lt;br /&gt;           link(Pid),&lt;br /&gt;           receive&lt;br /&gt;               {'EXIT', Pid, Why} -&gt; ExitFun(Why)&lt;br /&gt;           end&lt;br /&gt;       end&lt;br /&gt;   ).&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-3745002989087577017?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/3745002989087577017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/tiny-erlang-web-server-parallell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3745002989087577017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3745002989087577017'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/tiny-erlang-web-server-parallell.html' title='Tiny Erlang web server - parallel version'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-3901329891346233422</id><published>2009-09-16T13:59:00.000-07:00</published><updated>2009-10-21T02:07:02.056-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><title type='text'>Tiny Erlang web server - sequential version</title><content type='html'>This is a tiny web server written in &lt;a href="http://www.erlang.org/" target="_blank"&gt;Erlang&lt;/a&gt;. Requests are processed sequentially.&lt;br /&gt;&lt;pre&gt;% Filename: mserver2.erl&lt;br /&gt;% Tiny webserver that restarts on error.&lt;br /&gt;% Requests are processed sequentially.&lt;br /&gt;% Author: mikael.kindborg@gmail.com&lt;br /&gt;% Date: September 2008&lt;br /&gt;&lt;br /&gt;-module(mserver2).&lt;br /&gt;-export([start/0, stop/0, supervisor/0, start_server/0, server/1]).&lt;br /&gt;&lt;br /&gt;% How to benchmark:&lt;br /&gt;% apache benchmark ab -n 100 -c 10 http://1.1.1.84:4042/hello.html&lt;br /&gt;&lt;br /&gt;start() -&gt;&lt;br /&gt;   spawn(?MODULE, supervisor, []).&lt;br /&gt;  &lt;br /&gt;supervisor() -&gt;&lt;br /&gt;   io:format("Starting server.~n"),&lt;br /&gt;   Pid = spawn(?MODULE, start_server, []),&lt;br /&gt;   link(Pid),&lt;br /&gt;   process_flag(trap_exit, true),&lt;br /&gt;   receive&lt;br /&gt;       {'EXIT', Pid, normal} -&gt;&lt;br /&gt;           io:format("Server exited normally.~n"),&lt;br /&gt;           timer:sleep(1000);&lt;br /&gt;       {'EXIT', Pid, Reason} -&gt;&lt;br /&gt;           io:format("Server exited with code: ~w~n", [Reason]),&lt;br /&gt;           timer:sleep(1000),&lt;br /&gt;           supervisor();&lt;br /&gt;       stop -&gt;&lt;br /&gt;           io:format("Stoppning supervisor.~n");&lt;br /&gt;       Unknown -&gt;&lt;br /&gt;           io:format("Supervisor got an unknown message: ~w~n", [Unknown]),&lt;br /&gt;           supervisor()&lt;br /&gt;   end.&lt;br /&gt;&lt;br /&gt;start_server() -&gt;&lt;br /&gt;   {ok, ServerSocket} = gen_tcp:listen(&lt;br /&gt;       4042, [binary, {packet, 0}, {active, false}, {reuseaddr, true}]),&lt;br /&gt;   on_exit(&lt;br /&gt;       self(),&lt;br /&gt;       fun (Why) -&gt;&lt;br /&gt;           gen_tcp:close(ServerSocket),&lt;br /&gt;           io:format("Exiting server, closing ServerSocket, Why = ~w~n", [Why])&lt;br /&gt;       end),&lt;br /&gt;   server(ServerSocket).&lt;br /&gt;&lt;br /&gt;stop() -&gt;&lt;br /&gt;   ServerAddress = "localhost",&lt;br /&gt;   {ok, Socket} = gen_tcp:connect(ServerAddress, 4042, [binary, {packet, 0}]),&lt;br /&gt;   ok = gen_tcp:send(Socket, &lt;&lt;"stop"&gt;&gt;),&lt;br /&gt;   ok = gen_tcp:close(Socket).&lt;br /&gt;&lt;br /&gt;server(ServerSocket) -&gt;&lt;br /&gt;   {ok, Socket} = gen_tcp:accept(ServerSocket),&lt;br /&gt;   {ok, BinaryData} = gen_tcp:recv(Socket, 0),   &lt;br /&gt;   case BinaryData of&lt;br /&gt;       &lt;&lt;"stop"&gt;&gt; -&gt;&lt;br /&gt;           ok = gen_tcp:close(Socket),&lt;br /&gt;           io:format("Server stopped~n"),&lt;br /&gt;           ok;&lt;br /&gt;       &lt;&lt;"GET /stop", _/binary&gt;&gt; -&gt;&lt;br /&gt;           ok = gen_tcp:send(Socket, http_reply("Server stopped")),&lt;br /&gt;           ok = gen_tcp:close(Socket),&lt;br /&gt;           io:format("Server stopped~n"),&lt;br /&gt;           ok;&lt;br /&gt;       &lt;&lt;"GET /echo", _/binary&gt;&gt; -&gt;&lt;br /&gt;           ok = gen_tcp:send(&lt;br /&gt;               Socket,&lt;br /&gt;               http_reply(binary_to_list(BinaryData))),&lt;br /&gt;           ok = gen_tcp:close(Socket),&lt;br /&gt;           server(ServerSocket);&lt;br /&gt;       &lt;&lt;"GET /", Request/binary&gt;&gt; -&gt;&lt;br /&gt;           ok = gen_tcp:send(&lt;br /&gt;               Socket,&lt;br /&gt;               http_reply(&lt;br /&gt;                   readfile(&lt;br /&gt;                       parse_filename(Request)))),&lt;br /&gt;           ok = gen_tcp:close(Socket),&lt;br /&gt;           server(ServerSocket);&lt;br /&gt;       _Unknown -&gt;&lt;br /&gt;           ok = gen_tcp:send(Socket, http_reply("Unknown request")),&lt;br /&gt;           ok = gen_tcp:close(Socket),&lt;br /&gt;           io:format("BinaryData = ~s~n", [BinaryData]),&lt;br /&gt;           server(ServerSocket)&lt;br /&gt;   end.&lt;br /&gt;&lt;br /&gt;parse_filename(Request) -&gt;&lt;br /&gt;   RequestString = binary_to_list(Request),&lt;br /&gt;   StopIndex = string:str(RequestString, " HTTP"),&lt;br /&gt;   Filename = string:substr(RequestString, 1, StopIndex-1),&lt;br /&gt;   Filename.&lt;br /&gt;  &lt;br /&gt;readfile(Filename) -&gt;&lt;br /&gt;       {ok, Binary} = file:read_file(Filename),&lt;br /&gt;       binary_to_list(Binary).&lt;br /&gt;&lt;br /&gt;http_reply(Data) -&gt;&lt;br /&gt;   DataLength = string:len(Data),&lt;br /&gt;   list_to_binary(&lt;br /&gt;       "HTTP/1.1 200 OK\r\n" ++&lt;br /&gt;       "Date: " ++ mdate:date_now_string() ++ "\r\n" ++&lt;br /&gt;       "Server: MServer/0.1\r\n" ++&lt;br /&gt;       "Last-Modified: " ++ mdate:date_now_string() ++ "\r\n" ++&lt;br /&gt;       % Accept-Ranges: bytes&lt;br /&gt;       "Content-Length: " ++ integer_to_list(DataLength) ++ "\r\n" ++&lt;br /&gt;       "Connection: close\r\n" ++&lt;br /&gt;       "Content-Type: text/html; charset=UTF-8\r\n\r\n" ++&lt;br /&gt;       Data).&lt;br /&gt;&lt;br /&gt;% Create an exit handler, a process that traps exit messages&lt;br /&gt;% from another process. This can be used for a try/catch style&lt;br /&gt;% error handling between processes.   &lt;br /&gt;on_exit(Pid, ExitFun) -&gt;&lt;br /&gt;   spawn(&lt;br /&gt;       fun() -&gt;&lt;br /&gt;           process_flag(trap_exit, true),&lt;br /&gt;           link(Pid),&lt;br /&gt;           receive&lt;br /&gt;               {'EXIT', Pid, Why} -&gt; ExitFun(Why)&lt;br /&gt;           end&lt;br /&gt;       end&lt;br /&gt;   ).&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-3901329891346233422?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/3901329891346233422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/tiny-erlang-web-server-sequential.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3901329891346233422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/3901329891346233422'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/tiny-erlang-web-server-sequential.html' title='Tiny Erlang web server - sequential version'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-7527059942020901314</id><published>2009-09-16T07:04:00.000-07:00</published><updated>2009-10-21T02:06:37.827-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='end-user programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><title type='text'>Scheme and App Inventor for Android</title><content type='html'>Just came across &lt;a href="http://googleresearch.blogspot.com/2009/08/under-hood-of-app-inventor-for-android.html" target="_blank"&gt;this blog entry&lt;/a&gt; detaling the use of Scheme for an easy-to-use Android programming tool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-7527059942020901314?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/7527059942020901314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/scheme-and-app-inventor-for-android.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/7527059942020901314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/7527059942020901314'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/scheme-and-app-inventor-for-android.html' title='Scheme and App Inventor for Android'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5236266522633912942.post-9025219173094570878</id><published>2009-09-16T06:57:00.000-07:00</published><updated>2010-03-23T03:49:47.106-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='msc'/><title type='text'>Dynamic Languages</title><content type='html'>This blog is about dynamic programming languages. Classic lanugages like Lisp, Scheme, and Smalltalk indeed have a divine touch, and more recent languages such as Erlang, Python, and Ruby also have a distinctive beauty and dynamism that feels enlightning.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5236266522633912942-9025219173094570878?l=divineprogrammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://divineprogrammer.blogspot.com/feeds/9025219173094570878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/dynamic-languages.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/9025219173094570878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5236266522633912942/posts/default/9025219173094570878'/><link rel='alternate' type='text/html' href='http://divineprogrammer.blogspot.com/2009/09/dynamic-languages.html' title='Dynamic Languages'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry></feed>
