<?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-7421391</id><updated>2011-10-12T13:18:13.020+10:00</updated><title type='text'>Etymon</title><subtitle type='html'>\Et"y*mon\, n.; pl. E. Etymons, Gr. Etyma. 
&lt;br&gt;
[L., fr. Gr. 'e`tymon the true literal sense of a word according to its derivation, an etymon]</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>99</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7421391.post-1916926236507806836</id><published>2010-05-19T09:36:00.002+10:00</published><updated>2010-05-19T09:38:01.739+10:00</updated><title type='text'>Reading a File to a String in one line in Java</title><content type='html'>&lt;p&gt;&lt;a href="http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html"&gt;http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
&lt;code&gt;String text = new Scanner(new File("poem.txt")).useDelimiter("\\A").next();&lt;/code&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-1916926236507806836?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/1916926236507806836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=1916926236507806836' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/1916926236507806836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/1916926236507806836'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2010/05/reading.html' title='Reading a File to a String in one line in Java'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-5455829132119710911</id><published>2009-11-25T09:59:00.008+10:00</published><updated>2009-11-25T10:59:41.758+10:00</updated><title type='text'>JRuby and JNI and OS X.</title><content type='html'>&lt;p&gt;Like practically everyone I sat down a few years back and picked up enough Ruby to write an address-book app in Rails. Nice enough language, a few nice features[0]. Still at the end of the day... YADTL, so ultimately YAWN[1].&lt;/p&gt;
&lt;p&gt;
All this is to say that I found myself yesterday facing the need to convert a trivial rails app into a java servlet, with the added complication that it uses a third-party C++ library to do the bulk of the work.
&lt;/p&gt;
&lt;p&gt;
JRuby is a trivial install, and the application in question didn't make use of continuations, so rip out all the Rails code, and replace with a simple loop that takes requests from the cmdline instead of a POST parameter, and we're in business.
&lt;/p&gt;
&lt;p&gt;
Well up to the point where it falls over because it needs the C++ library.  Here's the first real hurdle.  Apple's JDK for OS X is compiled as a 64-bit binary which can't link against 32-bit libraries[2], and by default the C compiler only produces 32-bit libraries.
&lt;pre&gt;$ file /usr/local/lib/libcrfpp.dylib 
/usr/local/lib/libcrfpp.dylib: Mach-O dynamically linked shared library i386
&lt;/pre&gt;
A quick check on google yields &lt;a href="http://de-co-de.blogspot.com/2008/04/if-you-install-modjk.html"&gt;these&lt;/a&gt; &lt;a href="http://code.google.com/p/modwsgi/wiki/InstallationOnMacOSX"&gt;pages&lt;/a&gt; that suggest that I need to add &lt;code&gt;-arch i386 -arch x86_64&lt;/code&gt; to the &lt;code&gt;CXXFLAGS&lt;/code&gt; and &lt;code&gt;LDFLAGS&lt;/code&gt;. So after modifying the Makefile to compile the library with the above flags and install it in /opt/local we have:
&lt;pre&gt;$ file /opt/local/lib/libcrfpp.dylib 
/opt/local/lib/libcrfpp.dylib: Mach-O universal binary with 2 architectures
/opt/local/lib/libcrfpp.dylib (for architecture i386): Mach-O dynamically linked shared library i386
/opt/local/lib/libcrfpp.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
Then we need to compile the SWIG generated JNI wrapper, which will also require the above parameters, but also needs to link against Apples JNI installation.
Back to Google which provides this page from Apple that describes &lt;a href="http://developer.apple.com/mac/library/DOCUMENTATION/Java/Conceptual/Java14Development/05-CoreJavaAPIs/CoreJavaAPIs.html"&gt;how to compile JNI on Darwin&lt;/a&gt;, which provides the include path and an additional link flag.
&lt;/p&gt;
&lt;p&gt;
The command lines to compile the wrapper in question becomes:
&lt;pre&gt;g++ -arch i386 -arch x86_64 -c -I/System/Library/Frameworks/JavaVM.framework/Headers CRFPP_wrap.cxx
g++ -arch i386 -arch x86_64 -dynamiclib -L/opt/local/lib -lcrfpp -o libCRFPP.jnilib CRFPP_wrap.o -framework JavaVM&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
Wanting to avoid calling &lt;code&gt;System.loadLibrary&lt;/code&gt; from ruby code I wrote a quick wrapper class that could make the call in a static block:
&lt;pre&gt;package crfppwrapper;

import org.chasen.crfpp.Tagger;

public class CRFPP {
    public static Tagger newTagger(String args) {
        return new Tagger(args);
    }

    static {
        System.loadLibrary("CRFPP");
    }
}
&lt;/pre&gt;
Finally modify the relevant ruby file to link to the jar file:
&lt;pre&gt;require 'java'
require 'lib/CRFPP-0.53.jar'
&lt;/pre&gt;
and call the wrapper:
&lt;pre&gt;crfppwrapper.CRFPP.newTagger("...");
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
Finally modify the toplevel jruby script to pass the necessary java parameters to the jvm:
&lt;pre&gt;#!/usr/bin/env jruby -J-Djava.library.path=/opt/local/lib -J-cp .:lib/CRFPP-0.53.jar -w&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;And it worked. No more Rails; migrated to jruby; and ready to bundle into a  trivial servlet that will reintroduce the POST parameter to the mix.&lt;/p&gt;
&lt;p&gt;
[0] The implicit closure parameter to every function and an elegant brace syntax for creating the closures themselves does lend itself to some wonderfully elegant idioms.
&lt;/p&gt;&lt;p&gt;
[1] Of course if you were coming from J2EE you were probably more than happy to exchange static-typing for configuration-by-convention.
&lt;/p&gt;&lt;p&gt;
[2] And all of a sudden I'm having flashbacks to horror of IRIX binary toolchain management in the late 90's.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-5455829132119710911?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/5455829132119710911/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=5455829132119710911' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/5455829132119710911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/5455829132119710911'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2009/11/jruby-and-jni-and-os-x.html' title='JRuby and JNI and OS X.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-2074731896636241995</id><published>2009-09-08T10:44:00.003+10:00</published><updated>2009-09-08T10:49:01.212+10:00</updated><title type='text'>ldd equivalent under Darwin (OS X)</title><content type='html'>&lt;p&gt;
&lt;code&gt;ldd&lt;/code&gt; is an incredibly useful command under linux. It lists the shared-libraries required by an executable, and exactly which .so file each dependency is currently resolved to.
&lt;/p&gt;
&lt;p&gt;
A similarly useful tool is &lt;code&gt;od&lt;/code&gt;, which permits inspection of object files, especially executable and shared-libraries, extracting things like the string-table, symbol-table, and various headers and sections.
&lt;/p&gt;
&lt;p&gt;
Under Darwin these tools are combined in &lt;code&gt;otool&lt;/code&gt;. &lt;code&gt;ldd&lt;/code&gt; can be duplicated by &lt;code&gt;otool -L&lt;/code&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-2074731896636241995?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/2074731896636241995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=2074731896636241995' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/2074731896636241995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/2074731896636241995'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2009/09/ldd-equivalent-under-darwin-os-x.html' title='ldd equivalent under Darwin (OS X)'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-7762819097798653048</id><published>2009-08-26T14:25:00.004+10:00</published><updated>2009-08-26T14:31:17.341+10:00</updated><title type='text'>Gov2.0 and Open-Source - a response</title><content type='html'>&lt;p&gt;
Cross-posted from &lt;a href="http://gov2.net.au/blog/2009/08/26/lessons-from-the-open-source-world/"&gt;Data.gov and lessons from the open-source world&lt;/a&gt; at the &lt;a href="http://gov2.net.au/"&gt;Gov2.0 Taskforce blog&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
My biggest worry is that the government's response to this initiative will be the announcement of some $multi-million grand-gesture. Big press-conference; Minister announcing the 'grand vision'; and the possible benefits we could see, lost in the maze that is large-scale government procurement.
&lt;/p&gt;
&lt;p&gt;
The key insight of &lt;a href="http://www.catb.org/~esr/writings/cathedral-bazaar/"&gt;CatB&lt;/a&gt; is the extent to which redundancy is a benefit in exploratory development.
&lt;/p&gt;
&lt;p&gt;
For the moment, we have no idea of the correct model for Gov2.0 - we have some understanding of what has worked outside of government, and a few promising avenues of approach, but no actual answers. 
&lt;/p&gt;
&lt;p&gt;
So I think we want to recommend that different Agencies experiment with different approaches and that the OIC be tasked with:
&lt;ol&gt;
&lt;li&gt;Examining the success/failure of the different attempts, and eventually start to help agencies improve the success rate.&lt;/li&gt;
&lt;li&gt;Ensuring that the legal and regulatory requirements for aggregation and interoperability of/between these different services is standardised, as these are the issues that will derail bazaar development.&lt;/li&gt;
&lt;li&gt;Acting as a central clearing house where agencies/organisations/individuals can choose to self-publish interface descriptions, custom schema, metadata element schemes, vocabularies etc&lt;/li&gt;
&lt;li&gt;Providing a collaboration and mediation service to allow the reconciliation of conflicting interface/schema/scheme/vocab's.&lt;/li&gt;
&lt;/ol&gt;
&lt;/p&gt;
&lt;p&gt;
The result would hopefully be a myriad of exploratory projects, some of which would fail, most of which would be ho-hum, but many of which would succeed.
&lt;/p&gt;
&lt;p&gt;
The OIC would act as an institutional memory, learning and recording the lessons learnt; an institutional coordinator, making sure that people wanting to aggregate/integrate the different data-sources aren't forbidden from doing so; and an institutional mediator, assisting the different projects in finding and working together when they would like to.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Please post any comments to the gov2.0 site listed above, not here&lt;/em&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-7762819097798653048?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/7762819097798653048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=7762819097798653048' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/7762819097798653048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/7762819097798653048'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2009/08/cross-posted-from-data.html' title='Gov2.0 and Open-Source - a response'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-3383970403838754812</id><published>2009-07-13T09:45:00.002+10:00</published><updated>2009-07-13T09:54:53.806+10:00</updated><title type='text'>Google’s new OS could hit Microsoft where it hurts</title><content type='html'>&lt;p&gt;Quoted in a &lt;a href="http://blog.taragana.com/index.php/archive/googles-new-os-could-hit-microsoft-where-it-hurts/"&gt;blog post&lt;/a&gt; by Andy Goldberg, Andy provides a quote that I suspect a lot of Microsoft sycophants will be telling themselves over the next year:
&lt;/p&gt;
&lt;blockquote&gt;"Google may or may not have the experience and capability of actually producing an operating system and getting it deployed," he said. "It may not realise how hard it is."&lt;/blockquote&gt;
&lt;p&gt;
Anyone who takes this line should remind themselves: Chrome OS &lt;strong&gt;is not&lt;/strong&gt; an operating system! - it is browser-based windowing system running on top of an open-source OS; and Google can definitely handle that. Moreover, google has spent the better part of the past decade doing OS design and implementation. It's just that they haven't been selling it, they have been using it internally.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-3383970403838754812?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/3383970403838754812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=3383970403838754812' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/3383970403838754812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/3383970403838754812'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2009/07/googles-new-os-could-hit-microsoft.html' title='Google’s new OS could hit Microsoft where it hurts'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-3443091226434650440</id><published>2009-07-10T14:33:00.002+10:00</published><updated>2009-07-10T14:46:33.234+10:00</updated><title type='text'>How to Write an Equality Method in Java</title><content type='html'>&lt;p&gt;
Martin Odersky, Lex Spoon, and Bill Venners have written an article on &lt;a href="http://www.artima.com/lejava/articles/equality.html"&gt;How to Write an Equality Method in Java&lt;/a&gt;. Given the amount of traffic my post on the same topic has attracted, I thought I might take a look. Their solution is the best I have seen, and well worth a look, but the article suffers the same problem as every article I've read on this topic: it fails to properly define equals().
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;A Java equals() method should implement a test for bisimulation&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
To me, the remarkable thing about the Artima article is that it provides and example where the traditional getClass() approach I have previously recommended fails to implement bisimulation.  The good-news is that this is a rather artificial use-case, and as such isn't going to be causing many bugs.  The bad-news is that the fix requires a helper method defined at the topmost concrete class, and the need for it isn't intuitive.
&lt;/p&gt;
&lt;p&gt;
Anyway, if you program in Java you need to read and understand this article.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-3443091226434650440?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/3443091226434650440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=3443091226434650440' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/3443091226434650440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/3443091226434650440'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2009/07/how-to-write-equality-method-in-java.html' title='How to Write an Equality Method in Java'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-5392366830475445623</id><published>2009-07-02T15:30:00.004+10:00</published><updated>2009-07-08T16:38:09.376+10:00</updated><title type='text'>Scala and Various Things.</title><content type='html'>&lt;p&gt;Not quite ready to move across yet - however capturing some links to make life that little bit easier when I do.  I'm hoping these approaches will work as well for Elmo/OTM as they do for Hibernate.
&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://sntx.livejournal.com/33780.html"&gt;Hibernate and Scala&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://matt.immute.net/content/more-scala-hibernate"&gt;
More Scala + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://matt.immute.net/content/scala-hibernate-overview"&gt;Scala + Hibernate overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://groups.google.com/group/liftweb/browse_thread/thread/394b3a15206dd3b8"&gt;Lift thread with interesting comments&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I'll be updating this with any more links I want to save for a sunny day.
&lt;/p&gt;
&lt;p&gt;
A couple more links worthy of rereading:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://james-iry.blogspot.com/2007/09/monads-are-elephants-part-1.html"&gt;monads-are-elephants-part-1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://james-iry.blogspot.com/2007/10/monads-are-elephants-part-2.html"&gt;monads-are-elephants-part-2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://james-iry.blogspot.com/2007/10/monads-are-elephants-part-3.html"&gt;http://james-iry.blogspot.com/2007/10/monads-are-elephants-part-3.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://james-iry.blogspot.com/2007/11/monads-are-elephants-part-4.html"&gt;http://james-iry.blogspot.com/2007/11/monads-are-elephants-part-4.html&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/7421391-5392366830475445623?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/5392366830475445623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=5392366830475445623' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/5392366830475445623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/5392366830475445623'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2009/07/scala-and-hibernate.html' title='Scala and Various Things.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-5073249135396151226</id><published>2009-06-17T15:20:00.003+10:00</published><updated>2009-06-17T15:37:08.997+10:00</updated><title type='text'>Looking for  JSON, ReST, (and in-memory RDF) frameworks</title><content type='html'>&lt;p&gt;
Currently writing a number of small web-services to do various informatics tasks (more detailed post to come).  Fortunately I'm not the one having to deal with 3rd-party SOAP apis! Still I do need to do various XML and JSON parsing, and not having addressed the latter before I've gone looking for libraries.
&lt;/p&gt;
&lt;p&gt;
Currently I am about to start using &lt;a href="http://jackson.codehaus.org/"&gt;Jackson&lt;/a&gt;, but was wondering if anyone had any warnings, advice, or recommended alternatives?  In the course of looking at what was out there I have also come across &lt;a href="http://www.restlet.org/"&gt;Restlet&lt;/a&gt;, a ReST framework that seems like it is well worth the time to figure out and deploy, so I will probably be doing that soon as well, any warnings or advice on this will be welcome.
&lt;/p&gt;
&lt;p&gt;
One of the nice things about Restlet is its support for RDF. Granted it doesn't support querying, and the terminology in the interface is a bit confused, but it does use its native Resource interface for URIRefs, so it should integrate well. OTOH, if it does prove useful as a ReST framework, I can see myself writing a quick Sesame or Mulgara extension, as there is only so much you can do with RDF before you need a query and/or data-binding interface.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-5073249135396151226?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/5073249135396151226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=5073249135396151226' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/5073249135396151226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/5073249135396151226'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2009/06/looking-for-json-rest-and-in-memory-rdf.html' title='Looking for  JSON, ReST, (and in-memory RDF) frameworks'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-2771853285995894965</id><published>2009-06-04T15:13:00.003+10:00</published><updated>2009-06-04T15:34:09.102+10:00</updated><title type='text'>Deploying to tomcat using maven</title><content type='html'>&lt;p&gt;
This is a note to capture the process I am currently using to build and deploy a basic web application to tomcat for development.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;ol&gt;
&lt;li&gt;Create simple web app using archetype. &lt;br/&gt;
&lt;pre&gt;mvn archetype:create ... -DarchetypeArtifactId=maven-archetype-webapp&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Add server to ~/.m2/settings.xml
&lt;pre&gt;
  &amp;lt;servers&amp;gt;
    &amp;lt;server&amp;gt;
      &amp;lt;id&amp;gt;local-tomcat&amp;lt;/id&amp;gt;
      &amp;lt;username&amp;gt;username&amp;lt;/username&amp;gt;
      &amp;lt;password&amp;gt;password&amp;lt;/password&amp;gt;
    &amp;lt;/server&amp;gt;
  &amp;lt;/servers&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Add server to toplevel pom.xml
&lt;pre&gt;
  &amp;lt;build&amp;gt;
    ...
    &amp;lt;plugins&amp;gt;
      &amp;lt;plugin&amp;gt;
        &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;tomcat-maven-plugin&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;1.0-beta-1&amp;lt;/version&amp;gt;
        &amp;lt;configuration&amp;gt;
          &amp;lt;server&amp;gt;local-tomcat&amp;lt;/server&amp;gt;
        &amp;lt;/configuration&amp;gt;
      &amp;lt;/plugin&amp;gt;
    &amp;lt;/plugins&amp;gt;
  &amp;lt;/build&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;compile, test, deploy, and subsequently redeploy
&lt;pre&gt;
  $ mvn compile
  $ mvn test
  $ mvn tomcat:deploy
  $ mvn tomcat:redeploy
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/p&gt;
&lt;p&gt;
Of course what I would dearly love to know is how you configure a server url in the settings.xml file.  The documentation I can find (&lt;a href="http://mojo.codehaus.org/tomcat-maven-plugin/configuration.html"&gt;http://mojo.codehaus.org/tomcat-maven-plugin/configuration.html&lt;/a&gt;) describes how to use a custom url, and how to configure authentication information.  What it doesn't do is explain how you can do both at the same time, and all my attempts have resulted in XML validation errors when trying to run maven --- if I figure it out I'll update this post.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-2771853285995894965?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/2771853285995894965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=2771853285995894965' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/2771853285995894965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/2771853285995894965'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2009/06/deploying-to-tomcat-using-maven.html' title='Deploying to tomcat using maven'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-7847513034228899518</id><published>2009-05-27T10:01:00.002+10:00</published><updated>2009-05-27T10:53:05.756+10:00</updated><title type='text'>ANTLR: an exercise in pain.</title><content type='html'>&lt;p&gt;
Ok, so for my current project I need to either build heuristic or machine learning based fuzzy parser. As someone who has written numerous standard parsers before, this qualifies as interesting. Current approaches I'm considering include cascading concrete grammars; stochastic context-free grammars; and various forms of hidden-markov-model based recognisers. Whatever approach ends up working best, the first stage for all is a scanner.
&lt;/p&gt;&lt;p&gt;
So I start building a jflex lexer, and make reasonable progress when I find out that we are already using ANTLR for other projects, so I should probably use it as well. Having experienced mulgara's peak of &lt;em&gt;5&lt;/em&gt; different parser generators - this does eventually become ridiculous - I was more than willing to use ANTLR. Yes it's LL, and yes I have previously discussed my preference for LR; but, it does support attaching semantic actions to productions, so my primary requirement of a parser-generator is met; and anyway, it has an excellent reputation, and a substantial active community.
&lt;/p&gt;&lt;p&gt;
What I am now stunned by, is just how bad the documentation can be for such a popular tool. One almost non-existent wiki; a FAQ; and a woefully incomplete doxygen dump, does not substitute for a reference. ANTLR has worse documentation than sablecc had when it consisted of an appendix to a masters thesis!
&lt;/p&gt;&lt;p&gt;
My conclusion: If you have any choice don't use ANTLR. For Java: if you must use LL I currently recommend &lt;a href="https://javacc.dev.java.net/"&gt;JavaCC&lt;/a&gt;; if you can use an LALR parser do so, my current preference is &lt;a href="http://beaver.sourceforge.net/"&gt;Beaver&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-7847513034228899518?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/7847513034228899518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=7847513034228899518' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/7847513034228899518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/7847513034228899518'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2009/05/antlr-exercise-in-pain.html' title='ANTLR: an exercise in pain.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-9062206958188276881</id><published>2008-05-19T19:38:00.002+10:00</published><updated>2008-05-19T19:47:38.246+10:00</updated><title type='text'>So why can't google provide html for 40% of pdfs?</title><content type='html'>&lt;p&gt;
A google search for &lt;a href="http://www.google.com.au/search?hl=en&amp;client=firefox-a&amp;rls=org.mozilla%3Aen-US%3Aofficial&amp;hs=6bM&amp;as_qdr=all&amp;q=opensource+filetype%3Apdf&amp;btnG=Search&amp;meta="&gt;opensource filetype:pdf&lt;/a&gt; returns the standard 10 results on the front page, but only 6 of them offer a "View as HTML" link.  Is it just me, or has this become more prevalent recently? And what is the common property that results in this behaviour?
&lt;/p&gt;
&lt;p&gt;
If anyone has any clues or ideas I would love to hear them.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-9062206958188276881?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/9062206958188276881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=9062206958188276881' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/9062206958188276881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/9062206958188276881'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2008/05/so-why-cant-google-provide-html-for-40.html' title='So why can&apos;t google provide html for 40% of pdfs?'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-6570962635307612468</id><published>2008-01-15T10:40:00.000+10:00</published><updated>2008-01-15T10:43:12.175+10:00</updated><title type='text'>Now this is how conference videos should be presented</title><content type='html'>&lt;p&gt;
A great collection of conference presentations and interviews (mostly on java topics) &lt;a href="http://www.parleys.com/display/PARLEYS/Home"&gt;Parleys&lt;/a&gt; - but of particular interest to me is the presentation, the best I have seen.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-6570962635307612468?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/6570962635307612468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=6570962635307612468' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/6570962635307612468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/6570962635307612468'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2008/01/now-this-is-how-conference-videos.html' title='Now this is how conference videos should be presented'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-4638170299047801272</id><published>2007-11-29T16:27:00.000+10:00</published><updated>2007-11-29T16:41:29.403+10:00</updated><title type='text'>How to start thinking about RDF.</title><content type='html'>&lt;p&gt;While trying to understand RDF, its capabilities and its limitations I have done a lot of reading of earlier work on semi-structured data management.  It occurs to me that I haven't blogged a paragraph from an 1995 paper on heterogeneous information sources that really crystalised for me the crucial difference between RDF and previous attempts at semi-structured data (especially XML and friends) - better late than never I suppose...
&lt;/p&gt;
&lt;blockquote&gt;
We need note define in advance the structure of an object ... no notion of a fixed schema or object class. A label can play two roles: identifying an object (component) and identifying the meaning of an object (component).  If an information source exports objects with a particular label, then we assume that the source can answer the question "What does this label mean?".  It is particularly important to note that labels are relative to the source that exports them.  That is, we do not expect labels to be drawn from an ontology shared by all information sources.
&lt;/blockquote&gt;
&lt;p&gt;
Papakonstantinou, Y. et al. "Object Exchange Across Heterogeneous Information Sources", 11th Conference on Data Engineering, IEEE Computer Society, 251-260, 1995.
&lt;/p&gt;
&lt;p&gt;
The actual framework presented in the paper is focused on intraorganisational integration and so doesn't have the property of anarchic scalability required if it is to be applied to the internet - however it does express clearly this need for source-defined semantics if semi-structured data is to be tractable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-4638170299047801272?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/4638170299047801272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=4638170299047801272' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/4638170299047801272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/4638170299047801272'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2007/11/how-to-start-thinking-about-rdf.html' title='How to start thinking about RDF.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-5756428977785451716</id><published>2007-10-17T15:03:00.000+10:00</published><updated>2007-10-17T15:42:02.681+10:00</updated><title type='text'>Implementing a Resource Manger for the Java Transaction API.</title><content type='html'>&lt;p&gt;
One would hope that when an organisation like Sun specifies a standard as important as a transaction api they might take the time to ensure they do a reasonable effort -- unfortunately you would be wrong.  The JTA specification is freely available &lt;a href="http://java.sun.com/products/jta/"&gt;from Sun&lt;/a&gt;, however the document is extremely vague and requires the reader to infer the underlying transaction state machine - with the unsurprising result that the corner cases are left completely unspecified.  So having waded through this morass myself, I include here my advice on what you need to do to understand JTA, in the hope that anyone else coming to this standard won't have to waste as much time as I have understanding it.
&lt;/p&gt;
&lt;p&gt;
Read the JTA spec &lt;span style="font-weight:bold;"&gt;last&lt;/span&gt;.  JTA is a little more than a thin wrapper around the &lt;a href="http://www.omg.org/cgi-bin/doc?formal/00-06-28"&gt;Object Transaction Service 1.1&lt;/a&gt; published by the OMG.  This is one of the CORBA standards published in the late 90's and early 2000's - and like most of the &lt;span style="font-style:italic;"&gt;early&lt;/span&gt; CORBA specs, it is well written; easy to read; and pretty complete.  Unfortunately it too leaves the underlying state-machine and some of the corner-cases (especially those to do with recovery) underspecified.  As a result I recommend printing this out and referring to it as an adjunct to the JTA spec.
&lt;/p&gt;
&lt;p&gt;
Fortunately the CORBA-OTS is itself an object-oriented wrapper around another spec, the &lt;a href="http://www.opengroup.org/bookstore/catalog/c193.htm"&gt;Distributed Transaction Processing: The XA Specification&lt;/a&gt; spec' published by X/Open (now The Open Group).  There in Chapter 2 you will find &lt;span style="font-style:italic;"&gt;most&lt;/span&gt; of the definitions missing from the other two specs; and in Chapter 6 the state-tables that provide definitive semantics for the various operations you will need to implement.  You will also find a reference to another related X/Open specification - &lt;a href="http://www.opengroup.org/bookstore/catalog/g504.htm"&gt;Distributed Transaction Processing: Reference Model&lt;/a&gt; - which contains all the remaining definitions and assumptions missing from the the JTA/OTS specs.
&lt;/p&gt;
&lt;p&gt;
So if you do need to implement a JTA interface I strongly recommend you start with the X/Open reference model; then read the X/Open XA Spec; and only then read the JTA specification alongside the OTS spec for elaboration.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-5756428977785451716?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/5756428977785451716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=5756428977785451716' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/5756428977785451716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/5756428977785451716'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2007/10/implementing-resource-manger-for-java.html' title='Implementing a Resource Manger for the Java Transaction API.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-8167212437675063110</id><published>2007-09-19T22:01:00.000+10:00</published><updated>2007-09-19T22:16:37.849+10:00</updated><title type='text'>Model-URI/URL Use-cases and Requirements and Proposal</title><content type='html'>&lt;p&gt;
&lt;span style="font-style:italic;"&gt;Just posted this to mulgara-general - posting here to provide readily accessible permanent reference.&lt;/span&gt;

&lt;span style="font-style:italic;"&gt;I would greatly appreciate any comments anyone may have - please also feel free to solicit comments from outside the mulgara community if there is interest.
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-weight:bold;"&gt;The Use Cases and Requirements
&lt;/span&gt;&lt;br/&gt;
The three key requirements of a model-URI proposal are:
&lt;/p&gt;
&lt;p&gt;
1. Protocol/Scheme independence&lt;br/&gt;
2. Model/Server mobility&lt;br/&gt;
3. URI-standards compliance (ie. no fragment)&lt;br/&gt;
&lt;/p&gt;&lt;p&gt;
Also desirable are
&lt;/p&gt;&lt;p&gt;
4. Unique-name&lt;br/&gt;
5. Namespaced to allow a) potential resolution; b) predicable, human-readable URI's.&lt;br/&gt;
&lt;/p&gt;&lt;p&gt;
The context of the most complex use-case involves 4 models and 4 machines (and assumes a Distributed or Federated Resolver)
&lt;/p&gt;&lt;p&gt;&lt;pre&gt;
:modelA is on server1 on host1 and needs 
     to reference :modelB and :modelC
:modelB is on server2 on host2
:modelC is on server3 on host3
:modelD is on server4 on host4 run by an unrelated organisation
&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;
The application needs to perform the query:
&lt;/p&gt;&lt;p&gt;&lt;pre&gt;
select $id subquery(
  select $s $p $o 
  where $s $p $o in $locn and 
        $id &amp;lt;mulgara:locatedAt&amp;gt; $locn in &amp;lt;mulgara:modelURLResolver&amp;gt;)
from host1:modelA
where [ &amp;lt;:useModel&amp;gt; $identifier ] ;
&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;
Which queries each model listed in :modelA after converting their identifier into a URL via a posited resolution mechanism.
&lt;/p&gt;&lt;p&gt;
Now host2 fails, and we restore server2 on host3 to run alongside server3.
&lt;/p&gt;&lt;p&gt;
We would like to be able to have the query run unmodified.
&lt;/p&gt;&lt;p&gt;
What this means is that :modelB cannot encode host2 in its URI.
&lt;/p&gt;&lt;p&gt;
The URI does need to encode some sort of server-id as servers are guaranteed to use the same model-names at least some of the time (consider all system-model's have the name "").
&lt;/p&gt;&lt;p&gt;
Also because :modelD and :modelA-C are managed by unrelated organisations we must somehow encode the organisation in the model's URI-stem as they may well decide to use the same server-id ("server1" or "database" anyone?).
&lt;/p&gt;&lt;p&gt;
Also consider that any encoding of the organisation must also allow that organisation to maintain their own independent registry, or the proposal ceases to be scale-free (it's on this that the original UUID proposal floundered).
&lt;/p&gt;&lt;p&gt;
I have considered abandoning requirement 4, and just using URL's.  However ultimately we require a canonical name for internal purposes (even if it isn't exposed externally), and so even using URL's we would have to pick a designated 'unique name' for the model - we can't escape that - so we might as well save ourselves the headache and make it unambiguous.
&lt;/p&gt;&lt;p&gt;
So a summary of my thinking on the use-cases/requirements for rdf model-names - we desire:
&lt;/p&gt;&lt;p&gt;
1. Unambiguously an identifier&lt;br/&gt;
2. Encodes organisation&lt;br/&gt;
3. Encodes server-id&lt;br/&gt;
4. Doesn't encode hostname&lt;br/&gt;
5. Potentially resolvable via a per-organisation registry&lt;br/&gt;
&lt;/p&gt;&lt;p&gt;
&lt;span style="font-weight:bold;"&gt;* Proposal&lt;/span&gt;
&lt;/p&gt;&lt;p&gt;
If we wish to be unambiguous then we should use our own URI-scheme.  This has the added benefit that once we use our own scheme we have a lot more flexibility regarding how we structure the rest of the URI to meet our requirements.
&lt;/p&gt;&lt;p&gt;
I am proposing to use the scheme 'rdfdb' - as did the original UUID proposal.
&lt;/p&gt;&lt;p&gt;
I would prefer to avoid the use of opaque URI's; there is no reason why our URI can't be introspected if we structure it sanely - so the structure according to RFC2396 will be 'rdfdb://authority/path'.
&lt;/p&gt;&lt;p&gt;
Logically the model-name itself makes a good path so we arrive at 'rdfdb://authority/modelName'.  Leaving the need to encode an organisation and a server-id in the authority in a fashion that will potentially permit resolution via a registry.
&lt;/p&gt;&lt;p&gt;
Now as the authority is not a hostname, RFC2396 identifies us as a "Registry-based Naming Authority".  As such, the characters we have permitted to us are [ - _ . ! ~ * ' ( ) $ , ; : @ &amp; = + ] (excluding the []'s) - and the characters reserved are [ ? / ].
&lt;/p&gt;&lt;p&gt;
I therefore propose to structure the authority 'server-id~organisation-id' (that is the server-id and org-id separated by a tilde).
&lt;/p&gt;&lt;p&gt;
At the moment we don't support hierarchical server-id's; but I would like to leave us the option of doing so once we start supporting more aggressive distribution.  We also need to consider that it needs to remain a valid path-element for use in our existing model-URL's.  So for now I would like to limit server-id to what we currently use, but ultimately I think we should consider some sort of delimited hierarchical form (probably dotted).
&lt;/p&gt;&lt;p&gt;
The organisation-id should be something that will eventually permit the identification of a registry.  For now a dotted hierarchical form should suffice - although I will make sure the implementation leaves this as open as possible (the use of a tilde makes this possible).
&lt;/p&gt;&lt;p&gt;
It has also been suggested that to make it unambiguously clear we are *not* encoding a hostname as the organisation-id we should invert the traditional dns-style representation.
&lt;/p&gt;&lt;p&gt;
So putting all the pieces together:  If I am running a mulgara server -
&lt;/p&gt;&lt;p&gt;&lt;pre&gt;
host:         pneuma.netymon.com
organisation: netymon.com
server-id:    rdfDatabase
model-name:   addressBook
&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;
The model URL for addressBook remains: rmi://pneuma.netymon.com/rdfDatabase#addressBook&lt;br/&gt;
or: soap://pneuma.netymon.com/rdfDatabase#addressBook   ...etc...
&lt;/p&gt;&lt;p&gt;
and the model URL for the model is: rdfdb://rdfDatabase~com.netymon/addressBook
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-8167212437675063110?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/8167212437675063110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=8167212437675063110' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/8167212437675063110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/8167212437675063110'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2007/09/model-uriurl-use-cases-and-requirements.html' title='Model-URI/URL Use-cases and Requirements and Proposal'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-1781048797997844167</id><published>2007-09-17T20:48:00.001+10:00</published><updated>2007-09-17T20:54:38.829+10:00</updated><title type='text'>Operational vs. Denotational Semantics</title><content type='html'>&lt;p&gt;
Spent a little time this afternoon discussing several topics with LB and SR.  One topic we touched on was our continuing efforts to understand the distinction between denotational and operational semantics - I continue to be surprised at just how hard it's proving to nail down the precise distinction.
&lt;/p&gt;
&lt;p&gt;
Looking at the various scrawls on my whiteboard that are the only physical remnants of what was a fascinating discussion, I gave some more thought to the distinction, and I believe it can be described thus:
&lt;blockquote&gt;
Operational  :  M ( P ) |= σ -&gt; σ' &lt;br/&gt;
Denotational :  M ( P ) |= κ -&gt; P' &lt;br/&gt;
&lt;/blockquote&gt;
ie. In Operational semantics the meaning of a program is a transition function on a virtual machine.&lt;br/&gt;
in Denotational semantics the meaning of a program is a mapping from an initial basis to a new (simplified) program.
&lt;/p&gt;
&lt;p&gt;
Now this is confused by most operational semantics being "small-step", where the meaning is defined via structural recursion on the abstract grammar: 
&lt;blockquote&gt;
 M ( ρ ) |- σ -&gt; M (ρ') σ' { the meaning of an AST production is a transition function from an initial VM state to the meaning of a (simplified) production applied to a new VM state. }
&lt;/blockquote&gt;
Which end up looking very similar to denotational semantics as denotational semantics are normally defined via structural recursion.
&lt;/p&gt;&lt;p&gt;
But even for the similarity there remains the core distinction (as I understand it) - Denotational Semantics are defined in terms of a reduction-semantics from program+basis to a simplified program (although normally a program in a different, mathematically tractable language such as the lambda-calculus) whereas Operational Semantics are defined in terms of a transition-semantics from a program+initial-state to a new state (although normally a state extended with function-values defined in a mathematically tractable language such as the lambda-calculus).
&lt;/p&gt;&lt;p&gt;
Now of course Interpreter Semantics is a whole different kettle of fish, and of course leaves you facing the 'turtle problem' - you can try for 'turtles all the way down' if you like, but once you hit the metal you've pretty much lost the point of a semantics in the first place.  I must admit admiring the way ECMAscript handled it - an interpreter semantics in SML, which has an operational semantics of its own avoiding the problem.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-1781048797997844167?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/1781048797997844167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=1781048797997844167' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/1781048797997844167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/1781048797997844167'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2007/09/operational-vs-denotational-semantics.html' title='Operational vs. Denotational Semantics'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-8884653012674580607</id><published>2007-08-30T17:23:00.000+10:00</published><updated>2007-08-31T18:56:37.204+10:00</updated><title type='text'>RDF, Document Repositories</title><content type='html'>&lt;p&gt;
I have recently had several discussions with people working on/with various document repository projects.  One thing I hear is the increasing understanding of the importance of semantics in repository metadata management.  I'm naturally pleased to see this because storage, query, and management of semantics is precisely where projects like &lt;a href="http://www.mulgara.org/"&gt;mulgara&lt;/a&gt; come in.
&lt;/p&gt;
&lt;p&gt;
Now digital repositories are alot more than just a semantic store, there are also issues associated with the actual document storage, retrieval, and the QA, workflow, and various metadata extraction tasks.  However these days most repository projects include some sort of semantic store to manage metadata, and the question is reasonably asked - why not just use that?
&lt;/p&gt;
&lt;p&gt;
The reason I recommend considering using mulgara to augment a document repository is due to the additional flexibility gained by doing so.  When a repository developer approaches the metadata problem they have a natural tendency to view adopt an 'instance-focused' view of metadata.  This is where the focus is on the 'document', where each document is of a given 'document type', and each 'document type' implies  corresponding 'attributes'.  In contrast, RDF is 'property-focused' --- where the focus is on defining the 'meaning' of 'properties', and a 'document' having a given property 'classifies' the document as belonging to a given 'class of documents'.
&lt;/p&gt;
&lt;p&gt;
While the two are duals they do influence design.  If you are taking an instance-focused approach you will find yourself heading towards document-type hierarchies and defined attribute lists.  If you take a property-focused approach you will find yourself defining lexicons and ontologies.  The former tends towards relational approaches, the latter towards semantic approaches such as RDF.  The reason why I believe the semantic approach to be superior is in its flexibility.  Hierarchies are predicated on centralised control.  Even if you can maintain central control over the document type definitions and their attributes, the very act of standardisation in this manner leaves your project with the unfortunate choice of 'scale' or 'responsive to change'.
&lt;/p&gt;
&lt;p&gt;
RDF and its related standards allow the decentralisation of attribute/property definition, while providing the tools to manage the resulting 'mess'.  With the combination of namespaces, RDFS, and assuming the provision of schema repositories, it becomes possible to allow global use and reuse of locally defined 'models'.  This is especially relevant when you consider that 'local' should be considered in both temporal and spatial senses - keeping the system responsive both to the differing needs of independent organisations, and the changing requirements of a single entity.
&lt;/p&gt;
&lt;p&gt;
The result is the need for two additional boxes in your architecture diagram.  The first, a vocabulary server that allows users to define their own vocabulary extensions, and makes those definitions available to applications and critically capable of management and eventual rationalisation.  The second is a metadata server that can store the resulting data and permit ad-hoc querying by applications, and the inferencing required by vocabulary rationalisation.  One of the reasons &lt;a href="http://www.mulgara.org/"&gt;mulgara&lt;/a&gt; exists is to provide the storage and query engine required by these components - and so I do enjoy having the chance to talk to people about it.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-8884653012674580607?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/8884653012674580607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=8884653012674580607' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/8884653012674580607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/8884653012674580607'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2007/08/rdf-document-repositories.html' title='RDF, Document Repositories'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-117142375642534111</id><published>2007-02-14T13:22:00.000+10:00</published><updated>2007-02-14T13:29:16.443+10:00</updated><title type='text'>The Effect of File Sharing on Record Sales: An Empirical Analysis</title><content type='html'>&lt;p&gt;
&lt;em&gt;Felix Oberholzer-Gee Harvard University and Koleman Strumpf University of Kansas&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;&lt;a href="http://www.journals.uchicago.edu/JPE/journal/issues/v115n1/31618/brief/31618.abstract.html"&gt;Abstract&lt;/a&gt;&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
&lt;blockquote&gt;
For industries ranging from software to pharmaceuticals and entertainment, there is an intense debate about the appropriate level of protection for intellectual property. The Internet provides a natural crucible to assess the implications of reduced protection because it drastically lowers the cost of copying information. In this paper, we analyze whether file sharing has reduced the legal sales of music. While this question is receiving considerable attention in academia, industry, and Congress, we are the first to study the phenomenon employing data on actual downloads of music files. We match an extensive sample of downloads to U.S. sales data for a large number of albums. To establish causality, we instrument for downloads using data on international school holidays. Downloads have an effect on sales that is statistically indistinguishable from zero. Our estimates are inconsistent with claims that file sharing is the primary reason for the decline in music sales during our study period.
&lt;/blockquote&gt;
&lt;/p&gt;&lt;p&gt;
In the &lt;a href="http://www.journals.uchicago.edu/JPE/papers.html"&gt;Journal of Political Economy&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;
Available in &lt;a href="http://www.journals.uchicago.edu/JPE/journal/contents/v115n1.html"&gt;Volume 115, Number 1, February 2007&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
From &lt;a href="http://arstechnica.com/news.ars/post/20070212-8813.html"&gt;Ars Technica&lt;/a&gt; via &lt;a href="http://www.lessig.org/blog/"&gt;Lawrence Lessig&lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-117142375642534111?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/117142375642534111/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=117142375642534111' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/117142375642534111'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/117142375642534111'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2007/02/effect-of-file-sharing-on-record-sales.html' title='The Effect of File Sharing on Record Sales: An Empirical Analysis'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-117136955536846164</id><published>2007-02-13T21:08:00.000+10:00</published><updated>2007-07-13T13:49:42.547+10:00</updated><title type='text'>Java generics and the covariance and contravariance of arguments</title><content type='html'>&lt;p&gt;
Well given we require 1.5 now for other reasons, and 1.5 does complain if you don't constrain generic classes I have finally bitten the bullet and started using generics.  Unfortunately I just got bitten by what I suspect is going to be a very common mistake - in this case by failing to properly consider the type equivalence of parametrised method calls.
&lt;/p&gt;
&lt;p&gt;
Consider the following code:
&lt;/p&gt;&lt;pre&gt;
public interface TestInterface { }

public class TestClass implements TestInterface { }

import java.util.ArrayList;
import java.util.List;

public class Test {
 private List&amp;lt;testclass&amp;gt; list;

 public TestInterface test() {
   list = new ArrayList&amp;lt;testclass&amp;gt;();
   list.add(new TestClass());

   return covariant(list);
 }

 public TestInterface covariant(List&amp;lt;testinterface&amp;gt; ilist) {
   return ilist.remove(0);
 }
}
&lt;/pre&gt;
Now there is absolutely no reason why this should not work.  It is trivially inferable that the above code treats ilist as covariant in the list-type - and that therefore this code is statically correct.
&lt;p&gt;&lt;/p&gt;&lt;p&gt;
Of course Java's typing has never been particularly smart. List&amp;lt;t1&amp;gt;.add(T1) is contra-variant in t1, and T2 List&amp;lt;t2&amp;gt;.get(int) is co-variant in t2; so the Java compiler is correct to infer that in the general case List&amp;lt;t1&amp;gt; and List&amp;lt;t2&amp;gt; are substitutable iff t1 == t2.
&lt;/p&gt;&lt;p&gt;
If we can't declare a generic parameter to be covariant in its type parameter we have   a serious problem - it means that any non-trivial algorithm involving collections is going to run afoul of this.  You might consider trying to cast your way around it:
&lt;/p&gt;&lt;pre&gt;
 public TestInterface test() {
   list = new ArrayList&amp;lt;testclass&amp;gt;();
   list.add(new TestClass());

   return covariant((List&amp;lt;testinterface&amp;gt;)list);
 }
&lt;/pre&gt;
but not surprisingly that didn't work.
&lt;pre&gt;
Test.java:11: inconvertible types
found   : java.util.List&amp;lt;testclass&amp;gt;
required: java.util.List&amp;lt;testinterface&amp;gt;
 return convariant((List&amp;lt;testinterface&amp;gt;)list);
                                       ^
1 error
&lt;/pre&gt;
If you continue to hack at it you might try a double cast via a non-generic List.
&lt;pre&gt;
 public TestInterface test() {
   list = new ArrayList&amp;lt;testclass&amp;gt;();
   list.add(new TestClass());

   return covariant((List&amp;lt;testinterface&amp;gt;)((List)list));
 }
&lt;/pre&gt;
This works but leaves us with the unchecked/unsafe operation warning:
&lt;pre&gt;
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
&lt;/pre&gt;
Now this is a perfectly reasonable warning - it is unchecked; it is unsafe; and more importantly it &lt;em&gt;does violate encapsulation&lt;/em&gt;.  The problem here is that the caller should not be defining the type invariants of the callee - that's the job of the method signature!
&lt;p&gt;&lt;/p&gt;&lt;p&gt;
The correct solution is to allow us to declare covariant() to be covariant in its argument; and fortunately Java does support this.
&lt;/p&gt;&lt;p&gt;
To declare an argument to be covariant in its type parameter you can use the extends keyword:
&lt;/p&gt;&lt;pre&gt;
 public TestInterface covariant(List&amp;lt;? extends TestInterface&amp;gt; ilist) {
   return ilist.remove(0);
 }
&lt;/pre&gt;
To declare an argument to be contravariant in its type parameter you use the super keyword:
&lt;pre&gt;
 public void contravariant(List&amp;lt;? super TestClass&amp;gt; clist, TestClass c) {
   clist.add(c);
 }
&lt;/pre&gt;
Without these two facilities generics would be badly broken, so I am glad Sun had the presence of mind to include them - btw if you are using Java 1.5 I strongly recommend you read the &lt;a href="http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf"&gt;Java Generics Tutorial&lt;/a&gt;
&lt;p&gt;&lt;/p&gt;&lt;p&gt;
As an aside it is worth noting that as Java includes a Top type 'Object', List is a common covariant type - sufficiently common that Sun has included a syntactic sugar for it, List.  Personally I'm not sure this was such a good idea, List would work anyway, and I think I would prefer to have kept the covariance explicit.
&lt;/p&gt;
&lt;p&gt;
Update: Corrected capitalisation error in initial java example.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-117136955536846164?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/117136955536846164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=117136955536846164' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/117136955536846164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/117136955536846164'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2007/02/java-generics-and-covariance-and.html' title='Java generics and the covariance and contravariance of arguments'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-117075020521407017</id><published>2007-02-06T18:11:00.000+10:00</published><updated>2007-02-06T18:28:14.206+10:00</updated><title type='text'>Five things to consider when writing a Mulgara Resolver</title><content type='html'>&lt;p&gt;
Ended up writing a longer response than I had planned to a query about &lt;a href="http://mulgara.org/pipermail/mulgara-dev/2007-February/000323.html"&gt;writing a resolver&lt;/a&gt; in &lt;a href="http://www.mulgara.org/"&gt;Mulgara&lt;/a&gt; today.  I'm putting it here to keep a handle to it as it does cover the basic structure of the resolve() method in reasonable detail.
&lt;/p&gt;&lt;p&gt;
First it is important to realise that resolvers *don't* return triples - they return Resolutions.  These are Tuples that provide bindings for the variables in the Constraint passed to resolve().  So in the case of &amp;lt;http://www.example.com/path/subpath&amp;gt; $predicate $object the resulting Resolution should have two variables ($predicate $object).  In the case of &amp;lt;../subpath&amp;gt; &amp;lt;http://www.schema.com#parent&amp;gt; $subpath it will have one ($subpath).
&lt;/p&gt;&lt;p&gt;
You should also be aware that a Resolution can be unevaluated!  It is not uncommon for bindings, required to evaluate the constraint, come from other parts of the query.  Consider the following where clause:
&lt;pre&gt;
$url $p $o in &amp;lt;rmi://localhost/server1#sample&amp;gt; 
and 
&amp;lt;myfile&amp;gt; &amp;lt;hasurl&amp;gt; $url
&lt;/pre&gt;
in this case your resolver will be asked to resolve ($url $p $o), return a Resolution that will later be passed the $url in the prefix argument to beforeFirst().  Evaluation would then occur either in beforeFirst() or in the calls to next() - we prefer it to happen in beforeFirst if the memory requirement isn't unreasonable, our algorithmic reasoning assumes a comparatively cheap next().
&lt;/p&gt;&lt;p&gt;
If you require that a particular variable be bound prior to final evaluation then you need to provide a MandatoryBindingAnnotation - this indicates to the join logic that it must ensure a specific binding is satisfied by other constraints in the query before you are evaluated (in this case $url).
&lt;/p&gt;&lt;p&gt;
It is also worth noting that due to the support of intervals and the resulting interaction with query transformations, the XSDResolver is quite complicated as resolvers go.  Without that a call to resolve consists of:
&lt;ol&gt;
&lt;li&gt;Obtaining the model (constraint.getModel()).&lt;/li&gt;
&lt;li&gt;Do any preparatory work, especially any work that might be able to prove the result Empty (or a singleton).&lt;/li&gt;
&lt;li&gt;If you can't prove the result empty (or singleton), defer further evaluation to the returned Resolution.&lt;/li&gt;
&lt;/ol&gt;
Then inside the Resolution you need to consider how you implement the following four key methods
&lt;dl&gt;
&lt;dt&gt;MandatoryBindingAnnotation&lt;/dt&gt;
&lt;dd&gt;are there any variables that *must* be bound for the deferred evaluation to terminate.&lt;/dd&gt;
&lt;dt&gt;DefinablePrefixAnnotation&lt;/dt&gt;
&lt;dd&gt;can you cheaply reorder the variables in the result (log n or less)&lt;/dd&gt;
&lt;dt&gt;ReresolvableResolution&lt;/dt&gt;
&lt;dd&gt;can you cheaply reresolve the constraint if additional information becomes available (again log n or less)  [note: this will become an Annotation like the other two in the Mulgara 1.2 dev-cycle]&lt;/dd&gt;
&lt;dt&gt;beforeFirst()&lt;/dt&gt;
&lt;dd&gt;you can ignore the suffixTruncation arg, but you can't ignore the prefix - these *are* the values of the first N variables of the resolution - if all the variables are passed as a prefix your only decision is 1 row or 0 - but most of the time you will be passed less than this.&lt;/dd&gt;
&lt;/dl&gt;

At this point you have either performed the evaluation, or you have setup the evaluation and deferred the rest to be done incrementally on each call to next().
&lt;dl&gt;
&lt;dt&gt;next()&lt;/dt&gt;
&lt;dd&gt;does whatever is required to ensure that calls to getColumnValue().&lt;/dd&gt;
&lt;/dl&gt;
There is only one Tuple class that defers evaluation beyond this point (the implementation of count()).  Naturally we don't want to go to the effort of evaluating an entire subquery until the user actually goes to use it - so we defer evaluation of the count() until the call to getColumnValue().
&lt;dl&gt;
&lt;dt&gt;getColumnValue()&lt;/dt&gt;
&lt;dd&gt;normally this is a matter of returning values calculated in either beforeFirst() or next() - occasionally this amounts to evaluating it but this is uncommon.&lt;/dd&gt;
&lt;/dl&gt;
&lt;/p&gt;&lt;p&gt;
The whole point of the Resolution/Tuples/beforeFirst/next bother is to implement lazy-evaluation in java.  We only scale to bignum-levels when all query evaluation is done on a call-by-need basis.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-117075020521407017?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/117075020521407017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=117075020521407017' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/117075020521407017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/117075020521407017'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2007/02/five-things-to-consider-when-writing.html' title='Five things to consider when writing a Mulgara Resolver'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-117041822827380653</id><published>2007-02-02T22:07:00.000+10:00</published><updated>2007-02-02T22:10:28.296+10:00</updated><title type='text'>Ok now this is too cool for words.</title><content type='html'>&lt;p&gt;If you are a fan of Pratchett you have to checkout &lt;a href="http://homepages.tesco.net/janefisk/discworld/discworld.htm"&gt;The Great A'Tuin as a wedding cake&lt;/a&gt;!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-117041822827380653?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/117041822827380653/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=117041822827380653' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/117041822827380653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/117041822827380653'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2007/02/ok-now-this-is-too-cool-for-words.html' title='Ok now this is too cool for words.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-116968506234948277</id><published>2007-01-25T10:17:00.000+10:00</published><updated>2007-01-25T10:31:02.370+10:00</updated><title type='text'>Umm, would you mind if we borrowed your DPP?</title><content type='html'>&lt;p&gt;&lt;em&gt;from &lt;a href="http://www.boingboing.net/"&gt;boingboing&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Finally a public official has the courage to &lt;a href="http://politics.guardian.co.uk/terrorism/story/0,,1997247,00.html"&gt;speak sense&lt;/a&gt;.
&lt;blockquote&gt;
"London is not a battlefield. Those innocents who were murdered on July 7 2005 were not victims of war. And the men who killed them were not, as in their vanity they claimed on their ludicrous videos, 'soldiers'. They were deluded, narcissistic inadequates. They were criminals. They were fantasists. We need to be very clear about this. On the streets of London, there is no such thing as a 'war on terror', just as there can be no such thing as a 'war on drugs'.

"The fight against terrorism on the streets of Britain is not a war. It is the prevention of crime, the enforcement of our laws and the winning of justice for those damaged by their infringement."
&lt;/blockquote&gt;
If this was the only sentiment I would applaud, but to see his respect for the rule of law gives me hope our nations can come through this intact.
&lt;blockquote&gt;
"We wouldn't get far in promoting a civilising culture of respect for rights amongst and between citizens if we set about undermining fair trials in the simple pursuit of greater numbers of inevitably less safe convictions. On the contrary, it is obvious that the process of winning convictions ought to be in keeping with a consensual rule of law and not detached from it. Otherwise we sacrifice fundamental values critical to the maintenance of the rule of law - upon which everything else depends."
&lt;/blockquote&gt;
There is no right, no principle, no aspect of our 'way of life' that isn't completely dependent on the rule of law.  Without rule of law every other guarantee, social contract, or bill of rights is moot - completely and absolutely unenforcable and thereby irrelevant.
&lt;/p&gt;&lt;p&gt;
Note to any political types who might read this: This is a vote swinger.  The courage to respect and maintain rule of law in the face of fear is my definition of leadership, and what I am looking for above all when deciding my vote.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-116968506234948277?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/116968506234948277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=116968506234948277' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/116968506234948277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/116968506234948277'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2007/01/umm-would-you-mind-if-we-borrowed-your.html' title='Umm, would you mind if we borrowed your DPP?'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-115813512090112179</id><published>2006-09-13T18:08:00.000+10:00</published><updated>2006-09-13T18:12:00.970+10:00</updated><title type='text'>Erlang in 5 seconds.</title><content type='html'>&lt;p&gt;
There was recently a thread on erlang-questions that discussed how you would present Erlang in 5 seconds.  In an unrelated thread it is possible Richard Carlsson managed to nail it:
&lt;blockquote&gt;
In most respects, Erlang _is_ a concurrent, nondestructive Lisp with
a Prolog-inspired syntax that focuses on pattern matching and rules.
&lt;/blockquote&gt;
&lt;/p&gt;
&lt;p&gt;
For my own reference he original email:
&lt;blockquote&gt;
&lt;pre&gt;
Nick Linker wrote:
I wonder why Erlang is not Lisp? I mean why inventors of Erlang chose
to create its own language instead of creating just ERTS-specific
library for LISP (or at least Scheme)?

Here are some reasons why Lisp might not be a perfect match to
the problem they wanted to solve:
 - no built-in concurrency
 - destructive updates abound (in Scheme, too)
 - no pattern matching

And if you're going to fix those things, you might as well use a syntax
that feels more comfortable to you. In particular, pattern matching
makes function definitions and selective receives much more readable,
which I assume was an important goal for the kind of industrial
applications that Erlang was created for.

In most respects, Erlang _is_ a concurrent, nondestructive Lisp with
a Prolog-inspired syntax that focuses on pattern matching and rules.

 /Richard
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-115813512090112179?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/115813512090112179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=115813512090112179' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/115813512090112179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/115813512090112179'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/09/erlang-in-5-seconds.html' title='Erlang in 5 seconds.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-115811145748307136</id><published>2006-09-13T11:26:00.000+10:00</published><updated>2006-09-13T11:37:37.513+10:00</updated><title type='text'>The Monad Laws</title><content type='html'>&lt;p&gt;
Every now and then I come across a post that explains a concept so clearly it is inspiring.  I'd like to thank Albert Lai for just such a post.  &lt;a href="http://haskell.org/haskellwiki/Monad_Laws"&gt;Re: [Haskell-cafe] Monad laws&lt;/a&gt;
&lt;blockquote&gt;
&lt;pre&gt;
Deokhwan Kim &lt;dk@xxxxx.xxx.ac.kr&gt; writes:
&gt;
&gt;What is the practical meaning of monad laws?
&gt;
&gt;  1. (return x) &gt;&gt;= f == f x
&gt;  2. m &gt;&gt;= return == m
&gt;  3. (m &gt;&gt;= f) &gt;&gt;= g == m &gt;&gt;= (\x -&gt; f x &gt;&gt;= g)

I offer to re-write the laws in do-notation.  (Please view with a
fixed-width (non-proportional) font.)

1. do { x' &lt;- return x            do { f x
      ; f x'               ==        }
      }

2. do { x &lt;- m             ==     do { m
      ; return x }                   }

3. do { y &lt;- do { x &lt;- m          do { x &lt;- m
                ; f x                ; do { y &lt;- f x
                }          ==             ; g y
      ; g y                               }
      }                              }

                                  do { x &lt;- m
                    using 3.14       ; y &lt;- f x
                           ==        ; g y
                                     }

I think in this notation everyone sees the laws as plain common sense.
If you do write a monad that doesn't follow some common sense, the
dire consequence (practical or theoretical) is obvious.

Just in case it is still not obvious to somebody...

When we see a program written in a form on the LHS, we expect it to do
the same thing as the corresponding RHS; and vice versa.  And in
practice, people do write like the lengthier LHS once in a while.
First example: beginners tend to write

  skip_and_get = do { unused &lt;- getLine
                    ; line &lt;- getLine
                    ; return line
                    }

and it would really throw off both beginners and veterans if that did
not act like (by law #2)

  skip_and_get = do { unused &lt;- getLine
                    ; getLine
                    }

Second example: Next, you go ahead to use skip_and_get:

  main = do { answer &lt;- skip_and_get
            ; putStrLn answer
            }

The most popular way of comprehending this program is by inlining
(whether the compiler does or not is an orthogonal issue):

  main = do { answer &lt;- do { unused &lt;- getLine
                           ; getLine
                           }
            ; putStrLn answer
            }

and applying law #3 so you can pretend it is

  main = do { unused &lt;- getLine
            ; answer &lt;- getLine
            ; putStrLn answer
            }

Law #3 is amazingly pervasive: you have always assumed it, and you
have never noticed it.  (To put it into perspective, you hardly notice
yourself breathing, but this only makes the practical meaning of
breathing more profound, not less.)

Whether compilers exploit the laws or not, you still want the laws for
your own sake, just so you can avoid pulling your hair for
counter-intuitive program behaviour that brittlely depends on how many
redundant "return"s you insert or how you nest your do-blocks.
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;/p&gt;
&lt;p&gt;
It is also worth reading apfelmus' followup for further elaboration on the intuition behind the monad laws.
&lt;blockquote&gt;
&lt;pre&gt;
Deokhwan Kim wrote:
&gt; But what practical problems can unsatisfying them cause? In other words,
&gt; I wonder if declaring a instance of the Monad class but not checking it
&gt; for monad laws may cause any problems, except for not being qualified as
&gt; a theoretical monad?

This question is likely to be a result of an unlucky introduction to
monads where they are introduced top down: "Hear ye, a monad, this is
some mystic thing obeying the spiritual laws 1.,2. and 3.", isn't it?
It is this way that monads get the attribute "theoretical".

Asking what the practical meaning of the monad laws might be is like
asking what the practical meaning of the laws for natural number
addition could be: what does
i)  a + (b+c) == (a+b) + c mean?
How can i understand
ii)  a + 0 == a ?
What does
iii)  a + b == b + a signify?

These question are unlikely to arise because you have an intuition of
what a natural number is: a number of bullets in sack, coins in your
pocket, people in the mailing-list etc. With this knowledge, you will
most likely not have any problems explaining the laws i),ii),iii) to
somebody else and most likely you will have not doubt about *why* they
must be true.



For monads, my intuition is as following: a value of type (M a) is an
action, something producing a value of type  a  and (or by) executing a
side-effect like drawing on the screen or screwing up the hard drive.


With the operator &gt;&gt;=, I can execute such actions in a specific
sequence. For the sequence, it is of course unimportant how i group my
actions: i can group actions act1 and act2 first and then postpend act3,
or i can group act2 and act3 first and then prepend it with act1.

To simplify writing down a formular corresponding to this fact, we
introduce the operator &gt;&gt; defined by
    act1 &gt;&gt; act2 = act1 &gt;&gt;= \x -&gt; act2
which sequences actions but for simplicity discards the computed value x
of type a. It is only the side-effect of act1 we are interested in.

Now, the thought about grouping written does as formular is just
    (act1 &gt;&gt; act2) &gt;&gt; act3  ==  act1 &gt;&gt; (act2 &gt;&gt; act3)
and this is the simplified version of law 3. Of course, we know that
this is coined "associativity".

The actual law 3 is just a formulation for &gt;&gt;= that takes proper care of
the intermediate calculation result x.


With  return x , we can create an action which computes the value x but
 has absolutely no side-effects.
This can also be stated in formulas, as Mr "return" explains:
1. "if i am prepended to guys doing side-effects, i give them the value
x but do not take any responsibility for side-effects happening"
   (return x) &gt;&gt;= (\y -&gt; f y) ==  f x
2. "if i am postponed to an action which computes a value x, i don't do
any additional side-effects but just return the value i have been given"
   m &gt;&gt;= (\x -&gt; return x)  ==  m
which is of course equivalent to
   m &gt;&gt;= return  ==  m



So to answer your question:
&gt; In other words, I wonder if declaring a instance of the Monad class
&gt; but not checking it for monad laws may cause any problems, except for not
&gt; being qualified as a theoretical monad?
A thing you declare to be an instance of the Monad class, but one that
does not fulfill the three laws above, simply does not match the
intuition behind a monad. I.e. your definitions of (&gt;&gt;=) and (return)
are most likely to be void of the intended meaning.
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-115811145748307136?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/115811145748307136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=115811145748307136' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/115811145748307136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/115811145748307136'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/09/monad-laws.html' title='The Monad Laws'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-115703902396453954</id><published>2006-09-01T01:34:00.000+10:00</published><updated>2006-09-01T01:46:17.163+10:00</updated><title type='text'>Why I prefer LALR parsers</title><content type='html'>&lt;p&gt;
I was asked on a mailing list why I prefer LALR to LL based parser generators.  I ended up spending enough time on it to justify posting it here.  Summary: &lt;em&gt;"Reduced complexity in the semantic analyser is well worth the 'cost' of thinking bottom-up in the parser."&lt;/em&gt;
&lt;/p&gt;
&lt;blockquote&gt;
How come you prefer LALR? What about LR(k)?
&lt;/blockquote&gt;
&lt;p&gt;
I haven't really found the need for the added expressiveness of LR(k); this combined with the dearth of good GLR and LR(k) generators for many languages means that I haven't ended up using one for a project yet.  When people write production generators (as opposed to experimental), they seem to be either LL(k) or yacc+.
&lt;/p&gt;&lt;p&gt;
I'm not surprised at the popularity of LL, as you say, if you're going to write your parser by hand you're going to use top-down, recursive decent - ie LL.  Consequently for people coming to the problem of parsing for the first time, they are much easier to visualise, and as you point-out consequently to debug.  I recently had to assist a colleague with a couple of sablecc[0] bugs that were a direct result of visualising the parse top-down, while using a bottom-up parser.
&lt;/p&gt;&lt;p&gt;
However once you've written a handful of parsers, the expressive limitations of LL(k), and the software engineering challenges top-down imposes on semantic analysis quickly teach you to appreciate LALR.  Consequently I do not voluntarily use LL parsers in new projects.
&lt;/p&gt;
&lt;blockquote&gt;
I prefer LL(k) as it generates code similar to that you'd write
yourself (top down parser) and that's useful when you are debugging.
LL(k) is quicker :). 
&lt;/blockquote&gt;
&lt;p&gt;
You're right, debugging of the parser is simpler with LL(k).  That of course is beside the point, as I mentioned in my original email, the parser is the easy stage - the hard part is the semantic analysis, and LL makes this tougher.  Simplifying the parser at the expense of the SA is false economy.
&lt;/p&gt;&lt;p&gt;
The added complexity derives from two places.  The first derives from the additional information available with non-terminal productions in bottom-up parsers.  Because bottom-up parsers reduce non-terminals after their children are fully parsed.  This additional information makes using S or L-attribute grammars feasible for the first stage of SA.  When working with LL I have come across three ways of dealing with this:
&lt;ol&gt;
&lt;li&gt;Don't use attribute grammars, and use gradually (ie. most of the time, partially) initialised parser-global mutable state.&lt;/li&gt;
&lt;li&gt;Use nested parsers as accumulators.&lt;/li&gt;
&lt;li&gt;Use a eulers walk to convert top-down into bottom-up by attaching the SA to the post-order events.&lt;/li&gt;
&lt;/ol&gt;
In my experience the general approach is a combination of 1 and 2 - and they both cause serious structural problems in the resulting code, which all manner of coupling and structural aliasing between the parser and the SA that complicate ongoing maintenance.  3 wastes alot of memory (although admittably that is less of a problem now), but more importantly you have thrown away the very reason you went LL(k) in the first-place - top-down parsing.
&lt;/p&gt;
&lt;p&gt;
The second source of complexity is the consequence of losing access to left-recursive grammars - which has two key impacts.
&lt;ol&gt;
&lt;li&gt;Elimination of left-recursion replaces one simple rule with two coupled rules.&lt;/li&gt;
&lt;li&gt;This elimination is achieved by converting left-recursion to right-recursion; which will always[4] convert an S-attribute grammar into an L-attribute grammar; and seriously complicate any L-attribute grammar.&lt;/li&gt;
&lt;/ol&gt;
&lt;/p&gt;&lt;p&gt;
This causes problems analogous to the interaction of non-associative operators with foldr.
&lt;br/&gt;
Consider the following grammar (where &lt;code&gt;n&lt;/code&gt; is a terminal matching &lt;code&gt;{digit}+&lt;/code&gt; )
&lt;pre&gt;
E -&gt; E - n | n
&lt;/pre&gt;
converted[1] becomes
&lt;pre&gt;
E -&gt; nT*
T -&gt; - n
&lt;/pre&gt;
"10 - 5 - 3" is then parsed:
&lt;ul&gt;
&lt;li&gt;L-recursive : &lt;code&gt;(((10) - 5) - 3)&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;R-recusive : &lt;code&gt;(10 (- 5 (- 3)))&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
Now of course SA can evaluate the R-form correctly, it just takes more work[2]; less intuitive code[3]; greater coupling; greater complexity.
&lt;/p&gt;&lt;p&gt;
LL parsers can't handle the L-recursive grammar, LR parsers can.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Reduced complexity in the SA is well worth the 'cost' of thinking bottom-up; seriously, it's not that difficult to do.&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
[1] The kleene star simplifies this a bit, using e for the empty match the classic conversion is&lt;pre&gt;
    E -&gt; nE'
    E' -&gt; - nE' | e&lt;/pre&gt;
See Aho et al for details.
&lt;/p&gt;
&lt;p&gt;
[2] The L-recursive SA is a trivial S-attribute grammar defined as
&lt;pre&gt;
E -&gt; E' - n { E.val := E'.val - n.val }
E -&gt; n      { E.val := n.val }
&lt;/pre&gt;
&lt;/p&gt;&lt;p&gt;
[3] In this case the L-recursive form is so trivial that the resulting R-form produces a trivial accumulator based SA.  However note that even at this basic level, we have converted a simple declarative form into a recursive form that is fundamentally more complex.  In cases where the L-form is naturally recursive, the resulting R-form invariably introduces mutable shared state, with it's attendant complications.
&lt;/p&gt;&lt;p&gt;
[4] I'm reasonably certain this is the case, I don't however have time to double check this.  Presumably someone will correct me if I'm mistaken here.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-115703902396453954?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/115703902396453954/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=115703902396453954' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/115703902396453954'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/115703902396453954'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/09/why-i-prefer-lalr-parsers.html' title='Why I prefer LALR parsers'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-114557706469320051</id><published>2006-04-21T08:56:00.000+10:00</published><updated>2006-04-21T09:51:23.750+10:00</updated><title type='text'>Open Recursion: a definition.</title><content type='html'>&lt;p&gt;
I've been asked a couple of times now about my use of "open recursion".  It's covered in some detail by Pierce in "Types and Programming Languages"; I've included the one paragraph definition he gives below.
&lt;blockquote&gt;
&lt;p&gt;
&lt;strong&gt;Open recursion.&lt;/strong&gt; Another handy feature offered by most languages with objects and classes is the ability for one method body to invoke another method of the same object via a special variable called &lt;code&gt;self&lt;/code&gt; or, in some langauges, &lt;code&gt;this&lt;/code&gt;.  The special behavior of &lt;code&gt;self&lt;/code&gt; is that it is &lt;em&gt;late-bound&lt;/em&gt;, allowing a method defined in one class to invoke another method that is defined later, in some subclass of the first.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Types and Programming Lanauges, Benjamin C. Pierce, 2002, MIT Press, pg 227.&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-114557706469320051?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/114557706469320051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=114557706469320051' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114557706469320051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114557706469320051'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/04/open-recursion-definition.html' title='Open Recursion: a definition.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-114550208531244457</id><published>2006-04-20T10:31:00.000+10:00</published><updated>2006-04-20T18:35:10.383+10:00</updated><title type='text'>What is Object-Oriented Programming</title><content type='html'>&lt;p&gt;
Ok, so I've spent the past few days ragging on various applications of object-oriented programming.  So what do I consider OOP good for?  Well the answer naturally depends on what you consider OOP to be.  So before I attempt to ask "What is it good for?", I will prepare the way by looking at "What is Object Oriented Programming"?
&lt;/p&gt;
&lt;p&gt;
The biggest problem with giving a definition for object-oriented programming is that there are so many to choose from.  Worse, the vast majority consist of little more than vague handwaving giving little or no thought to the existence of non-OO techniques.  Consider the &lt;a href="http://www.paulgraham.com/reesoo.html"&gt;list of features&lt;/a&gt; listed by Johnathan Rees on Paul Graham's site.
&lt;/p&gt;
&lt;p&gt;
Consider the first example. Encapsulation is not a distinguishing feature of OOP.  Not only is it common in numerous non-OO languages, but it is not supported by many OO languages including both Smalltalk and Python!  Moreover encapsulation is a friendly name given to existentially quantified types, which are the underlying theory used to understand &lt;em&gt;Modules&lt;/em&gt;.  Ie. when you see a feature offering encapsulation, what you are really seeing is a module/package system (possibly in disguise).  Yes that does mean that Java/C#/C++ classes are doing double duty as both a type definition AND a module system.  Yes that is the cause of several problems you are probably experiencing.  No it doesn't have to be that way, there are languages that successfully seperate the two orthoginal concepts.
&lt;/p&gt;
&lt;p&gt;
I make use of theory here because it allows me to avoid handwaving. Specifically it allows me to avoid the trap of promoting specific language features to the status of paradigm definition just because they are favoured, or even common in OOP languages.  Using this approach I can quickly eliminate Encapsulation, Protection, Ad hoc Polymorphism, Parametric Polymorphism, and Sum-of-Product-of-Function from Ree's list.  This leaves us with only "Everything is an object", "All you can do is send a message", Specification Inheritance, and Implementation Inheritance to consider.  So lets map these to theory and see what we have left:
&lt;dl&gt;
&lt;dt&gt;Everything is an object&lt;/dt&gt;
&lt;dd&gt;This is literally a meaningless phrase as either it is strictly a matter of syntax (2.add(3) vs. 2 + 3); or it is a matter of purity, at which point it begs the question.&lt;/dd&gt;
&lt;dt&gt;All You can do is send a message&lt;/dt&gt;
&lt;dd&gt;Message Passing.  You can take your pick of various algebras and calculi to model this.  &lt;a href="http://citeseer.ist.psu.edu/context/552/0"&gt;CSP&lt;/a&gt; was popular for a while; &lt;a href="http://www.amazon.com/gp/product/354066579X/sr=8-1/qid=1145513870/ref=pd_bbs_1/102-8567709-1780100?%5Fencoding=UTF8"&gt;Process Algebra&lt;/a&gt; has its admirers; but my favourate is the &lt;a href="http://www.amazon.com/gp/product/0521658691/sr=8-2/qid=1145501749/ref=pd_bbs_2/102-8567709-1780100?%5Fencoding=UTF8"&gt;pi-calculus&lt;/a&gt;.
&lt;/dd&gt;
&lt;dt&gt;Specification Inheritance&lt;/dt&gt;
&lt;dd&gt;This is subtype-polymorphism using subsumption.&lt;/dd&gt;
&lt;dt&gt;Implementation Inheritance&lt;/dt&gt;
&lt;dd&gt;Open Recursion.  Not alot of use if you don't have subtype-polymorphism as well, and proves difficult to model when you do.  The simplest treatments use a least-fixed-type operator applied to a 'self' abstraction.&lt;/dd&gt;
&lt;/dl&gt;
&lt;/p&gt;
&lt;p&gt;
Ultimately the above three concepts coalese into two conceptualisations of OOP.
&lt;/p&gt;
&lt;p&gt;
The first focuses on the 'object', considering them as identifiable, autonomous, finite automatons communicating via message-passing.  Conceptually we are talking about highly concurrent actor based models.  This approach is the once taken by Simula, Erlang, Pick, and friends.  However while it corresponds closest to the original conception of OOP, it is barely recognisable in modern mainstream OOP languages.  In fact these languages are more likely to be described as concurrency-oriented than object-oriented.
&lt;/p&gt;
&lt;p&gt;
The second focuses on the 'class', considering OOP in terms inheritance and subtyping.  Conceptually we are talking about languages that provide records containing function typed attributes that are parametised by a recursive 'self' parameter that provides for 'late-binding'.  The conventional way to model this theoretically is via Abardi and Cardelli's &lt;a href="http://www.amazon.com/gp/product/0387947752/102-8567709-1780100?n=283155"&gt;Object Calculus&lt;/a&gt; (or you could try one of the papers available online ie &lt;a href="http://citeseer.ist.psu.edu/304252.html"&gt;A Theory of Primitive Objects (second order systems)&lt;/a&gt; or &lt;a href="http://citeseer.ist.psu.edu/abadi96imperative.html"&gt;An Imperative Object Calculus&lt;/a&gt;).  Representitive languages include all the usual suspects: Java, C++, C#, Smalltalk, etc.
&lt;/p&gt;
&lt;p&gt;
While concurrent agents with message passing might be the original definition of OO, as mentioned above most programmers who consider themselves OO wouldn't recognise this as OO; certainly almost none of the languages traditionally considered OO would fit this definition.  So it is pointless to pursue it further.  That leaves us with a single definition.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Object Oriented Programming is any programming based on a combination of subtype polymorphism and open recursion&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Translated back into more common terms - programming based on a combination of
&lt;ol&gt;
&lt;li&gt;Polymorphic functions that accept as actual parameters values of any subtype of their formal parameters, and&lt;/li&gt;
&lt;li&gt;Late binding, based on a distinguished 'self' parameter to functions that provides access to attributes of a record/object based on its runtime type.&lt;/li&gt;
&lt;/ol&gt;
Which is consise, precise, and coincides with our intuition --- even if it does leave out a few 'traditional' aspects commonly included in definitions of OOP.  Now to produce an object oriented language you need to add &lt;em&gt;at least&lt;/em&gt; the idea of functions and function application without which you are not turing complete and you will need records, without which you can't define subtyping.  These don't belong to any paradigm rather they are what it means to be a programming language.  You probably want to add a store and references, but again these do not belong to OO rather they belong to the super-paradigm Iterative Programming.  There are all sorts of features you can add to your language but only two, subtype-polymorphism and open recursion, make you Object Oriented.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-114550208531244457?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/114550208531244457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=114550208531244457' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114550208531244457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114550208531244457'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/04/what-is-object-oriented-programming.html' title='What is Object-Oriented Programming'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-114540470832518119</id><published>2006-04-19T09:49:00.000+10:00</published><updated>2006-04-19T14:53:42.870+10:00</updated><title type='text'>Interpreter Pattern and Structural Recursion</title><content type='html'>&lt;p&gt;
I have previously discussed the flaws and limitations of the Visitor Pattern; criticised the Singleton Patterm as a global variable in disguise; and dismissed all but one of the rest as kludges to work around the GoF's languages-of-choice. That leaves the Interpreter.
&lt;/p&gt;
&lt;p&gt;
This is a critically important pattern, if you only learn one pattern, make it this one!  It is so fundamental to what we do to be different in kind from the other patterns in the book.  In fact it is so critical that Gamma et al would probably have been better off ignoring the other patterns and writing their book exclusively on the Interpreter.  In a very real sense this is exactly what Daniel Friedman did in "Essentials of Programming Languages" (EoPL).
&lt;/p&gt;
&lt;p&gt;
If nothing else, the fact that you can comfortably write an entire book &lt;em&gt;introducing the basics&lt;/em&gt; of the Interpreter Pattern is a good sign we're dealing with a different beast here to the rest of the GoF.  Can you imagine writing a 300 page book introducing the basics of the factory-method?
&lt;/p&gt;
&lt;p&gt;
The reason why the interpreter pattern is so important is that it amounts to designing a language, and language is our primary tool as programmers.  We solve problems with computers, ultimately we do so with sequences of opcodes passed to the execution unit of our cpus; but the number of concepts we can express in a single sentence in machine code is limited, and the amount of detail we can choose to ignore when it is irrelevant to our solution is minimal. The act of climbing the language stack, (machine code -&gt; symbolic assembly -&gt; macro assembly -&gt; C -&gt; libc -&gt; [java, Scheme, ML, etc]) is an exercise in increasing these two measures.  Note I included libc in that list.  I did that because language is the core abstraction being invoked in library, module, and macro systems as Kernighan and Pike discuss in "The Practice of Programming".
&lt;/p&gt;
&lt;p&gt;
Now for the bad news.  Yes the interpreter pattern is all goodness and light, but the unfortunately the sample implementation provided by GoF is crap.  It's crap for exactly the same reason the visitor pattern is an inappropriate approach for parse-tree manipulation.  This is a symbolic transformation, and as a problem is decidedly non-object-oriented.  I'll go into exactly what an object-oriented &lt;em&gt;problem&lt;/em&gt; looks like another time, but suffice to say that there is a good reason why LISP has survived 50 years, and the applicability of functional programming techniques to symbolic programming is a major part of it.
&lt;/p&gt;
&lt;p&gt;
The solution offered in Design Patterns is an excelent piece of OO design.  The problem: You have an AST you wish to execute.  The solution: encapsulate the knowledge of how each different node-type should be evaluated in an 'evaluate' method on each node-type's associated class.  Below is an example calculator implemented in Java using this exact design:
&lt;pre&gt;
$cat test/*.java

/**
 * test/Add.java
 */
package test;

public class Add implements Expression {
  private Expression lhs;
  private Expression rhs;

  public Add(Expression lhs, Expression rhs) {
    this.lhs = lhs;
    this.rhs = rhs;
  }

  public int calc() {
    return this.lhs.calc() + this.rhs.calc();
  }
}

/**
 * test/Div.java
 */
package test;

public class Div implements Expression {
  private Expression lhs;
  private Expression rhs;

  public Div(Expression lhs, Expression rhs) {
    this.lhs = lhs;
    this.rhs = rhs;
  }

  public int calc() {
    return this.lhs.calc() / this.rhs.calc();
  }
}

/**
 * test/Expression.java
 */
package test;

public interface Expression {
  public int calc();
}

/**
 * test/Main.java
 */
package test;

public class Main {
  public static void main(String[] args) {
    System.out.println(Integer.toString(
        new Mul(
          new Sub(new Num(6), new Num(2)),
          new Add(new Num(2), new Num(3))).calc()));
  }
}

/**
 * test/Mul.java
 */
package test;

public class Mul implements Expression {
  private Expression lhs;
  private Expression rhs;

  public Mul(Expression lhs, Expression rhs) {
    this.lhs = lhs;
    this.rhs = rhs;
  }

  public int calc() {
    return this.lhs.calc() * this.rhs.calc();
  }
}

/**
 * test/Num.java
 */
package test;

public class Num implements Expression {
  private int num;

  public Num(int num) {
    this.num = num;
  }

  public int calc() {
    return this.num;
  }
}

/**
 * test/Sub.java
 */
package test;

public class Sub implements Expression {
  private Expression lhs;
  private Expression rhs;

  public Sub(Expression lhs, Expression rhs) {
    this.lhs = lhs;
    this.rhs = rhs;
  }

  public int calc() {
    return this.lhs.calc() - this.rhs.calc();
  }
}
&lt;/pre&gt;
and indeed this does print '20' as expected.
&lt;/p&gt;
&lt;p&gt;
Compare this with the ML code below, or the far more complex interpreter on page 74 of EoPL, and the problem is immedately clear.  With symbolic transformation we are invariably performing 'structual recursion'.  We have a data-structure, that is indeed a &lt;em&gt;structure&lt;/em&gt;, defined recursively that is then processed by following the structure of the data, possibly performing an operation at each step.  Consequently it is the structure that is important in comprehending the code, and ensuring a perfect match between data-structure and code-structure that is required to get it right.  By scattering the code across multiple files, it makes it much more difficult to understand the &lt;em&gt;structure&lt;/em&gt; of the code, and impossible to verify that this matches the structure of the data without signifigant effort.
&lt;pre&gt;
$cat calc.ml

(* Calculator *)

type expression =
  | Num of int
  | Add of expression * expression
  | Sub of expression * expression
  | Mul of expression * expression
  | Div of expression * expression ;;

let rec calc expr =
  match expr with
    | Num n -&gt; n
    | Add (e1, e2) -&gt; calc e1 + calc e2
    | Sub (e1, e2) -&gt; calc e1 - calc e2
    | Mul (e1, e2) -&gt; calc e1 * calc e2
    | Div (e1, e2) -&gt; calc e1 / calc e2

let main () =
  print_int(calc(Mul(Sub(Num 6, Num 2), Add(Num 2, Num 3))));
  print_newline();
  exit 0 ;;
main() ;;
&lt;/pre&gt;
and it is now trivial to inspect the code and the data and verify that the structures are identical.  In fact it is so trivial the compiler will warn us of our mistake.
&lt;pre&gt;
$ diff calc.ml calc-broken.ml 15c15
&lt;     | Mul (e1, e2) -&gt; calc e1 * calc e2
---
&gt; (*    | Mul (e1, e2) -&gt; calc e1 * calc e2 *)
$ ocamlc -o calc-broken calc-broken.ml 
File "calc-broken.ml", line 11, characters 2-199:
Warning P: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
Mul (_, _)
$ ./calc-broken
Fatal error: exception Match_failure("calc-broken.ml", 11, 2)
&lt;/pre&gt;
Now if you are stuck in an OO-world then the closest you can get to the above is to use either the visitor pattern or dynamic double dispatch.  Not as neat, and a scary amount of boilerplate, but it works, and it is definately preferable to the example given in GoF; and when the time comes that you are not compelled to consign yourself to the OOP-only gulag you now know that there is something worth escaping to.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-114540470832518119?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/114540470832518119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=114540470832518119' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114540470832518119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114540470832518119'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/04/interpreter-pattern-and-structural.html' title='Interpreter Pattern and Structural Recursion'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-114534076576562689</id><published>2006-04-18T16:00:00.000+10:00</published><updated>2006-04-18T16:14:19.706+10:00</updated><title type='text'>Back working on Kowari.</title><content type='html'>&lt;p&gt;
I am very grateful that I have been able to obtain another contract to work full-time on Kowari, so we should be seeing several fixes, changes, and enhancements flow into kowari over the next 3 months.  The first installment is an enhancement to iTql to permit the convenient expression of compound constraints and existentials within the query.
&lt;pre&gt;
{ s p1 o1 : p2 o1,o2 in m}
  is expanded to 
s p1 o1 in m and 
s p2 o1 in m and 
s p2 o2 in m

  and
[ p1 o1 : p2 o1,o2 in m ] 
  is expanded to 
$av__X p1 o1 in m and 
$av__X p2 o1 in m and 
$av__X p2 o2 in m ; 

for some value of X
&lt;/pre&gt;
This syntax is derived directly from N3/SPARQL, with the only exception being that we use colons instead of semicolons to separate predicates because kowari uses ';' as a query seperator.
&lt;/p&gt;
&lt;p&gt;
Anyone doing large conjunctions on custom resolvers will be particularly pleased to see this, and this is my first step towards better custom resolver support in general.
&lt;/p&gt;
&lt;p&gt;
In other news I feel I should point people at the Netymon Public Repository which is currently home to any kowari improvements made by Netymon until such a time as the future of the sourceforge project is determined.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-114534076576562689?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/114534076576562689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=114534076576562689' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114534076576562689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114534076576562689'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/04/back-working-on-kowari.html' title='Back working on Kowari.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-114532749484318989</id><published>2006-04-18T11:29:00.000+10:00</published><updated>2006-10-09T23:14:23.886+10:00</updated><title type='text'>The perils of avoiding heresy (or "What are Design Patterns")</title><content type='html'>&lt;p&gt;
My last two posts have been rather critical of the Visitor Pattern as described in "Design Patterns" more commonly known as GoF (Gang of Four).  So the question is reasonably asked, do I consider the other patterns similarly flawed?  If anyone is interested in the answer, it's yes.  In fact rather than being subtitled "Elements of Reusable Object-Oriented Software", it should have been &lt;em&gt;"21 reasons C++ sucks; 1 embarassment; and an Abstract Syntax Tree"&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;
First the embarassment: Singleton.&lt;br/&gt;
This is a global variable.  It should be treated in your design as a global variable; a useful hack sometimes, but always undesirable.  Singleton is more honestly described as "Abusing your languages class system to provide namespacing for global variables".  Just say no.
&lt;/p&gt;
&lt;p&gt;
Regarding the 21 other patterns, let me just add that most of them apply to Java equally to C++, but Java simply wasn't a serious contender when the book was written; and of course the examples are mostly C++ (all of them except a few in smalltalk).
Ponder this question: Why isn't 'Constructor' a creational pattern?  Then ask yourself, why are the OO-community the only programming community to name the Factory Method, or Command patterns?  The answers are simple, but the ramifications profound.
&lt;/p&gt;
&lt;p&gt;
In a language with first-class constructors, the Factory Method Pattern consists of
&lt;pre&gt;
factory = MyClass.constructor
&lt;/pre&gt;
In a language with closures the Command Pattern consists of
&lt;pre&gt;
menuItem.clicked = lambda : ...do stuff...
&lt;/pre&gt;
In a langauge with constructors, the Constructor Pattern consists of
&lt;pre&gt;
obj = new MyClass()
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
The final pattern is the OO version of the fundamental 'design pattern', elsewhere known as 'language'.  The Interpreter Pattern was first applied, in it's non-OO form, during the 1950's, most famously in the development of symbolic assembly language, FORTRAN and Lisp.  Since then it has found wide application being used in such diverse domains as database-querying, and printf format strings.  The pattern is simultaneously both the most signifigant, cross-language, powerful pattern in Computer Science, and the biggest 'DUH' in the GoF's book.  Of course, as with Visitor, the pattern in GoF is a near perfect example of the results of trying to shoehorn a non-OO problem into an OO-design; however I'll leave analysis of that for another time.
&lt;/p&gt;
&lt;p&gt;
So if the book is predominately a catalogue of unfortunately necessary kludges around the semantic weaknesses of mainstream OO-languages, why do I still highly recommend it to new programmers?
&lt;/p&gt;
&lt;p&gt;
Well for starters, precisely because it is a catalogue of &lt;em&gt;necessary&lt;/em&gt; kludges.  The book does capture (with the exception of Singleton) good work arounds for the weaknesses a programmer is going to face when working with C++/Java/C# (and to a lesser extent Python/Ruby/Smalltalk/etc).  We all find ourselves needing to work in these languages from time to time, and it is well worth knowing cleaner kludges.
&lt;/p&gt;
&lt;p&gt;
Secondly, along with "Refactoring" by Martin Fowler, GoF provides the reader with a solid introduction to good OO design.  Combined, these two books will guide the new programmer into a solid understanding of classic object orientation.  Given OO is the dominant paradigm behind all the current mainstream languages (unless you consider VB mainstream), this is worthwhile.  That there are far better, cleaner, and safer alternative designs available outside the mainstream is beside the point when a new programmer is going to face Java or C# (or heaven forbid C++).  Where a skilled programmer will translate these alternatives into a clean non-OO implementation within a mainstream language (see previous discussion regarding Visitor pattern and parser generators); this is simply not a reasonable expectation of a new programmer who is still mastering their first or second language.
&lt;/p&gt;
&lt;p&gt;
Read them, learn them, even use them.  Still you should always remember, these are kludges, and there are generally better alternatives available - the proof of you skill as a programmer is you understanding of what they are.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-114532749484318989?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/114532749484318989/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=114532749484318989' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114532749484318989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114532749484318989'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/04/perils-of-avoiding-heresy-or-what-are.html' title='The perils of avoiding heresy (or &quot;What are Design Patterns&quot;)'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-114489209601859227</id><published>2006-04-13T11:11:00.000+10:00</published><updated>2006-04-13T14:11:10.400+10:00</updated><title type='text'>More on the visitor pattern</title><content type='html'>&lt;p&gt;
The primary reason I started this blog was that I occasionally spend non-trivial amounts of time contributing to mailing lists discussions.  Some of those emails approach short articles and I got fustrated having them disappear into list-archives, sometimes never to be seen again (even when I've gone looking for them).
&lt;/p&gt;
&lt;p&gt;
Not surprisingly my recent blog entry, and associated post to the kowari mailing lists has led to a need to respond with a more carefully reasoned, and less emotional defense than yesterdays rant.
&lt;/p&gt;
&lt;p&gt;
First it has been pointed out that I used the term Abstract Syntax Tree when it would be more correct to refer to the output of sablecc as a Concrete Syntax Tree.  I acknowledge this, although I have always found the distinction vague.  It always seems to rely on the semantics of the grammar not the syntax. The closest I've come to definition that doesn't make reference to semantics is: "An AST is a CST missing some bits"; which of course implies CST is a subtype of AST forall values of some == none.
&lt;/p&gt;
&lt;p&gt;
However as this post is not dealing specifically with sablecc, but rather with parser generators in general, and with their interaction with the visitor pattern in particular, I will continue to use the more general term AST as it is more appropriate given the existence of tools such as javacc that permit the definition of an AST directly within the grammar file.
&lt;/p&gt;
&lt;p&gt;
I was pointed at &lt;a href="http://nat.truemesh.com/archives/000531.html"&gt;http://nat.truemesh.com/archives/000531.html&lt;/a&gt; for a discussion of new features in sablecc to make the use of the visitor pattern more palateable.  Indeed these features are going to be useful, however they only demonstrate my point.
&lt;blockquote&gt;
    Defining the abstract syntax tree and writing transformations from to concrete to abstract tree
     is quite an effort, and then you have to write your own visitor classes to process that tree.
&lt;/blockquote&gt;
Exactly the same argument applies if what you are wanting is 3-address code, or a rmi-enabled Query object (which is want Kowari is generating).  What the author of sablecc is slowly learning is that the authors of cups, yacc, and antlr whose products he dismissed so casually in his thesis actually did know what they were doing.
&lt;/p&gt;
&lt;p&gt;
Ultimately the Lex -&gt; Parse -&gt; Semantic Analysis stage of a compiler is not suited to an OO based design, and no attempt to shoehorn this into an OO framework is going to be as effective as recognising this and working with the grain of the problem.  You can see this clearly illustrated if you look at the actual Parser.java file generated by sablecc.  It is not object oriented in the slightest, rather it is a massive automaton (itql has 205 states), with each state associated with a small fragment of functional code.  This accurately reflects the nature of the problem. That the the user is then presented an interface that ignores this underlying reality in favour of ideological purity is unfortunate.
&lt;/p&gt;
&lt;p&gt;
The only justification given is that it allows the semantic analysis to be seperated from the grammar defintion.  But then the seperation of the first stage SA from grammar is undesirable, so this is a moot point.  A stage-1 SA &lt;em&gt;must&lt;/em&gt; follow the exact shape of the productions in the grammar.  As structure is very awkward to keep synchronised, DRY dictates that this structure should be defined in exactly one place.  Moreover the as the parser is completely defined by the structure, don't think of the 'grammar' file as the parser's grammar; think of it as the stage-1 SA definition.  The parser just happens to be generated directly from a simple structural analysis of the SA definition. I have written numerous parsers, they cease being difficult when you stop trying to think of them in imperative terms, but consider them as declarative definitions of symbolic tree transformations.  Anyone having trouble with this concept should reread sections 5.1-5.4 of Aho/Sethi/Ullman (Dragon Book).
&lt;/p&gt;
&lt;p&gt;
Parsing is easy.  Semantics is not.  The visitor pattern results in a very clean elegant interface to the parser, and makes the parser writers life easy.  However it wasn't a fundamentally hard life to begin with, and the decision results in scattering the semantic analysis code as 1-3 line fragments across dozens of files (unless you do what kowari does and breaks encapsulation).  To the extent you follow the pattern, you need a visitor for each unique synthesised attribute.  What is generally a one line annotation on an EBNF grammar becomes an entire class.  If you allow apply() to return a synthesised attribute, you can normally reduce the number of classes by combining visitors. Be aware though that having used this approach myself the price is in maintainability and flexibility as you have to be very careful you avoid undesired interactions between the combined visitors.
&lt;/p&gt;
&lt;p&gt;
Parsing is only occasionally hard; Semantic Analysis is only occasionally easy.  We should not be trying to find ways of making parsing easier just because it is easy; rather we should be trying to find ways to make semantic analysis easier precisely because it is hard. We are dealing with a functional problem and trying to find an object-oriented imperative solution is working against the grain, and it leaves me wondering, "Why you would bother?".
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-114489209601859227?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/114489209601859227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=114489209601859227' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114489209601859227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114489209601859227'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/04/more-on-visitor-pattern.html' title='More on the visitor pattern'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-114475472353932340</id><published>2006-04-11T13:20:00.000+10:00</published><updated>2006-04-11T22:40:48.046+10:00</updated><title type='text'>Visitor Pattern and Trees Considered Harmful</title><content type='html'>&lt;p&gt;
I have just finished a very fustrating week fighting a parser generator implementing some syntactic sugar for &lt;a href="http://www.kowari.org/"&gt;Kowari&lt;/a&gt;.  The reason why it's been so fustrating is simply because it should have taken one day to implement, test, and document, except that the parser generator was sablecc.
&lt;/p&gt;
&lt;p&gt;
Now sablecc has been stable, featureful, and reasonably performant.  Documentation is a minor problem given that it really only consists of a tutorial and the author's masters thesis; still it's a LALR parser generator once you have an EBNF exactly how hard can it be?  As a parser generator sablecc works wonderfully.
&lt;/p&gt;
&lt;p&gt;
Unfortunately that's also where the trouble starts, because it's very rare for someone to only want a parser.  Generally someone is using a parser generator because they are writing some sort of compiler, and so the parser generator feeds into some sort of semantic analysis stage.  And this is where sablecc fails, cf. the topic of todays post.
&lt;/p&gt;
&lt;p&gt;
Sablecc generates an AST.  Sablecc &lt;strong&gt;always&lt;/strong&gt; generates an AST! And of course how does your hard working, OOP entrenched, lemming of an author support inspection of this tree?  Well as with all well behaved OOP lemmings the author parrots off in the true unquestioning drone of the acolyte, "The visitor pattern of course". Think I'm joking?  The thesis was called "SABLECC, AN OBJECT-ORIENTED COMPILER FRAMEWORK"!  At this point swearing would be appropriate.
&lt;/p&gt;
&lt;p&gt;
Let's step back and look at the problem we are actually trying to solve. We have an context-free grammar that describes how we can generate an abstract syntax tree from a given input.  Semantic Analysis is effectively a transform applied to the AST.  Now the nature of this transform is remarkably consistent across compilers.  Occasionally it amounts to a eulers walk over the tree, but generally it is a straight forward post-order traversal generating what are called 'Synthsised Attributes' at each production from it and it's children[0].  The result is called an 'Annotated Syntax Tree', and generally the attribute derivations are defined to ensure that the desired output of the semantic analyser is an attribute at the root of the AST.
&lt;/p&gt;
&lt;p&gt;
Attribute derivation defintions are routinely defined as code snippets that convert child attributes into production attributes.  In other words we have a series of functions that are dispatched on the AST node type, are called within the context of the results of the child production's functions, and are called as a post-order traversal.
&lt;/p&gt;
&lt;p&gt;
Finally we have the added advantage that each node in the AST corresponds to a reduction in the LALR bottom-up shift-reduce parser that is the ultimate goal of an LALR parser generator.  Being bottom-up, this is automatically a post-order sequence of reductions.  Consequently we can choose to forgo the generation of the AST altogether and associate the functions directly with the reductions if we so desire.  (and why wouldn't we?)
&lt;/p&gt;
&lt;p&gt;
Now generating an AST is sometimes desirable, for instance when you require the afore  mentioned eulers walk based traversal, or if you are wanting to unparse the AST back into source-code again later.  But regardless of if you generate an AST or not, &lt;strong&gt;most&lt;/strong&gt; compilations are a simple bottom-up generation of the root anntoation in an annotated syntax tree based on associating functions with AST-nodes/parser-reductions.
&lt;/p&gt;
&lt;p&gt;
So that is the problem we want to solve, and in the strictest possible sense it is fundamentally functional in nature.  This of course poses a serious problem to our aforementioned object-oriented-lemming, because the natural, straight forward solution is not object-oriented.  So the lemming spits out a tree and of course doesn't even need to think about the next step.  After all "the object-oriented way to traverse a tree is the visitor pattern", so we'll disregard the fact that the problem is functional in nature --- we have this hammer and by george if we aren't going to make this problem fit our solution.
&lt;/p&gt;
&lt;p&gt;
The visitor pattern is kludge used by programmers in a language that doesn't support multiple-dispatch to provide themselves with a static version of double-dispatch.  The cannonical example that was used by the GoF when they documented the pattern is tree traversal.  And ever since that fateful day no OOL has dared consider anything else (feh).  Note there is no mention of trees in the definition above.  Trees are a datastructure.  The visitor pattern is a language semantics idiom. &lt;strong&gt;THEY ARE NOT RELATED CONCEPTS!&lt;/strong&gt;  Maybe if you are implementing dynamic traversals over a static tree (which does require double-dispatch to do cleanly) you might consider the visitor pattern as a solution to THIS problem; but only if you are willing to bet the life of your first born to guarentee that you will never ever want to introduce a new tree-node type into your design.
&lt;/p&gt;
&lt;p&gt;
For LALR parsers using code definitions for synthesised attributes, this problem has been solved for decades.  Yacc got it right.  The limitations and difficulties that programmers have with yacc fall into 2 categories: Memory management - garbage collection neatly solves that problem; Conceptual vagueness - a tool can only rarely even help you understand the problem you are trying to solve.
&lt;/p&gt;
&lt;p&gt;
Why is this the right approach?  Because the attribute derivations are generally trivial calls to constructors or functions --- along the lines of foobar = new Foobar(token), or combined = combineFoobars(child1.foobar, child2.foobar).  And these derivations are intimately associated with individual productions (as discussed above).  Consequently it is extremely awkward to seperate the grammar definition from the attribute derivation definition, as they needs must have an identical structure, and hence seperation violates the DRY principle and makes debugging/enhancement a right royal pain.
&lt;/p&gt;
&lt;p&gt;
So why have I suffered this week?  Because OO-Lemmings can't be bothered to consider if OO is an appropriate paradigm for the problem that presents itself to us; and because of this unfortunate association of tree-traversal with the visitor pattern.  Now I can't do anything about the prevalence of lemmings that won't get me arrested, but please please please stop using the visitor pattern to traverse trees.
&lt;/p&gt;
&lt;p&gt;
[0] If an attribute derivation requires information from a parent or sibling then it is referred to as an 'Inherited Attribute', and this is when you require a dependency aware eulers walk instead of a post-order traversal.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-114475472353932340?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/114475472353932340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=114475472353932340' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114475472353932340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114475472353932340'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/04/visitor-pattern-and-trees-considered.html' title='Visitor Pattern and Trees Considered Harmful'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-114309364714443059</id><published>2006-03-23T16:00:00.000+10:00</published><updated>2006-03-23T16:00:47.156+10:00</updated><title type='text'>Amusing: seen on LtU</title><content type='html'>&lt;blockquote&gt;
Here's the condensed LtU guide to the static types vs dynamic types debate:

    * Haskell-vs-Scheme is an issue on which reasonable people differ.
    * Ruby-vs-Java is an issue on which unreasonable people differ. 

Everything else is details. 
&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-114309364714443059?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/114309364714443059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=114309364714443059' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114309364714443059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/114309364714443059'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/03/amusing-seen-on-ltu.html' title='Amusing: seen on LtU'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-113955092777394670</id><published>2006-02-10T15:46:00.000+10:00</published><updated>2006-02-10T15:55:27.783+10:00</updated><title type='text'>Hint to new programmers</title><content type='html'>&lt;p&gt;
So I'm working my way through code written by a recent grad.... this sucks!  So to all new programmers out there...
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;RETURN TAKES A PARAMETER FOR A REASON!&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Just because you CAN return void and use an object field as an implicit return parameter DOESN'T MEAN YOU SHOULD!
&lt;/p&gt;
&lt;p&gt;
....and I suppose some lawyer would decide it was murder.....
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-113955092777394670?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/113955092777394670/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=113955092777394670' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113955092777394670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113955092777394670'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/02/hint-to-new-programmers.html' title='Hint to new programmers'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-113797766502528133</id><published>2006-01-23T09:58:00.000+10:00</published><updated>2006-01-23T10:54:25.086+10:00</updated><title type='text'>Loops Considered Harmful  (personal reprise)</title><content type='html'>&lt;p&gt;
Paul Gearon posted a &lt;a href="http://gearon.blogspot.com/2006/01/loops-considered-harmful-yesterday.html"&gt;short rant&lt;/a&gt; on Java's verbosity and general clunkiness.  The problem is to write a function that takes a string and returns a string containing the distinct characters of that string in sorted order.  While Paul does provide a solution in java, he only alludes to the sort of function you might expect to write.  So I thought I might have a go at the problem:
&lt;/p&gt;

&lt;p&gt;
Assuming we have a string type, and a sorted-set in our standard library:
&lt;pre&gt;
(lambda str (reverse-list-&gt;string
                (sorted-set-fold (compose cons flip) '()
                     (string-fold insert (sorted-set) str))))
&lt;/pre&gt;
Note: The reverse reduces the complexity from O(n^2 log m) to O(n log m)&lt;br&gt;
3 lines.  No mess, no fuss.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-113797766502528133?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/113797766502528133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=113797766502528133' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113797766502528133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113797766502528133'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/01/loops-considered-harmful-personal.html' title='Loops Considered Harmful  (personal reprise)'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-113685388112882290</id><published>2006-01-10T09:53:00.000+10:00</published><updated>2006-01-10T10:44:41.186+10:00</updated><title type='text'>Trouble in Kowari-land</title><content type='html'>&lt;p&gt;
Times of transition are always hard, and cultures do not always mix without conflict.  The past year has been a time of transition for Kowari, as we have had to move from a close-knit circle of developers mostly working in the same room, to a distributed open-source community.  It has of course been complicated by the need to try and reach an understanding with the new copyright owners of much of the kowari codebase, Northrup Grumman.
&lt;/p&gt;
&lt;p&gt;
Yesterday I had the unpleasant duty of &lt;a href="http://sourceforge.net/mailarchive/forum.php?thread_id=9421085&amp;forum_id=38668"&gt;accepting&lt;/a&gt; the &lt;a href="http://sourceforge.net/mailarchive/forum.php?thread_id=9421086&amp;forum_id=38668 "&gt;resignation&lt;/a&gt; of a good &lt;a href="http://prototypo.blogspot.com/"&gt;friend&lt;/a&gt;, colleague, and co-developer/admin from the Kowari project after he received legal threats from Northrup.  I remember watching these sorts of tussles go down in my years within the OSS community.  I have always felt sympathy for those volunteers who find themselves in the way of corporate lawyers.  Now as the maintainer who has to sit and wait for NG's response I realise just how important the freedom in free-software really is.  The MPL 1.1 is now the only thing standing between me and the loss of the Kowari project.
&lt;/p&gt;
&lt;p&gt;
It's not really surprising that this story is starting to find its way onto the blogsphere.  I would like to thank the SOFA community for their &lt;a href="http://cyberborean.wordpress.com/2006/01/09/disturbing-news-from-kowari/#more-36"&gt;note&lt;/a&gt; of support.  In response to &lt;a href="http://clarkparsia.com/weblog/2006/01/09/is-northrup-grumman-smushing-kowari/"&gt;Clark Parsia's&lt;/a&gt; questions about the legal status of kowari:
&lt;ol&gt;
&lt;li&gt;The copyright in the vast majority of Kowari as of Jan 2005, and consequently the majority of Kowari now was owned by Tucana Technologies, and hence now by NG.  However the majority of the work done in 2005 was done by parties unassociated with NG, and this work is copyright the authors (or in some cases the parties that paid for the work).  Of particular note is the work done by Paul Gearon on the krule engine, and the work commissioned by the DSTO on the query rewriting.  The former particularly is perfectly capable of independent existence, and while it currently lives in the kowari sourcetree is not derivative.&lt;/li&gt;
&lt;li&gt;There have been no releases since Tucana went insolvent.  It took 6 months to reorganise after Tucana's fold, and another 3-4 months to prepare for release.  We were ready for release in November, however held off at the explicit (and inconvenient) request of NG in an effort to support there integration into the community.  I should be clear here; The 9th of January release date was requested by Northrup, and acceeded to by the Kowari administrators as a sign of good-faith.  We had originally planned to release 1.1 in November.&lt;/li&gt;
&lt;li&gt;IANAL, but my understanding of the MPL --- and my personal first-hand knowledge of the express intent of Tucana when the MPL was chosen as a license --- is that anyone who cares to has the right to take a snapshot of the sourceforge repository; label it MyKowariRelease1.1; and release it to the public.  And indeed if open-source means anything, it means the right to fork.  However at the present point in time, I am the administrator of the kowari project, and Northrup have the same right to fork from Kowari as anyone else does.&lt;/li&gt;
&lt;/ol&gt;
As is clear in Clark Parsia's blog post above, this uncertainty is hurting Kowari so I will do whatever I can to ensure it is resolved promptly.  All I can ask is to please be patient and lets see if we can't help Northrup to become a productive member of the opensource community.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-113685388112882290?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/113685388112882290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=113685388112882290' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113685388112882290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113685388112882290'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2006/01/trouble-in-kowari-land.html' title='Trouble in Kowari-land'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-113530270630170398</id><published>2005-12-23T11:45:00.000+10:00</published><updated>2005-12-23T11:53:28.556+10:00</updated><title type='text'>Humourous post on ocaml-list</title><content type='html'>&lt;p&gt;
Ok so the fact that I found this hilarious probably suggests I need my head examined... I still thought I'd share it though.
&lt;blockquote&gt;
&lt;pre&gt;
From: hars@bik-gmbh.de
Subject: Re: [Caml-list] Camlp4 in a Unix pipe
Message-Id: &lt;4383605A.7030309@bik-gmbh.de&gt;

Alessandro Baretta wrote:
Cool command line! How did you discover the '-' option? 

Out of habit? In the the unix shell monad, "foo &gt;&gt;= bar" happens to be written
as "foo | bar -" ("return" is written "cat", in case you wondered. So "Hey,
that is a useless use of cat!" really means 'Hey, you ignored the monad laws!")

Yours, Florian (time to go home, I know).
&lt;/pre&gt;
&lt;/blockquote&gt;
So yeah at this point I probably have to conceed I'm strange :).
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-113530270630170398?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/113530270630170398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=113530270630170398' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113530270630170398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113530270630170398'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2005/12/humourous-post-on-ocaml-list.html' title='Humourous post on ocaml-list'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-113471916672348057</id><published>2005-12-16T17:44:00.000+10:00</published><updated>2005-12-16T17:46:41.270+10:00</updated><title type='text'>Alternative Logics</title><content type='html'>&lt;p&gt;
Found via Google Blogs:  &lt;a href="http://sigfpe.blogspot.com/2005/10/alternative-logic.html"&gt;A Neighbourhood of Infinity: Alternative Logic&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
An interesting read.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-113471916672348057?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/113471916672348057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=113471916672348057' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113471916672348057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113471916672348057'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2005/12/alternative-logics.html' title='Alternative Logics'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-113469459679002313</id><published>2005-12-16T10:50:00.000+10:00</published><updated>2005-12-16T10:56:36.800+10:00</updated><title type='text'>Google Blogging and an interesting assertion.</title><content type='html'>&lt;p&gt;
Read &lt;a href="http://gearon.blogspot.com/2005/12/blogging-i-notice-new-post-on-google.html"&gt;Paul's post&lt;/a&gt; on the latest addition to Google Labs.  Installed &lt;a href="http://googleblog.blogspot.com/2005/12/new-firefox-extensions.html"&gt;Google Blogger&lt;/a&gt;, and WOW this is cool.  Naturally first stop was to check out etymon (disappointing), and second to visit sites I visit regularly.  Stumbled upon this quote recounted by &lt;a href="http://www.martinfowler.com/bliki/OOPSLA2005.html"&gt;Martin Fowler&lt;/a&gt;; would love to see some measurements.
&lt;blockquote&gt;
While I'm on the topic of concurrency I should mention my far too brief chat with Doug Lea. He commented that multi-threaded Java these days far outperforms C, due to the memory management and a garbage collector. If I recall correctly he said "only 12 times faster than C means you haven't started optimizing".
&lt;/blockquote&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-113469459679002313?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/113469459679002313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=113469459679002313' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113469459679002313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113469459679002313'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2005/12/google-blogging-and-interesting.html' title='Google Blogging and an interesting assertion.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-113443747356747993</id><published>2005-12-13T10:46:00.000+10:00</published><updated>2005-12-13T11:31:13.610+10:00</updated><title type='text'>Reading List Reprise</title><content type='html'>&lt;p&gt;
When I started this blog I posted my reading list, having recently finished &lt;a href="http://www.cis.upenn.edu/~bcpierce/tapl/"&gt;Types and Programming Languages&lt;/a&gt; I thought it was probably time to revisit the reading list.
&lt;dl&gt;
&lt;dt&gt;&lt;a href="http://www.cs.indiana.edu/eopl/"&gt;Essentials of Programming Languages&lt;/a&gt;, Daniel Freidman&lt;/dt&gt;
&lt;dd&gt;I finished this early in the year. Unfortunately I never did finish working the examples beyond the first couple of chapters.  There is some very interesting material in this book, particularly the last couple of chapters.&lt;/dd&gt;
&lt;dt&gt;&lt;a href="http://www.cis.upenn.edu/~bcpierce/tapl/"&gt;Types and Programming Languages&lt;/a&gt;, Benjamin Pierce&lt;/dt&gt;
&lt;dd&gt;I recently finished this (back in October), and loved it. This book is illuminating, and it definately achieved its goal. This book is a superb example of how to introduce a reader to a field, and provide the necessary preparation for accessing further works.&lt;/dd&gt;
&lt;dt&gt;&lt;a href="http://www.amazon.co.uk/exec/obidos/ASIN/0486678709/wwwlink-software-21/026-8559680-2190064"&gt;Introduction to Graph Theory&lt;/a&gt;, Richard J. Trudeau&lt;/dt&gt;
&lt;dd&gt;Read, and yes it was a fun book, but unfortunately did not ever really reach the depth I needed for it to be immediately applicable.  What I received from this book was mostly vocab.&lt;/dd&gt;
&lt;dt&gt;&lt;a href="http://www.sics.se/~joe/thesis/armstrong_thesis_2003.pdf"&gt;Making reliable distributed systems in the presesnce of software errors&lt;/a&gt;, Joe Armstrong&lt;/dt&gt;
&lt;dd&gt;I know Greg was annoyed by some trivial errors in some of the example code; however I am very glad I've read this thesis.  This is the closest I have seen to practical self-reparing systems. An gentle and easy read, it lays out a practicioners framework for designing reliable systems.  Highly recommended.&lt;/dd&gt;
&lt;dt&gt;&lt;a href="http://citeseer.ist.psu.edu/19489.html"&gt;The Polyadic PI Calculus : A Tutorial&lt;/a&gt;, Robin Milner&lt;/dt&gt;
&lt;dd&gt;Never did finish reading this as I ended up borrowing Milner's book and reading it instead. I'm curious to know if there has been any work on the relationship between PI-calculus processes and continuations.
&lt;dt&gt;&lt;a href="http://haskell.cs.yale.edu/yale/papers/haskellworkshop01/"&gt;Genuinely Functional User Interfaces&lt;/a&gt;, Antony Courtney, Conal Elliott&lt;/dt&gt;
&lt;dd&gt;As I said this is my primary area of interest, and it remains the long-term focus of my efforts. This paper remains a core influence on my interest in Type-Theory, Category Theory, and Language Semantics&lt;/dd&gt;
&lt;dt&gt;&lt;a href="http://haskell.cs.yale.edu/yale/papers/oxford02/"&gt;Arrows, Robots, and Functional Reactive Programming&lt;/a&gt;, Paul Hudak, Henrik Nilsson, Antony Courtney, John Peterson&lt;/dt&gt;
&lt;dd&gt;Opps, that's right I was going to read this one... I'll have to carry this one over to my new reading list...&lt;/dd&gt;
&lt;/dl&gt;
Other works read worthy of note include:
&lt;dl&gt;
&lt;dt&gt;&lt;a href="http://www.amazon.com/gp/product/0521663504/102-5832763-1324145?v=glance&amp;n=283155"&gt;Purely Functional Data Structures, Chris Okasaki&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;This book stands alongside my copies of Cormen, Date, Brooks, and K&amp;R without shame. Only a year old and already starting to wear from use. Personally I consider it essential reading for anyone serious about programming.  I am seriously considering buying a second copy so I can lend one without losing it from my library. This book is important enough that I will be posting seperately about it.&lt;/dd&gt;
&lt;/dl&gt;
Other things read and recommended:
&lt;ul&gt;
&lt;li&gt;I reread Fred Brooks, The Mythical Man-Month&lt;/li&gt;
&lt;li&gt;I reread Kernighan and Pike, The Practice of Programming&lt;/li&gt;
&lt;li&gt;I'm reading selected chapters of Benjamin Pierce, Advanced Topics in Types and Programming Languages, which is proving to be even better than TAPL due to it's focus on more practical issues (although it does rather assume you have at least a basic grasp of the theory in TAPL :)&lt;/li&gt;
&lt;/ul&gt;
Other things of interest include:
&lt;ul&gt;
&lt;li&gt;I'm half way through Joseph Landin, An Introduction to Algebraic Structures&lt;/li&gt;
&lt;li&gt;Several papers on Core Erlang (I'll track down citations if anyone is interested)&lt;/li&gt;
&lt;li&gt;Various standards including the RDF stack, and the XMPP RFC's&lt;/li&gt;
&lt;li&gt;Started Roy Crole, Categories for Types&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-113443747356747993?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/113443747356747993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=113443747356747993' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113443747356747993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113443747356747993'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2005/12/reading-list-reprise.html' title='Reading List Reprise'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-113435812100647298</id><published>2005-12-12T13:25:00.000+10:00</published><updated>2005-12-12T13:28:41.016+10:00</updated><title type='text'></title><content type='html'>Found on &lt;a href="http://lambda-the-ultimate.org/node/view/1155"&gt;Lambda&lt;/a&gt;
&lt;blockquote&gt;...  I'm guessing you won't like my new Redneck Scheme dialect, in which call-with-current-continuation is renamed y'all-come-back-soon-now-y'hear?...
Anton van Straaten&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-113435812100647298?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/113435812100647298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=113435812100647298' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113435812100647298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113435812100647298'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2005/12/found-on-lambda.html' title=''/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-113393154383738489</id><published>2005-12-07T14:48:00.000+10:00</published><updated>2005-12-07T15:27:22.473+10:00</updated><title type='text'>Kowari insert/select and blank-nodes.</title><content type='html'>&lt;p&gt;
I was asked recently to justify &lt;a href="http://www.kowari.org/"&gt;Kowari's&lt;/a&gt; decision to maintain blank-node identity across an insert/select command.  My response was along the lines of treating kowari as a 4-graph partitionable as rdf-compliant 3-graphs (actually technically a superset as we don't restrict the domains of subjects and predicates as rdf does).  At this point the entire 4-graph is within the scope of the existential, and consequently it is valid to retain blank-node identity between the rdf-partitions (kowari models).
&lt;/p&gt;&lt;p&gt;
However it did send me back to the &lt;a href="http://www.w3.org/TR/rdf-mt/"&gt;RDF-SEMANTICS&lt;/a&gt; spec again where I found the following in &lt;span style="font-style: italic;"&gt;1.5. Blank Nodes as Existential Variables&lt;/span&gt;
&lt;/p&gt;&lt;blockquote&gt;This effectively treats all blank nodes as having the same meaning as existentially quantified variables in the RDF graph in which they occur, and which have the scope of the entire graph. In terms of the N-Triples syntax, this amounts to the convention that would place the quantifiers just outside, or at the outer edge of, the N-Triples document corresponding to the graph. This in turn means that there is a subtle but important distinction in meaning between the operation of forming the union of two graphs and that of forming the merge. The simple union of two graphs corresponds to the conjunction ( 'and' ) of all the triples in the graphs, maintaining the identity of any blank nodes which occur in both graphs. This is appropriate when the information in the graphs comes from a single source, &lt;span style="font-style: italic;"&gt;or where one is derived from the other by means of some valid inference process, as for example when applying an inference rule to add a triple to a graph&lt;/span&gt;. Merging two graphs treats the blank nodes in each graph as being existentially quantified in that graph, so that no blank node from one graph is allowed to stray into the scope of the other graph's surrounding quantifier. This is appropriate when the graphs come from different sources and there is no justification for assuming that a blank node in one refers to the same entity as any blank node in the other.&lt;/blockquote&gt;
(emphasis added)
&lt;p&gt;&lt;/p&gt;
Later in &lt;span style="font-style: italic;"&gt;2. Simple Entailment between RDF graphs&lt;/span&gt; we come across the &lt;span style="font-style: italic;"&gt;Merging Lemma&lt;/span&gt;
&lt;blockquote&gt;Merging lemma. The merge of a set S of RDF graphs is entailed by S, and entails every member of S. [Proof]

This means that a set of graphs can be treated as equivalent to its merge, i.e. a single graph, as far as the model theory is concerned. This can be used to simplify the terminology somewhat: for example, the definition of S entails E, above, can be paraphrased by saying that S entails E when every interpretation which satisfies S also satisfies E.

The example given in section 1.5 shows that it is not the case, in general, that the simple union of a set of graphs is entailed by the set.

The main result for simple RDF inference is:&lt;/blockquote&gt;
This is relevant because an alternative view of kowari is as a set of named graphs.
&lt;/p&gt;
&lt;p&gt;
Last time I read this document was when I first started with Tucana, and hadn't heard of RDF before.  It is amazing how much more understandable the rdf-semantics document once you've spent some time working with RDF.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-113393154383738489?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/113393154383738489/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=113393154383738489' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113393154383738489'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/113393154383738489'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2005/12/kowari-insertselect-and-blank-nodes.html' title='Kowari insert/select and blank-nodes.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-112424732559324435</id><published>2005-08-17T12:10:00.000+10:00</published><updated>2005-08-17T13:17:44.330+10:00</updated><title type='text'>Persistent Datastructures</title><content type='html'>&lt;p&gt;
Many moons ago I wrote a short tutorial on pthreads.  It was adopted (with permission) by a number of universities to provide a brief introduction for their students doing pthread based coursework.  It strikes me as bizzare, but the tutorial remains the top google hit for 'pthreads tutorial'.  Consequently I periodically get requests for help with threading issues.
&lt;/p&gt;&lt;p&gt;
When I wrote the tutorial I was still enamoured with threads, an infatuation that didn't last very long :).  Since then, my experience working with pthreads, auto-parallelising compilers, java, erlang, kowari, and 10 years of professional programming, have fundamentally changed my perspective on how to approach concurrency.
&lt;/p&gt;&lt;p&gt;
&lt;ol&gt;
&lt;li&gt;Concurrency bad&lt;/li&gt;
&lt;li&gt;See 1&lt;/li&gt;
&lt;li&gt;Shared-memory concurrency very very bad&lt;/li&gt;
&lt;li&gt;see 3&lt;/li&gt;
&lt;/ol&gt;

However we can't always avoid concurrency so:

&lt;ul&gt;
&lt;li&gt;Process isolation good&lt;/li&gt;
&lt;li&gt;Message-Passing/Rendevous good&lt;/li&gt;
&lt;li&gt;Co-routine/Continuation good&lt;/li&gt;
&lt;/ul&gt;
Again, sometimes we can't avoid shared-memory concurrency if we want to make good use of some modern cpu architectures so:
&lt;ul&gt;
&lt;li&gt;Locks are bad - you've accepted all the pain and suffering associated with shared-memory concurrency, and now you're going to &lt;strong&gt;SERIALISE&lt;/strong&gt; operations!!&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;&lt;p&gt;
Assuming you are stuck using shared-memory threads, what do you do now?  Well first hope like hell you have a garbage collector.  If you don't it is going to hurt enough I would suggest you give up now and go back and reconsider the reasons why you discounted the other options above -- anything is better than this.  If you do have a garbage collector, start reading up on persistent datastructures.
&lt;/p&gt;&lt;p&gt;
Persistent datastructures are very important in safe efficient thread-based design because they don't require locking.  They are called persistant because they are immutable.  Once you have a reference to a structure that structure is guaranteed const.  What this means is that any method that would mutate an empherial (ie, what you are used to) structure returns a new structure.
&lt;/p&gt;&lt;p&gt;
As an example consider a list
&lt;pre&gt;
x = []              | x = null 
y = x.prepend(1)    | y = { 1, x }
z = y.prepend(2)    { z = { 2, y }
&lt;/pre&gt;
Now if you need the rest of your program to see the updated list you use some sort of reference cell.  The simplest is just a one element queue.  This is a classic reader-writer problem; except you don't have to worry about evicting readers before the writer does his thing.
&lt;pre&gt;
RefCell&lt;T&gt;:
  init(T data);   // Initialises the cell with data.  All subsequent access to data must originate with this cell.
  T read();       // Returns the current value of data (internally access is protected by the 'access lock').
  T writeLock();  // Obtains the 'write lock' (or blocks), and returns the current value of data.
  unLock(T data); // Updates the current value of data under the 'access lock', and releases the 'write lock'.
&lt;/pre&gt;
Note there is almost no contention for readers, no book-keeping, and once a reader has a reference to data, all further access to the structure is lock-free.
&lt;/p&gt;&lt;p&gt;
However take another look at it.  Step back and think about what this is and you will realise that what we have written here is a transaction based datastore.  What this means is that you can now go examine all your transaction management theory and introduce multiple-writers, lock-stealing, etc, et al.  Now as long as T is persistent, you are atomic, consistent, and isolated.  If you ensure unLock flushes the structure to disk you now have an ACID datastore (surprised? :).  Add consistency checks to the mutation operations and you can call it a database :).
&lt;/p&gt;&lt;p&gt;
Granted, without a garbage collector, memory management is a bitch.  The standard reference on persistent structures is Chris Okasaki.  A quick google will get you a fair way; however citeseer is the motherlode.  If you have access to a university library, I would lookup his book (Purely Functional Data Structures), which will save you alot of searching on citeseer :).
&lt;/p&gt;&lt;p&gt;
Another thing worth noting is that it is worth noting is that once you leave the ephemeral space, you need to start making decisions beyond the simple "Vector/List/Hash/Tree".  There are alot more tradeoffs to consider.  Do you really need the efficient random-access of a vector, or are you actually using it as a queue, or dqueue?  A persistent queue can be implemented with O(1) amortized operations, but the best I have been able to find (quickly) for a true 'vector' is log(i) access (i = index) &lt;a href="http://citeseer.ist.psu.edu/okasaki95purely.html"&gt; [citeseer]&lt;/a&gt;.  Just as importantly, a persistant queue is very simple, almost identical in fact to an efficient ephemeral queue; whereas a persistant random-access-list much more complicated than a vector.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-112424732559324435?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/112424732559324435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=112424732559324435' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/112424732559324435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/112424732559324435'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2005/08/persistent-datastructures.html' title='Persistent Datastructures'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-111783898409409487</id><published>2005-06-04T08:38:00.000+10:00</published><updated>2005-06-04T08:49:44.096+10:00</updated><title type='text'>Using Jabber as a communications framework</title><content type='html'>&lt;p&gt;
&lt;a href="http://www.symphonious.net/"&gt;Adrian Sutton&lt;/a&gt; asks about using Jabber as a communications framework for developing a bug-tracking/QA application.  Two items immediately spring to mind.
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://ll3.ai.mit.edu/program.html"&gt;ACME: Toward a LL Testing Framework for Large Distributed Systems&lt;/a&gt;&lt;br&gt; - Dana Moore and Bill Wright&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ejabberd.jabber.ru/"&gt;ejabberd&lt;/a&gt; and &lt;a href="http://www.erlang-projects.org/Public/projects/eai__esb/j-eai_1.0_beta_4/view"&gt;J-EAI&lt;/a&gt; - which uses it as it's message bus.&lt;/li&gt;
&lt;/ul&gt;
I haven't had any experience with jabber except as a casual user, however these are projects that have caught my eye as things I would like to investigate when/if I ever have time.  So Adrian, if you do check them out, let me know how you go :).
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-111783898409409487?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/111783898409409487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=111783898409409487' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/111783898409409487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/111783898409409487'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2005/06/using-jabber-as-communications.html' title='Using Jabber as a communications framework'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-111697862835107483</id><published>2005-05-25T09:49:00.000+10:00</published><updated>2005-05-25T09:50:28.356+10:00</updated><title type='text'>Silly old lady</title><content type='html'>&lt;p&gt;
&lt;a href="http://mlm.bpa.nu:8080/weblog/fun/experiment.writeback"&gt;There was an old lady&lt;/a&gt; who swallowed a bird;&lt;br&gt;
How absurd, to swallow a bird!&lt;br&gt;
She swallowed the bird to catch the spider&lt;br&gt;
That wriggled and jiggled and wiggled inside her.&lt;br&gt;
She swallowed the spider to catch the fly.&lt;br&gt;
But I dunno why she swallowed that fly -&lt;br&gt;
Perhaps she'll die&lt;br&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-111697862835107483?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/111697862835107483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=111697862835107483' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/111697862835107483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/111697862835107483'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2005/05/silly-old-lady.html' title='Silly old lady'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-110560975196988642</id><published>2005-01-13T19:37:00.000+10:00</published><updated>2005-01-13T19:51:47.406+10:00</updated><title type='text'>Long Time no See</title><content type='html'>&lt;p&gt;
I realise it has been almost two months since I last blogged, I can only plead two excuses for this lapse.  The first reason is that I have met an incredible woman and have dedicated a substantial amount of time recently in getting to know her better.  The second is that on the 26th of December, Tucana Technologies (my employer) closed its doors.  This is an incredible blow as without reservation, this was the best job I have ever had. I can only hope that I will be able to find something half as involving, challanging, and inspiring as my work on Kowari and RDF.  Anyway, unless I should suddenly find myself with employment I should be able to address some of the unfinished posts I have lined up for this blog over the next week or two.
&lt;/p&gt;
&lt;p&gt;
On that note, I have spent some time trying to install GHC under OSX 10.2, unfortunately the only install I have been able to find and install thus far is for 10.3.  If anyone out there knows of a package or install method for 10.2 it would be much appreciated.
&lt;/p&gt;
&lt;p&gt;
Finally if anyone is interested in employing a Senior Computer Systems Engineer with a strong background in metadata, RDF, and in the use and design of more languages than you can poke a stick at, feel free to contact me on andrae@humbug.org.au; CV available on request.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-110560975196988642?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/110560975196988642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=110560975196988642' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110560975196988642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110560975196988642'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2005/01/long-time-no-see.html' title='Long Time no See'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-110134750714378739</id><published>2004-11-25T10:10:00.000+10:00</published><updated>2004-11-25T11:51:47.143+10:00</updated><title type='text'>Well worth the time.</title><content type='html'>&lt;p&gt;
Went back and watched two of the &lt;a href="http://ll2.ai.mit.edu/"&gt;Little Languages 2 Workshop&lt;/a&gt; presentations.  Specifically Joe Armstrong and Todd Proebsting's presentations on "Concurrency Orientated Programming", and "Disruptive Programming Language Technologies" respectively.  I highly recommend both these talks to anyone who is the slightest bit interested in programming languages, or has any serious involvement in development.  It is just unfortunate that they are only available as real-video.  Still if you have r-v installed, they are both well worth the time.
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://web.mit.edu/webcast/ailab/mit-ll2-s1-09nov02-80k.ram"&gt;Concurrency Oriented Programming in Erlang (invited talk);
Joe Armstrong, Swedish Institute of Computer Science.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://web.mit.edu/webcast/ailab/mit-ll2-s2-09nov02-80k.ram"&gt;Disruptive Programming Language Technologies  (invited talk);
Todd Proebsting, Microsoft Research.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
Note these are links to the two sessions of the workshop.  It's convenient that both my favourite talks from this workshop happen to be first in each session.
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-110134750714378739?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/110134750714378739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=110134750714378739' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110134750714378739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110134750714378739'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/11/well-worth-time.html' title='Well worth the time.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-110117276300826402</id><published>2004-11-23T11:11:00.000+10:00</published><updated>2004-11-23T11:19:23.010+10:00</updated><title type='text'>The Theory of Classification.</title><content type='html'>&lt;p&gt;
&lt;a href="http://morenews.blogspot.com/"&gt;Andrew Newman&lt;/a&gt; came across this set of articles on OO theory.  I stumbled across them about a year ago, read the first few, changed jobs, and promptly forgot to go find them again.  I remember them as well worth the time to read.
&lt;blockquote&gt;
This is the first article in a regular series on object-oriented type theory, aimed specifically at non-theoreticians. The object-oriented notion of classification has for long been a fascinating issue for type theory, chiefly because no other programming paradigm has so sought to establish systematic sets of relationships between all of its types. Over the series, we shall seek to find answers to questions such as: What is the difference between a type and a class? What do we mean by the the notion of plug-in compatibility? What is the difference between subtyping and subclassing? Can we explain inheritance, method combination and template instantiation? Along the way, we shall survey a number of different historical approaches, such as subtyping, F-bounds, matching and state machines and seek to show how these models explain the differences in the behaviour of popular object-oriented languages such as Java, C++, Smalltalk and Eiffel. The series is titled "The Theory of Classification", because we believe that all of these concepts can be united in a single theoretical model, demonstrating that the object-oriented notion of class is a first-class mathematical concept!
&lt;/blockquote&gt;
Anyway, the links:
&lt;h5&gt;"The Theory of Classification"&lt;/h5&gt;
&lt;A HREF="http://www.jot.fm/issues/issue_2002_05/column5"&gt;1&lt;/A&gt;, 
&lt;A HREF="http://www.jot.fm/issues/issue_2002_07/column4"&gt;2&lt;/A&gt;, 
&lt;A HREF="http://www.jot.fm/issues/issue_2002_09/column4"&gt;3&lt;/A&gt;, 
&lt;A HREF="http://www.jot.fm/issues/issue_2002_11/column2"&gt;4&lt;/A&gt;, 
&lt;A HREF="http://www.jot.fm/issues/issue_2003_01/column2"&gt;5&lt;/A&gt;, 
&lt;A HREF="http://www.jot.fm/issues/issue_2003_03/column2"&gt;6&lt;/A&gt;, 
&lt;A HREF="http://www.jot.fm/issues/issue_2003_05/column2"&gt;7&lt;/A&gt;, 
&lt;A HREF="http://www.jot.fm/issues/issue_2003_07/column4"&gt;8&lt;/A&gt;, 
&lt;A HREF="http://www.jot.fm/issues/issue_2003_11/column2"&gt;9&lt;/A&gt;, 
&lt;A HREF="http://www.jot.fm/issues/issue_2004_01/column4"&gt;10&lt;/A&gt;, 
&lt;A HREF="http://www.jot.fm/issues/issue_2004_03/column1"&gt;11&lt;/A&gt;, 
&lt;A HREF="http://www.jot.fm/issues/issue_2004_05/column2"&gt;12&lt;/A&gt;, 
&lt;A HREF="http://www.jot.fm/issues/issue_2004_07/column2"&gt;13&lt;/A&gt;, 
&lt;A HREF="http://www.jot.fm/issues/issue_2004_09/column2"&gt;14&lt;/A&gt;, 
and &lt;A HREF="http://www.jot.fm/issues/issue_2004_11/column1"&gt;15&lt;/A&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-110117276300826402?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/110117276300826402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=110117276300826402' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110117276300826402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110117276300826402'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/11/theory-of-classification.html' title='The Theory of Classification.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-110050401393057584</id><published>2004-11-15T17:30:00.000+10:00</published><updated>2004-11-15T17:33:33.930+10:00</updated><title type='text'>Links found.</title><content type='html'>&lt;p&gt;
Just noting that I have updated the Arrows 'n Robots summary with links to citeseer and Wan's thesis page on the Yale-group pages.  Also wanted to dump the url to the Yale group here so next time I can find it more easily.
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://haskell.cs.yale.edu/yale/"&gt;http://haskell.cs.yale.edu/yale/&lt;/a&gt;
&lt;a href="http://haskell.cs.yale.edu/yale/publications.html"&gt;http://haskell.cs.yale.edu/yale/publications.html&lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-110050401393057584?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/110050401393057584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=110050401393057584' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110050401393057584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110050401393057584'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/11/links-found.html' title='Links found.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-110049021368820170</id><published>2004-11-15T13:38:00.000+10:00</published><updated>2004-11-15T13:43:33.686+10:00</updated><title type='text'>Category Theory</title><content type='html'>&lt;p&gt;
I have had a few people ask me to explain the utility and signifigance of category theory.  This proves rather difficult given I am a complete novice in this area myself; desprately trying to keep my head above water in the simplest of papers.  Still I found this paragraph useful, and I decided to post it here so I can find it again.
&lt;blockquote&gt;
Category theory unifies mathematical structures in a second, perhaps even more important, manner. Once a type of structure has been defined, it quickly becomes imperative to determine how new structures can be constructed out of the given one and how given structures can be decomposed into more elementary substructures. For instance, given two sets A and B, set theory allows us to construct their cartesian product A X B. For an example of the second sort, given a finite abelian group, it can be decomposed into a product of some of its subgroups. In both cases, it is necessary to know how structures of a certain kind combine. The nature of these combinations might appear to be considerably different when looked at from too close. Category theory reveals that many of these constructions are in fact special cases of objects in a category with what is called a "universal property". Indeed, from a categorical point of view, a set-theoretical cartesian product, a direct product of groups, a direct product of abelian groups, a product of topological spaces and a conjunction of propositions in a deductive system are all instances of a categorical concept: the categorical product. What characterizes the latter is a universal property. Formally, a product for two objects a and b in a category C is an object c of C together with two morphisms, called the projections, p: c → a and q: c → b such that, and this is the universal property, for all object d with morphisms f: d → a and g: d → b, there is a unique morphism h: d → c such that p o h = f and q o h = g. Notice that we have defined a product for a and b and not the product for a and b. Indeed, products and, in fact, every object with a universal property, are defined up to (a unique) isomorphism. Thus, in category theory, the nature of the elements constituting a certain construction is irrelevant. What matters is the way an object is related to the other objects of the category, that is, the morphisms going in and the morphisms going out, or, put differently, how certain structures can be mapped into it and how it can map its structure into other structures of the same kind.
&lt;/blockquote&gt;
Jean-Pierre Marquis, &lt;a href="http://plato.stanford.edu/entries/category-theory/"&gt;Stanford Encyclopedia of Philosophy: Category Theory&lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-110049021368820170?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/110049021368820170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=110049021368820170' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110049021368820170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110049021368820170'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/11/category-theory.html' title='Category Theory'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-110024258420852024</id><published>2004-11-12T16:55:00.000+10:00</published><updated>2004-11-15T17:30:08.556+10:00</updated><title type='text'>Arrows, Robots, and Functional Reactive Programming --- Summary</title><content type='html'>&lt;p&gt;
First some background reading from the bibliography I'll have to read eventually:
&lt;ul&gt;
&lt;li&gt;John Hughes.  &lt;a href="http://citeseer.ist.psu.edu/hughes98generalising.html"&gt;Generalising monads to arrows.&lt;/a&gt;  Science of Computer Programming, 37:67-111, May 2000&lt;/li&gt;
&lt;li&gt;Ross Paterson.  &lt;a href="http://citeseer.ist.psu.edu/paterson01notation.html"&gt;A Notation for Arrow-based Libraries&lt;/a&gt;.  In ICFP'01: International Conference on Functional Programming, pages 229-240, Firenze, Italy, 2001&lt;/li&gt;
&lt;li&gt;Zhanyong Wan. &lt;a href="http://haskell.cs.yale.edu/yale/papers/zwthesis/"&gt;Functional Reactive Programming for Real-Time Embedded Systems&lt;/a&gt;. PhD thesis, Department of Computer Science, Yale University, December 2002&lt;/li&gt;
&lt;li&gt;Zhanyong Wan, Walid Taha, and Paul Hudak.  &lt;a href="http://citeseer.ist.psu.edu/wan01realtime.html"&gt;Real-time FRP&lt;/a&gt;. In Proceedings of Sixth ACM SIGPLAN '00 Conference on Programming Language Design and Implementation (PLDI), pages 242-252, Vancouver, BC, Canada, June 2000. ACM, ACM Press.&lt;/li&gt;
&lt;li&gt;Zhanyong Wan, Walid Taha, and Paul Hudak. &lt;a href="http://citeseer.ist.psu.edu/wan02eventdriven.html"&gt;Event-driven FRP&lt;/a&gt;. In Proceedings of Fourth International Symposium on Practical Aspects of Declarative Languages. ACM, Jan 2002&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;&lt;p&gt;
Naturally when you are using FRP the core concept is that of the &lt;em&gt;signal&lt;/em&gt;.  So we define signal to have the type
&lt;code&gt;Signal a = Time -&gt; a&lt;/code&gt;, ie a function of Time returning a value of type 'a'; s(t).  The robot used throughout the paper is a simple differential drive with a handful of basic sensors.  So given two signals vr(t) -&gt; &lt;code&gt;vr::Signal Double&lt;/code&gt; and vl(t)&lt;code&gt;vl::Signal Double&lt;/code&gt; which are the velocities of the right and left wheels respectively we can write an reactive program for calculating the robots position:
&lt;pre&gt;
x     = (1 / 2) * integral ((vr + vl) * sin theta)
y     = (1 / 2) * integral ((vr + vl) * cos theta)
theta = (1 / l) * integral (vr - vl)
&lt;/pre&gt;
Of course the nice thing about this program is that it is a direct transliteration of the physics equations governing the motion of such a robot!  This is why FRP is important.
&lt;/p&gt;&lt;p&gt;
Such programs are clear, consise, correct, and unfortunately completely unworkable in the general case.  The problem is that while in the small (with simple toy examples) you couldn't get better than this, larger programs tend to lead to opaque space and time management with the resultant space and time leaks.  The focus on this paper is how to retain most of the legibility and good domain match of FRP while preventing leaks.  The FRP DSL developed in this paper is called Yampa, and it solves the leak problem by disallowing signals as first class values.  Instead signals are manipulated indirectly via set of combinators called &lt;em&gt;signal transformers&lt;/em&gt; or &lt;em&gt;signal functions&lt;/em&gt;.
&lt;pre&gt;
SF a b = Signal a -&gt; Signal b
&lt;/pre&gt;
This of course is very similar to the Haskell IO or State monads, and reminisent of Hutton's &lt;a href="http://citeseer.ist.psu.edu/hutton96monadic.html"&gt;Monadic Parser Combinators&lt;/a&gt;.  On the other hand, as presaged by the subject, the authors use &lt;a href="http://citeseer.ist.psu.edu/hughes98generalising.html"&gt;Arrows&lt;/a&gt; rather than Monads as the basis for their combinator library.
&lt;blockquote&gt;
A good analogy for this idea is a state or IO monad, where the state is hidden, and a program consists of a linear sequencing of actions that are eventually run by an interpreter or the operating system.  But in fact arrows are more general than monads, and in particular the composition of signal functions does not have to be completely linear
&lt;/blockquote&gt;
Specifically Arrow contains a fixedpoint combinator &lt;code&gt;loop&lt;/code&gt; which provides access to recursion.
&lt;/p&gt;&lt;p&gt;
The basic combinators include.
&lt;dl&gt;
&lt;dt&gt;lift function: &lt;code&gt;arr :: ( a -&gt; b ) -&gt; SF a b&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;Takes a normal function from type 'a' to 'b', and returns a signal-function/transformer that will convert a signal of type 'Signal a' to 'Signal b'.&lt;/dd&gt;
&lt;dt&gt;compose: &lt;code&gt; (&gt;&gt;&gt;) :: SF a b -&gt; SF b c -&gt; SF a c&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;Takes two signal functions and returns the composition of them&lt;/dd&gt;
&lt;dt&gt;tuping:  &lt;code&gt; (&amp;&amp;&amp;) :: SF a b -&gt; SF a c -&gt; SF a (b, c)&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;This permits you to take one signal and apply two functions to it similtaniously producing two signals both independently derived from the input.  And of course, once you have tupled outputs....&lt;/dd&gt;
&lt;dt&gt;tuple-transform: &lt;code&gt;(***) :: SF a b -&gt; SF c d -&gt; SF (a c) (b d)&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;Take two signal functions and returns a transformer that applies them to the respective signals in a tupled signal.&lt;/dd&gt;
&lt;/dl&gt;
Now arr, (&gt;&gt;&gt;), and (&amp;&amp;&amp;) form a minimal universal set.  However to fit the Arrow framework defined by Hughes, we use the original minimal set defined as arr, (&gt;&gt;&gt;), and first (which only takes one argument, and applies it to the first signal in the tuple, passing the second unchanged).
&lt;/p&gt;&lt;p&gt;
Some standard combinators provided:
&lt;code&gt;
&lt;ul&gt;
&lt;li&gt;identity :: SF a a&lt;/li&gt;
&lt;li&gt;constant :: b -&gt; SF a b&lt;/li&gt;
&lt;li&gt;time :: SF a Time&lt;/li&gt;
&lt;/ul&gt;
&lt;/code&gt;
Also the standard arrow combinators (remember, when thinking of FRP, just substitute 'SF' for 'a' in the type-sigs):
&lt;code&gt;
&lt;ul&gt;
&lt;li&gt;arr :: Arrow a =&gt; (b -&gt; c) -&gt; a b c&lt;/li&gt;
&lt;li&gt;arr2 :: Arrow a =&gt; (b -&gt; c -&gt; d) -&gt; a (b, c) d&lt;/li&gt;
&lt;li&gt;(&gt;&gt;&gt;) :: Arrow a =&gt; a b c -&gt; a c d -&gt; a b d&lt;/li&gt;
&lt;li&gt;(&lt;&lt;&lt;) :: Arrow a =&gt; a c d -&gt; a b c -&gt; a b d&lt;/li&gt;
&lt;li&gt;first :: Arrow a =&gt; a b c -&gt; a (b, d) (c, d)&lt;/li&gt;
&lt;li&gt;second :: Arrow a =&gt; a b c -&gt; a (d, b) (d, c)&lt;/li&gt;
&lt;li&gt;(***) :: Arrow a =&gt; a b c -&gt; a b' c' -&gt;a (b, b') (c, c')&lt;/li&gt;
&lt;li&gt;(&amp;&amp;&amp;) :: Arrow a =&gt; a b c -&gt; a b c' -&gt; a b (c, c')&lt;/li&gt;
&lt;li&gt;loop :: Arrow a =&gt; a (b, d) (c, d) -&gt; a b c&lt;/li&gt;
&lt;/ul&gt;
&lt;/code&gt;
Note that with loop, 'd' provides a channel for feedback, and hence recursion.  Notice also the strong streamish feel to the api.  I would like to see a Arrow based treatment of the unix-pipe concept.  I think it could result in a powerful scripting framework.  Also worth noting that some signal functions are stateful (integral is one example), and as such cannot be defined without access to the underlying signals (forbidden).  Hence they must either be pre-defined, or defined as a combination of pre-defined stateful signal functions.
&lt;/p&gt;&lt;p&gt;
So now convert the original FRP expression for x(t) to raw arrow-form:
&lt;pre&gt;
x = (1/2) * integral ((vr + vl) * cos theta)

given: vrSF :: SF RobotInput Velocity  (SF that extracts vr from a RobotInput)
   and vlSF :: SF RobotInput Velocity  (SF that extracts vl from a RobotInput)
   and thetaSF :: SF RobotInput Angle

xSF :: SF RobotInput Distance   -- Signal Function transforming RobotInput -&gt; Distance
xSF = (((vrSF &amp;&amp; vlSF) &gt;&gt;&gt; arr2 (+)) &amp;&amp;&amp; (thetaSF &gt;&gt;&gt; arr cos)) &gt;&gt;&gt; arr2 (*) &gt;&gt;&gt; integral &gt;&gt;&gt; arr (/2)
  or slightly more legible:
xSF = let v = (vrSF &amp;&amp;&amp; vlSF) &gt;&gt;&gt; arr2 (+)
          t = thetaSF &gt;&gt;&gt; arr cos
      in (v &amp;&amp;&amp; t) &gt;&gt;&gt; arr2 (*) &gt;&gt;&gt; integral &gt;&gt;&gt; arr (/2)
  which isn't all that much better.
&lt;/pre&gt;
So what we have gained above is the ability to mediate access to signals behind a reasonably safe, yet complete abstraction.  However the loss in clarity is striking.  Fortunately there is a proposed arrow-syntax that is similar to Haskell's monadic do-syntax.
&lt;pre&gt;
xSF' :: SF RobotInput Distance
xSF' = proc inp -&gt; do
  vr    &lt;- vrSF     -&lt; inp
  vl    &lt;- vlSF     -&lt; inp
  theta &lt;- thetaSF  -&lt; inp
  i     &lt;- integral -&lt; (vr + vl) * cos theta
  returnA -&lt; (i / 2)
&lt;/pre&gt;
Which while not as nice as the original FRP, has the triple advantage of being declarative, legible, and safe!
&lt;blockquote&gt;
It is important to note that the arrow syntax allows one to get a handle on a signal's &lt;em&gt;values&lt;/em&gt; (or &lt;em&gt;samples&lt;/em&gt;), but &lt;em&gt;not&lt;/em&gt; on the signals themselves.  In other words, first recalling that a signal function &lt;code&gt;SF a &lt;/code&gt; can be thought of as a type &lt;code&gt;Signal a -&gt; Signal b&lt;/code&gt;, which in turn can be thought of as type &lt;code&gt;(Time -&gt; a) -&gt; (Time -&gt; b)&lt;/code&gt;, the syntax allows getting a handle on values of type &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;, but not on values of type &lt;code&gt;Time -&gt; a&lt;/code&gt; or &lt;code&gt;Time -&gt; b&lt;/code&gt;.
&lt;/blockquote&gt;
Although I can't reproduce it here, Fig 2 is dramatic.  The correspondance between arrow-based signal-functions, and the signal-flow-diagrams shown is striking, and exciting.  I have been excited about the potential of FRP to liberate UI programming from the tyranny of the state-machine; Fig 2 amazed at the clarity available.  I am now, more than ever, convinced that I am on the right track.
&lt;/p&gt;&lt;p&gt;
Events diverge from Signals slightly in that while they are also temporal values, event's don't so much change from one value to another over time, as simply not exist between 'impulses' (in the signal processing sense).  In fact their is an isomorphism between impulse-streams vs. continuous-signals and event-streams vs. signals.  In previous papers the authors accepted this distinction as signifigant, and the two were treated seperately.  However by noting an isomorphism between &lt;code&gt;Event a&lt;/code&gt; and &lt;code&gt;Maybe a&lt;/code&gt; they are able to define a signal of type &lt;code&gt;Signal (Event b)&lt;/code&gt; ie. an &lt;em&gt;event stream&lt;/em&gt;, which becomes a signal that can be thought of as alternating between &lt;code&gt;Nothing&lt;/code&gt; and &lt;code&gt;Just a&lt;/code&gt;.  &lt;em&gt;A signal function of type &lt;code&gt;SF a (Event b)&lt;/code&gt; generates an event stream, and is called an &lt;/em&gt;event source.
&lt;/p&gt;&lt;p&gt;
There are a number of combinators for use with event-streams.  I'm just going to list them with minimal discussion, for more than that see the paper.
&lt;pre&gt;
switch, dSwitch :: SF a (b, Event c) -&gt; (c -&gt; SF a b) -&gt; SF a b  
        -- switch or delayed-switch.  Note the function from the event payload to a new SF a b.

rSwitch, drSwitch :: SF a b -&gt; SF (a, Event (SF a b)) b 
        -- note event is defined to carry an SF (possibly inserted by tag), this allows for recurring switch.

tag :: Event a -&gt; b -&gt; Event b

mergeBy :: (a -&gt; a -&gt; a) -&gt; Event a -&gt; Event a -&gt; Event a
lMerge, rMerge :: Event a -&gt; Event a -&gt; Event a
  -- Different ways of handing event collision.

-- Useful event-sources:

edge :: SF Bool (Event ())
  -- Obtain an edge trigged event-stream from a (Signal Boolean)

never :: SF a (Event b)
now :: b -&gt; SF a (Event b)
after :: Time -&gt; b -&gt; SF a (Event b)
repeatably :: Time -&gt; b -&gt; SF a (Event b)

-- Useful event-stream transform back to signal space:

hold :: a -&gt; SF (Event a) a
accum :: a -&gt; SF (Event (a -&gt; a)) (Event a)

accumHold :: a -&gt; SF (Event (a -&gt; a)) a
accumHold init = accum init &gt;&gt;&gt; hold init
&lt;/pre&gt;
&lt;/p&gt;&lt;p&gt;
Finally just to show how it goes together, the paper implements a few robot controllers.  First you implement your robot's controller as a signal function from RobotInput to RobotOutput.  So a FRP mapping from the robots sensor-signals to signals which the signal-function-processor will apply to the robot's actuators.  This controller is actually parametised by the robots properties, but that isn't surprising:
&lt;pre&gt;
type RobotController = RobotProperties -&gt; SF RobotInput RobotOutput.
&lt;/pre&gt;
Finally the FRP engine is implemented as a function from a controller to IO().  In the case of the RobotSimulator implemented for the paper, the engine also takes a second controller and a world description.
&lt;pre&gt;
runSim :: Maybe WorldTemplate -&gt; RobotController -&gt; RobotController -&gt; IO ()
&lt;/pre&gt;
Of course, returning the IO monad, this can be trivially instansated as as Haskell main function.
&lt;/p&gt;&lt;p&gt;
All in all a fascinating paper --- well worth the time to read.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-110024258420852024?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/110024258420852024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=110024258420852024' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110024258420852024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110024258420852024'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/11/arrows-robots-and-functional-reactive_12.html' title='Arrows, Robots, and Functional Reactive Programming --- Summary'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-110013843464490063</id><published>2004-11-11T11:38:00.000+10:00</published><updated>2004-11-11T13:44:29.710+10:00</updated><title type='text'>Arrows, Robots, and Functional Reactive Programming --- Prelude</title><content type='html'>&lt;p&gt;
Now this is a fun paper.  I mean, Category Theory, FRP, and you get to play with Robots!  What more could you want?  So lets take these three elements individually, and then I will try and summarise the paper.
&lt;dl&gt;
&lt;dt&gt;Category Theory&lt;/dt&gt;
&lt;dd&gt;My understanding of Category Theory is as a systematic treatment of abstraction and generalisation.  It allows us to take collections of mathmatical proofs and theorms that have the same structure/form, abstract them into a categorical notation, and then generalise them by providing &lt;em&gt;mappings&lt;/em&gt; from the categorial constructs to concepts in specific domains.  This is naturally of signifigant interest to type-theorists who treat programs as proofs and want access to the power of parametic/polymorphic types and functions without sacrificing rigor.  Arrows are a concept from category theory, a generalisation of Monads which beyond just lifting sequencing to a first-class object, allow parametised composition of sequencing.  This gives us the ability to support the more complex temporal sequencing of operations required by...
&lt;/dd&gt;
&lt;dt&gt;Functional Reactive Programming&lt;/dt&gt;
&lt;dd&gt;Or as that is a bit of a mouthful, FRP; is one of the most intuitive and widespread programming paradigms in use today.  It is an approach to programming that has been made so unobtrusive that four of the five other members of my family use it (in the form of a spreadsheet) without realising they are programming.  At a basic level, FRP introduces a new paramatised datatype into the language, the time-varying 'signal'.  By then permitting functions to be defined that accept these signals and return time-varying signals, you eliminate the shared-state, duplicated-logic, fragmented code paths, and explicit state-machines spawned by current, traditional event-driven approaches.  As a basis for comparison, just imagine comparing a traditional spreadsheet with one where to implement a formula for a cell you would have to attach an 'onChange' callback to each referenced cell that recalculated the value.
&lt;/dd&gt;
&lt;dt&gt;Robots&lt;/dt&gt;
&lt;dd&gt;Robots have a number of constraints that have not been traditionally considered strengths of functional programming.
&lt;ul&gt;
&lt;li&gt;Large numbers of discrete and continuous time-varying inputs that are most definately *note* referentially transparent.&lt;/li&gt;
&lt;li&gt;Real-time constraints that impose a requirement to avoid time-leaks, which encourages the use of imperative operation sequences.  Execution of which can be easilly suspended and resumed as higher priority tasks require resources.&lt;/li&gt;
&lt;li&gt;Extensive use of embedded controllers and limited compuational resources that place a premium on transparency of resource use and strict avoidance of space-leaks.&lt;/li&gt;
&lt;li&gt;A history of research largely based on low level system languages (ie MIML) and assembly, which makes for a hostile reception for many of the assumptions of higher-level functional programming&lt;/li&gt;
&lt;/ul&gt;
Of course FRP is a natural fit to the first problem.  However it has traditionally done so by trading off certainty and predictability in both time and space analysis.  This paper attempts to address these two problems in order to allow the exploitation of FRP's natural (theoretical) fit to robotics to be exploited.
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-110013843464490063?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/110013843464490063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=110013843464490063' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110013843464490063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110013843464490063'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/11/arrows-robots-and-functional-reactive.html' title='Arrows, Robots, and Functional Reactive Programming --- Prelude'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-110013698271945083</id><published>2004-11-11T11:36:00.000+10:00</published><updated>2004-11-11T11:38:14.006+10:00</updated><title type='text'> Bananas, Lenses, Envelopes, and Barbed Wire --- Finale</title><content type='html'>&lt;p&gt;
Finished the Bananas and Lenses paper on the weekend, along with another on FRP that I'll summarise later.  Section 4 takes the previous work based on Lists from section 2 and combines it with the category-theory results from section 3 to develop a theory of cata/ana/hylo/para -morphisms over arbitary datatypes.  Section 5 is a very brief extension to parametric types.
&lt;/p&gt;&lt;p&gt;
Unfortunately I simply don't have enough category theory to follow the discussion properly, let alone explain it here.  I think it is probably time to make another visit to Amazon and pick up a book or two on category theory.  I'm thinking probably Pierce's introduction, and possibly Crole's &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0521457017/ref=pd_sxp_elt_l1/002-7221337-9580044"&gt;"Categories for Types"&lt;/a&gt; on the basis of the review there.  I've already read Pierce's intro, and it is mercifully brief and yet even from a quick reading I found I remembered enough to follow fragments of the paper.  Unfortunately I found it too brief to allow me to learn enough to follow the rest :/.
&lt;/p&gt;&lt;p&gt;
Anyway, this paper was just for fun; fun was had; and I come away with a fresh perspective on recursion.  That counts as a win for me.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-110013698271945083?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/110013698271945083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=110013698271945083' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110013698271945083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/110013698271945083'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/11/bananas-lenses-envelopes-and-barbed.html' title=' Bananas, Lenses, Envelopes, and Barbed Wire --- Finale'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109703304424346463</id><published>2004-10-06T13:18:00.000+10:00</published><updated>2004-10-06T13:24:04.243+10:00</updated><title type='text'>Back.</title><content type='html'>&lt;p&gt;
Got back on saturday from a week long holiday helping run a holiday &lt;a href="http://www.computercamp.org.au/"&gt;computer-camp&lt;/a&gt; for high-school kids.  Now mostly recovered, and will probably blog a little on it later.
&lt;/p&gt;&lt;p&gt;
In the meantime thought I might quickly point at an interesting Wired article I found on &lt;a href="http://slashdot.org"&gt;slashdot&lt;/a&gt;.  Looking at one of the most interesting economic effects of the net, the growth of niche markets.  Recommended reading &lt;a href="http://www.wired.com/wired/archive/12.10/tail.html"&gt;The Long Tail&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109703304424346463?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109703304424346463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109703304424346463' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109703304424346463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109703304424346463'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/10/back.html' title='Back.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109565196223565687</id><published>2004-09-20T13:42:00.000+10:00</published><updated>2004-09-20T15:29:35.956+10:00</updated><title type='text'>Just how stupid do you think we are?</title><content type='html'>&lt;p&gt;
Seen on #prolog on freenode:
&lt;blockquote&gt;
&lt;pre&gt;
--&gt; Initial_KK (noemail@CPE00e0292573fd-CM400026081604.cpe.net.cable.rogers.com) has joined #prolog
&amp;lt;Initial_KK&amp;gt; hi All
&amp;lt;Initial_KK&amp;gt; what's this program do?
&amp;lt;Initial_KK&amp;gt; member(X,[X|_]).
&amp;lt;Initial_KK&amp;gt; member(X,[_|T]) :- member(X,T).
&lt;/pre&gt;
&lt;/blockquote&gt;
My guess?  &lt;em&gt;Your Homework you lazy slob&lt;/em&gt;.&lt;br/&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109565196223565687?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109565196223565687/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109565196223565687' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109565196223565687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109565196223565687'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/09/just-how-stupid-do-you-think-we-are.html' title='Just how stupid do you think we are?'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109539604190798427</id><published>2004-09-17T14:38:00.000+10:00</published><updated>2004-09-17T15:12:10.926+10:00</updated><title type='text'>Orthogonality == Flexible ? </title><content type='html'>&lt;p&gt;
As a core developer of &lt;a href="http://www.kowari.org"&gt;Kowari&lt;/a&gt; I am regularly faced with both the good and the unfortunate aspects of RDF.  One thing I continually run up against is the seemingly arbitary distinctions between subject, predicate, and object nodes.  In this particular case, I still can't find out why RDF won't permit blank nodes as predicates.  The same goes for Literals as subjects and predicates.  Having a string literal as a predicate or subject is a little strange, and almost certainly bad style, but a typed literal most certainly makes sense.  If I want to make statements about the number 5 (LT 6, GT 4, isPrime, isOdd, etc) currently we either have to use bnodes, or fake URIs, so we get:
&lt;pre&gt;
_:bnA &amp;lt;owl:sameAs&amp;gt; '5'^^&amp;lt;xmls:decimal&amp;gt;
_:bnB &amp;lt;owl:sameAs&amp;gt; '4'^^&amp;lt;xmls:decimal&amp;gt;
_:bnC &amp;lt;owl:sameAs&amp;gt; '6'^^&amp;lt;xmls:decimal&amp;gt;
_:bnA &amp;lt;lessThan&amp;gt; _:bnC
_:bnA &amp;lt;greaterThan&amp;gt; _:bnB
....
&lt;/pre&gt;
vs.
&lt;pre&gt;
'5'^^&amp;lt;xmls:decimal&amp;gt; &amp;lt;lessThan&amp;gt; '6'^^&amp;lt;xmls:decimal&amp;gt;
'5'^^&amp;lt;xmls:decimal&amp;gt; &amp;lt;greaterThan&amp;gt; '4'^^&amp;lt;xmls:decimal&amp;gt;
...
&lt;/pre&gt;
This is particularly important when you consider what's involved in merging two such documents.  Consider trying to insert a document containing primes, with a document containing prime-factors.  As we are currently forced to use bnodes, and bnode-refid's are only valid within a single document we are going to have to stuff around doing bnode unification.
&lt;/p&gt;&lt;p&gt;
Finally the fact that a URI is itself perfectly fine as a typed literal, suggests that all we really need is bnodes and typed literals (and a fair bit of syntactic sugar, but that's a serialisation issue, so we can ignore that for semantics).  At the end of the day, RDF is very cool, but I suspect a fully orthogonal triple-store is even cooler.  I suppose it's just fortunate that Kowari is an RDF-store built on top of a generic triple-store ;)
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109539604190798427?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109539604190798427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109539604190798427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109539604190798427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109539604190798427'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/09/orthogonality-flexible.html' title='Orthogonality == Flexible ? '/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109479711371491932</id><published>2004-09-10T11:34:00.000+10:00</published><updated>2004-09-10T16:18:33.716+10:00</updated><title type='text'>Reading</title><content type='html'>&lt;p&gt;
Sometimes life throws you a curve ball.  The past week I have been scrambling to help my parents respond to their landlords reasonable, yet highly inconvenient, desire to sell their house vacant possession.  Consequently my blog has been neglected of late.
&lt;/p&gt;&lt;p&gt;
I enjoy reading essays, and I have definately enjoyed reading some of &lt;a href="http://www.gladwell.com/archive.html"&gt;Malcolm Gladwell's&lt;/a&gt; contributions to the &lt;a href="http://www.newyorker.com/"&gt;New Yorker&lt;/a&gt; (Gladwell also wrote &lt;a href="http://www.gladwell.com/books.html"&gt;The Tipping Point&lt;/a&gt;, a book I am going to have to read that discusses the effects of non-linearity in social systems).  I particularly enjoyed &lt;a href="http://www.gladwell.com/2002/2002_04_29_a_blowingup.htm"&gt;Blowing Up&lt;/a&gt;, a look at non-linearity applied to the stock-market; &lt;a href="http://www.gladwell.com/2001/2001_07_02_a_ddt.htm"&gt;The Mosquito Killer&lt;/a&gt;, a facinating look at the anti-malaria campaigns of the 20th century, and DDT in particular; &lt;a href="http://www.gladwell.com/1997/1997_09_29_a_flu.htm"&gt;The Dead Zone&lt;/a&gt;, the hunt for the Spanish Flu; &lt;a href="http://www.gladwell.com/1997/1997_03_17_a_cool.htm"&gt;The Coolhunt&lt;/a&gt;, a curious look into the 'cool hunters', a profession I never realised existed.  Finally &lt;a href="http://www.gladwell.com/1996/1996_06_03_a_tipping.htm"&gt;The Tipping Point&lt;/a&gt;, an article written four years before the publication of Gladwell's book, a reminder that non-linearity is a fact of life, and humans are particularly bad at anticipating the ramifications.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109479711371491932?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109479711371491932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109479711371491932' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109479711371491932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109479711371491932'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/09/reading.html' title='Reading'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109412350028194668</id><published>2004-09-02T21:07:00.000+10:00</published><updated>2004-09-02T21:12:01.243+10:00</updated><title type='text'>Scheme Cookbook.</title><content type='html'>&lt;p&gt;
A few of my friends are also in the process of learning scheme.  Stumbled across this interesting site which will not doubt be useful: &lt;a href="http://schemecookbook.org/"&gt;The Scheme Cookbook&lt;/a&gt;.  &lt;a href="http://www.gbch.net/gjb/blog/"&gt;Greg&lt;/a&gt;, with his habit of implementing &lt;code&gt;cat&lt;/code&gt; will likely be particularly interested in the chapter on &lt;a href="http://schemecookbook.org/Cookbook/FileChapter#Files_and_Directories"&gt;Files and Directories&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109412350028194668?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109412350028194668/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109412350028194668' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109412350028194668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109412350028194668'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/09/scheme-cookbook.html' title='Scheme Cookbook.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109410899897040350</id><published>2004-09-02T16:52:00.000+10:00</published><updated>2004-09-02T17:12:23.266+10:00</updated><title type='text'>Paul Graham is at it again.</title><content type='html'>&lt;p&gt;
Paul Graham has published yet another essay. This time the topic is, not inappropriately, &lt;a href="http://www.paulgraham.com/essay.html"&gt;essays&lt;/a&gt;. As expected, the essay is worth the time to read --- if nothing else his essays are entertaining.  Graham presents the essay as a form of exploratory reasoning, attempting to differentiate it from the dissertation which he presents as far more rhetorical in nature.  To illustrate this he draws an analogy between the relationship between thought and essay and between conversation and dialogue.
&lt;blockquote&gt;
Fundamentally an essay is a train of thought-- but a cleaned-up train of thought, as dialogue is cleaned-up conversation. Real thought, like real conversation, is full of false starts. It would be exhausting to read. You need to cut and fill to emphasize the central thread, like an illustrator inking over a pencil drawing. But don't change so much that you lose the spontaneity of the original.
&lt;/blockquote&gt;
I couldn't help wondering if a better analogy would be the relationship between blog and essay.  I certainly don't take the time to polish my blog posts Paul takes to polish his essays.
&lt;/p&gt;&lt;p&gt;
I personally found it thought provoking, and if that is a common experience, I guess that would make it a successful essay. I certainly wasn't surprised to see it dwell on Graham's other bug-bear, the shocking state of the modern high-school curricula.  Still I find some irony in my main response: pondering the possibility that the internet may trigger a resurgence in the importance placed on rhetoric and the essayist in our society; this would certainly be no bad thing.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109410899897040350?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109410899897040350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109410899897040350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109410899897040350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109410899897040350'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/09/paul-graham-is-at-it-again.html' title='Paul Graham is at it again.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109402649837472958</id><published>2004-09-01T22:14:00.000+10:00</published><updated>2004-09-01T23:53:23.796+10:00</updated><title type='text'>Equality and Equivalence.</title><content type='html'>&lt;p&gt;
My &lt;a href="http://etymon.blogspot.com/2004/08/objectequals.html"&gt;previous entry&lt;/a&gt; on the implementation of Object.equals() has attracted some comment, but the principle response was from &lt;a href="http://www.intencha.com/adrian/000214.php"&gt;Adrian Sutton&lt;/a&gt;, who objected to my example of a buggy equals implementation.
&lt;/p&gt;&lt;p&gt;
In one respect his criticism is valid; in general a subclass should delegate to its superclass for inheritited state equality.  To do otherwise is to break encapsulation, and duplicate code.  On the otherhand his complaint misses the point:
&lt;blockquote&gt;
Class B is incorrectly assuming that it knows how to compare class A's data, and more importantly class B is changing the behavior of A in a way that is not compatible with the original model. Essentially, class A defines equality as having the same n1 values and class B &lt;em&gt;is in the wrong for changing that&lt;/em&gt;.  [emph added]
&lt;/blockquote&gt;
What Adrian misses is that if B is unable to meaningfully extend A's definition of equality then A should indicate that by declaring its implementation &lt;code&gt;final&lt;/code&gt;, in the absence of a final declaration, B is entitled to extend it.  I give an example of a meaningful use of final/instanceof in the Shape/Circle/Ellipse example at the end of the post, which I chose as it conveniently demonstrates all three cases associated with appropriate use of instanceof:
&lt;ol&gt;
&lt;li&gt;Abstract class implementing equals using instanceof to allow proper delegation of equality in subclasses.&lt;/li&gt;
&lt;li&gt;Extensible concrete class, uses instanceof to allow subclassing; equals declared final to enforce contract&lt;/li&gt;
&lt;li&gt;Subclassing the concrete class, overriding accessors permitting inherited (unoverridable) equals method to operate correctly (besides meeting the superclass contract ;).&lt;/li&gt;
&lt;/ol&gt;
On the other hand Adrian is mistaken when he suggests that the use of getClass() in equals is a bug.  There are two flaws with his reasoning.  The first arises from a confusion between syntax and semantics. Adrian offers a code fragment, suggesting that it would need A to use instanceof for correctness:
&lt;blockquote&gt;
&lt;pre&gt;
class C extends A {
  public getValue() {
    return n1;
  }
}
&lt;/pre&gt;
&lt;/blockquote&gt;
The confusion is in thinking this defines a new class.  This is a discussion of semantics, hence any class offered as a counter example must needs be a new class semantically, while the above is strictly syntax.  The easiest way to approach the semantics of a class is as a function constructing independent, concurrent, finite automata.  Now C doesn't define any new states, and doesn't define any new behaviour (state transitions), semantically then it doesn't define a new class --- mathmatically, C is still isomorphic up to congruence with A, so in a very real sense they are the same class.  What C actually defines is a function. A new, if rather clumsy, projection on A returning n1.  I had better make it clear that I'm not suggesting there is a non-clumsy way of doing this, rather that the reason why it is valid to want an C to be equivalent to a A is that C &lt;strong&gt;doesn't define a new class&lt;/strong&gt;, just a new function.  Hence it is a completely different case to B, which &lt;strong&gt;is&lt;/strong&gt; a non-congruent class.  If you have a concrete class that must support subclassing, instanceof &lt;em&gt;is a bug&lt;/em&gt;.
&lt;/p&gt;&lt;p&gt;
Moreover this is exactly what we would expect when we consider what it actually means for two objects to be equivalent.  Remember, an object is an  FA, and as such there is a well established body of work on the meaning of equivalence, anyone interested should read up on simulation and &lt;a href="http://cliki.tunes.org/Bisimulation"&gt;bisimulation&lt;/a&gt;.  Informally however the key is recognising that the bundling of state and behaviour provided by an object is not just something we get to ignore when it becomes inconvenient, at least not without losing correctness.  That if we are serious about OO, we are not just answering the question "are we currently in the same state?", but "are we in the same state, and will we remain in the same state in response to the same stimula?".  In other words, it doesn't matter that B.n1 == A.n1, if A and B have different behaviours &lt;strong&gt;they aren't the same object&lt;/strong&gt;.
&lt;/p&gt;&lt;p&gt;
It becomes particularly important to recognise this when you face the prospect of also implementing Comparable.  The problem here is that the contract for compareTo is that of a Total Order. The best you can manage on &lt;code&gt;A U B&lt;/code&gt; is a Pre-order, and once again you are left with the prospect of subtle and obscure bugs.  From the javadoc for Comparable:
&lt;blockquote&gt;
This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method.
...
 For the mathematically inclined, the relation that defines the natural ordering on a given class C is:
&lt;pre&gt;
       {(x, y) such that x.compareTo((Object)y) &lt;= 0}.
&lt;/pre&gt;
The quotient for this total order is:
&lt;pre&gt;
       {(x, y) such that x.compareTo((Object)y) == 0}.
&lt;/pre&gt;
It follows immediately from the contract for compareTo that the quotient is an equivalence relation on C, and that the natural ordering is a total order on C. When we say that a class's natural ordering is consistent with equals, we mean that the quotient for the natural ordering is the equivalence relation defined by the class's equals(Object) method:
&lt;pre&gt;
     {(x, y) such that x.equals((Object)y)}.
&lt;/pre&gt;
&lt;/blockquote&gt;
Yet after all this, I do share Adrian's pain in this.  The unfortunate fact is that if the author implemented A.equals properly, but forgot to include an accessor to A.n1, there is no clean way of gaining access to it.  If you do find yourself in this fix, you are left with either direct bytecode hacking (the JVM doesn't know about the access permissions, so you can just access n1 directly), or package injection (if n1 doesn't have private scope).  Alternatively, if the author has followed Adrian's advice, it becomes impossible to implement B correctly, and as Adrian's use of instanceof is wrong at a semantic level, no amount of bytecode hackery will save you.
&lt;/p&gt;&lt;p&gt;
So yet again we come back to my original point.  Either you are implementing an abstract class; or you are writing a concrete class and can support either subclass equivalence, or polymorphic equality. "But I need both"!? Tough; Java doesn't support both, and a good engineer knows to work within the limitations of their tools.  That a sizable segment of the java community continues to ignore the limitations of their language by presenting incorrect code, pretending that both are achievable, is a sad indictment on the state of that community.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109402649837472958?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109402649837472958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109402649837472958' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109402649837472958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109402649837472958'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/09/equality-and-equivalence.html' title='Equality and Equivalence.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109385010030503691</id><published>2004-08-31T23:57:00.000+10:00</published><updated>2004-08-31T23:56:39.993+10:00</updated><title type='text'>Bananas, Lenses, Envelopes, and Barbed Wire --- Section 3</title><content type='html'>&lt;p&gt;
Apparently the paper gives all it's definitions in terms of the category CPO (Complete Partial Orders);  not entirely sure what the difference is between a complete and an incomplete partial-order is, so the signifigance probably escapes me.  Alot of this section is also reminisent of Piece's &lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0262660717/ref=wl_it_dp/104-1402038-0575107?%5Fencoding=UTF8&amp;coliid=I3LIQSAAKRVKKC&amp;v=glance&amp;colid=3TNDFEPMAEVFH"&gt;Introduction to Category Theory&lt;/a&gt;, so I should probably go back and reread that.
&lt;/p&gt;&lt;p&gt;
Functors: I remember functors being fun reading in Pierce.  In this case we are interested in bifunctors and monofunctors; being types into types and functions into functions; and just functions into functions respectively.  Both cases preserve id and compose.
&lt;/p&gt;&lt;p&gt;
Products: Standard category fare.  We have the bifunctor (at least I assume it's a bifunctor, the paper dosn't say, but it meets the defn' above) || which takes two types and maps to the type of pairs of those two types (the paper's example: D||D' = {(d,d') | d &lt;- D, d &lt;- D'} --- I'm using &lt;- instead of the 'element of' symbol, I really need to get a better blog editor, one I can type symbols into easily; (f||g)(x,x') = (f x, g x') ) and the expected projection and tupling combinators.
&lt;/p&gt;&lt;p&gt;
Sum: Interesting, latent-typing as a functor, or at least something that looks like latent-typing to me.  Also interesting to note the use of bottom (_|_) to include undecidability.
&lt;pre&gt;
 D|D'          = ({tag0}||D}) U ({tag1}||D'}) U {_|_}
(f|g) _|_      = _|_
(f|g) (tag0,x) = (tag0, f x)
(f|g) (tag1,x) = (tag1, g x)
&lt;/pre&gt;
Also worth noting the injection and selection operators:
&lt;pre&gt;
i0 x = ({tag0},x)
i1 y = ({tag1},y)
f v g --- which applies f to arguments tagged 0,
                and g to arguments tagged 1.
&lt;/pre&gt;
&lt;/p&gt;&lt;p&gt;
Arrow: Some type of 'wrapping' function.  The example given is (f -&gt; g) h = g $ h $ f.  This suggests some sort of injection into f -&gt; g, but I'm not entirely sure how.  Apparently this is related to curry, uncurry, and eval, but again I don't see the relationship.
&lt;/p&gt;&lt;p&gt;
Identity, Constants: Pretty much as expected.  Lifting and Sectioning, will require a little more thought.
&lt;/p&gt;&lt;p&gt;
Interesting definition of a constant as a function of &lt;strong&gt;1&lt;/strong&gt; -&gt; A.  &lt;strong&gt;1&lt;/strong&gt; of course having only a single member &lt;em&gt;void&lt;/em&gt;.  Also given p::A-&gt;bool, and p? a = i0 a or i1 a if p a is true/false respectively, you have f v g $ p? modeling if p then f else g.
&lt;/p&gt;&lt;p&gt;
The rest of section 3 easily exceeds my grasp of category theory.  We define a representation for categorical recursion, then move on to recursive types,  specifically the least-fixed-point of a monofunctor.  Three examples given are cons-lists, binary trees, and natural numbers.
&lt;/p&gt;&lt;p&gt;
Having covered to background theory, the paper moves on to definitions of our operators over arbitary data types.  That will have to wait until I've recovered from section 3 ;).
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109385010030503691?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109385010030503691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109385010030503691' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109385010030503691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109385010030503691'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/08/bananas-lenses-envelopes-and-barbed_31.html' title='Bananas, Lenses, Envelopes, and Barbed Wire --- Section 3'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109358258157023040</id><published>2004-08-30T13:18:00.000+10:00</published><updated>2004-08-30T14:32:00.700+10:00</updated><title type='text'>Bananas, Lenses, Envelopes, and Barbed Wire.</title><content type='html'>&lt;p&gt;
Read the first two sections of &lt;a href="http://citeseer.ist.psu.edu/meijer91functional.html"&gt;"Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire"&lt;/a&gt; over lunch.  So far a very interesting paper, although looking ahead, I suspect it will probably endup exausting my understanding of category theory reasonably soon.
&lt;/p&gt;&lt;p&gt;
The paper has 6 sections.  Section 1 is a short introduction, motivation, and review of the literature; section 2, a short introduction to the four recursion operators cata, ana, hylo, and para; section 3 draws from category theory to outline a theory of algebraic data types used in the rest of the paper; section 4, a formal definition of the operators introduced in Sect2 using the theory developed in Sect3; section 5 extends some of sect4 to parametized types; section 6 is the conclusion, acknowlegements, and references.
&lt;/p&gt;&lt;p&gt;
The paper aims to define a series of four 'recursion operators'; cata, ana, hylo, and para, and then use them as the basis for a functional programming calculus.  These operators correspond to constructors for cata-, ana-, hylo-, and paramorphisms respectively.  The reason for doing this is that unstructured recursion isn't amenable to structual analysis and manipulation, so it is preferable to generalise various recursive forms into various forms of structured recursion before trying to develop the calculus.
&lt;/p&gt;&lt;p&gt;
The examples given are all with respect to your standard inductive list data-type:
&lt;pre&gt;
A* -&gt; Nil | Cons(A A*)
&lt;/pre&gt;
&lt;em&gt;(It's possibly worth noting that this is a direct algebraic analogue to your standard linked-list definition in an imperative language)&lt;/em&gt;
&lt;dl&gt;
&lt;dt&gt;Cata&lt;/dt&gt;
&lt;dd&gt;Constructs a catamorphism, more generally known as a right fold.  Think of it as collapsing a list into a value.  It takes two parameters, a binary function and an identity.
&lt;pre&gt;
h = cata(b, .) 
  -&gt;  h Nil          = b
      h (Cons(a,as)) = a . h(as)

and

h :: A* -&gt; B
b :: B
. :: A -&gt; B -&gt; B
&lt;/pre&gt;
cata is denoted using 'banana brackets': (|b, a|).  A good example of a catamorphism is length().
&lt;pre&gt;
length = cata(0, (+) $ 1)  
  note: (+) $ 1  is the right assoc composition of addition and the 1
        function (which ignores its argument and returns 1)
 
proof by substitution:

length Nil = 0
length (Cons(a,as)) =  ((+) $ 1) a length(as)
                    =&gt; (+) 1(a) length(as)
                    =&gt; 1 + length(as)
&lt;/pre&gt;
Which is of course the standard definition of length::A* -&gt; N
&lt;/dd&gt;
&lt;dt&gt;Ana&lt;/dt&gt;
&lt;dd&gt;Constructs an anamorphism, more generally known as an unfold.  This is naturally the inverse of a fold, and expands a value into a list.  It takes two parameters, an induction function and a termination predicate.
&lt;pre&gt;
h = ana(g, p) 
  -&gt;  h b = | p b  -&gt; Nil
            | else -&gt; Cons(a, h b') where (a, b') = g b

and

h :: B -&gt; A*
g :: B -&gt; (A B)
p :: A -&gt; boolean
&lt;/pre&gt;
ana is denoted with 'lense brackets' ([g, p]).  A good example of an anamorphism is zip, an easier one to follow is count(n), which returns the list of numbers incrementing from n.
&lt;pre&gt;
count n = ana(g, False) where False a = false,
                              g a = (a, a + 1)
&lt;/pre&gt;
&lt;/dd&gt;
&lt;dt&gt;Hylo&lt;/dt&gt;
&lt;dd&gt;Constructs a hylomorphism.  This is your classic inductive recursion from one value to another (think factorial, or fibonacci).  This can be represented as an anamorphism that builds the recursive call-stack, followed by an catamorphism that folds the stack into a result. 
&lt;pre&gt;
h = hylo(c, ., g, p) 
  -&gt;  h a = | p a  -&gt; c
            | else -&gt; b . (h a') where (b, a') = g a

and

h :: A -&gt; C
c :: C
. :: B -&gt; C -&gt; C


g :: A -&gt; (B A)
p :: A -&gt; boolean
&lt;/pre&gt;
hylo is denoted using 'envelope brackets': [|(c, .), (g, p)|].  A good example of a hylomorphism is factorial.
&lt;pre&gt;
fact n = [|(1, *),(g, p)|] where g n -&gt; (n, n - 1),
                                 p = | 0    -&gt; true
                                     | else -&gt; false

substitute:

fact = hylo(c, ., g, p) 
  -&gt;  fact n = | n == 0  -&gt; 1
               | else    -&gt; b * (fact a') where (b, a') = (n, n - 1)
            =&gt; | else    -&gt; n * (fact (n - 1)).

&lt;/pre&gt;
Which is of course the classic factorial
&lt;/dd&gt;
&lt;dt&gt;Para&lt;/dt&gt;
&lt;dd&gt;Constructs a paramorphism.  This is the weakest description of any of the four.  I can't really claim to understand para, but it is immediately recognisable as structured recursion over inductive datatypes.  I'm hoping that the definition will be provided later in the paper, but unlike the other three, this intro section only provided examples.  It does however cite another paper by one of the authors &lt;a href="http://citeseer.ist.psu.edu/meertens90paramorphisms.html"&gt;Meertens, Paramorphisms&lt;/a&gt;.  The example for numbers (Num ::= 0 | 1 + num):
&lt;pre&gt;
h = para(b, .) 
  -&gt;  h 0       = b
      h (1 + n) = n . (h n)
&lt;/pre&gt;
para is denoted using 'barbed-wire brackets': [&amp;lt;b, .&amp;gt;].  Factorial can be written as a paramorphism as:
&lt;pre&gt;
fact n = [&lt; 1, (g) &gt;] where n g m -&gt; (1 + n) * m
&lt;/pre&gt;
&lt;/dd&gt;
&lt;/dl&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109358258157023040?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109358258157023040/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109358258157023040' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109358258157023040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109358258157023040'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/08/bananas-lenses-envelopes-and-barbed.html' title='Bananas, Lenses, Envelopes, and Barbed Wire.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109271829185039477</id><published>2004-08-27T23:48:00.000+10:00</published><updated>2004-08-28T20:40:46.666+10:00</updated><title type='text'>Object.equals()</title><content type='html'>&lt;p&gt;
Like many languages Java provides two equality methods to test objects for equivalence.  The first is accessed via the '==' operator and does a simple heap reference comparison.  The other is a standard method on Object, equals() which is intended to be overridden by the programmer to perform a value-based comparison.  Now the equivalence operator is defined by the language spec, and ultimately implemented by the JVM developers, hence not our concern.  Unfortunately the java community has failed to properly document the subtleties involved in writing a correct equals method, and so I continue to come across incorrect implementations and worse, incorrect recommendations.
&lt;/p&gt;&lt;p&gt;
But first we have to understand what we are dealing with.  Fundamentally when we are defining an equals method on a class A, what we are defining is an &lt;a href="http://www.iscid.org/encyclopedia/Equivalence_Relation"&gt;Equivalence Relation&lt;/a&gt; over the set of all objects of class A.  This is important because it highlights that we can define our equals method to return &lt;em&gt;anything we want&lt;/em&gt; provided we meet three rules.
&lt;ul&gt;
&lt;li&gt;Reflexivity: a.equals(a) -&gt; true &lt;/li&gt;
&lt;li&gt;Symmetry: a.equals(b) &lt;-&gt; b.equals(a) &lt;/li&gt;
&lt;li&gt;Transitivity: a.equals(b) &amp;&amp; b.equals(c) -&gt; a.equals(c) &lt;/li&gt;
&lt;/ul&gt;
If we break any of these rules someone will suffer subtle and devious bugs.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;Node: To save typing I'm going to leave out the hashCode method in each of these examples, but be aware if you override equals() you &lt;strong&gt;*must*&lt;/strong&gt; override hashCode() to match.&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
One consequence of the requirements is that we must ensure that any test we use in our equals implementation meets these requirements as well.  So lets consider the standard mistake:
&lt;pre&gt;
class A {
  int n1;
  public boolean equals(Object o) {
    if (!(o instanceof A)) {
      return false;
    } else {
      A rhs = (A)o;
      return this.n1 == rhs.n1;
    }
  }
}
&lt;/pre&gt;
This is a very common implementation of equals, it has even made its way into a number of Java books.  Worse, the bug only manifests in the presence of implementation inheritance of concrete classes.
&lt;pre&gt;
class B extends A { 
  int n2;
  public boolean equals(Object o) {
    if (!(o instanceof B)) {
      return false;
    } else {
      B rhs = (B)o;
      return this.n1 == rhs.n1 &amp;&amp; this.n2 == rhs.n2;
    }
  }
}
&lt;/pre&gt;
To demonstrate the bug lets define a simple function on A's:
&lt;pre&gt;
static printEqual(A a1, A a2) {
  if (a1.equals(a2)) {
    System.out.println("EQUAL");
  } else {
    System.out.println("NOT-EQUAL");
  }
}
&lt;/pre&gt;
And test it:
&lt;pre&gt;
  A test1 = new A();
  A test2 = new B();
  printEqual(test1, test2);
      =&gt; Prints "EQUAL"
  printEqual(test2, test1);
      =&gt; Prints "NOT-EQUAL" !!!!
&lt;/pre&gt;
And we've broken symmetry.  This &lt;strong&gt;will&lt;/strong&gt; bite you.  There is no situation when an asymmetrical equality is not a bug.  Unfortunately it is scary how many places on the net this is presented as the exemplar equals() implementation.
&lt;/p&gt;&lt;p&gt;
So what does a correct equals method look like.  Well there are two.  The first is very straight forward, and should be the default choice.
&lt;pre&gt;
class A {
  int n1;
  public boolean equals(Object o) {
    if (o == this) {
      return true;
    } else if (o == null || !getClass().equals(o.getClass())) {
      return false;
    } else {
      A rhs = (A)o;
      return this.n1 == rhs.n1;
    }
  }
}

class B extends A { 
  int n2;
  public boolean equals(Object o) {
    if (!super.equals(o)) {
      return false;
    } else {
      B rhs = (B)o;
      return this.n2 == rhs.n2;


    }
  }
}
&lt;/pre&gt;
Now test1 != test2 AND test2 != test1.  Also, by delegating from B to A at the start of B::equals() we ensure any inaccessible state in A is handled appropriately, and more importantly, that the equality code for A isn't duplicated in B.  If you can't delegate from B-&gt;A like this, then it suggests that your B isn't actually an A, and you should check your class design (you probably should be using delegation rather than inheritance).
&lt;/p&gt;&lt;p&gt;
There are times however when you would really like an B to compare equal to an A.  The classic example is the circle/ellipse or square/rectangle shape examples.  It would be really nice if an ellipse with equal axes compared equal to an equivalent instance of a circle sub-class.  The way we can achieve this is to recognise that the core requirement of a correct equals implementation is that the operations we use to implement meet the same reflexivity/symmetry/transitivity requirements as the method itself.  Next note that instanceof is only asymmetric in the subclass; and in fact &lt;em&gt;any&lt;/em&gt; operation in the subclass will lead to asymmetry!  So if we do need subclassed equality, we can't permit a subclass to override the equals() method.
&lt;pre&gt;
abstract class Shape {
  public boolean equals(Object o) {
    if (o == this) {
      return true;
    } else if (o instanceof Shape) {
      // !! Note: instanceof is safe here as Shape is abstract.
      Shape rhs = (Shape)o;
      return [shape specific comparison --- maybe position];
    } else {
      return false;
    }
  }
}

class Ellipse extends Shape { 
  int minor, major;

  public int getMinor() { return minor; }
  public int getMajor() { return major; }

  // !!! NOTE THE USE OF *final* to prevent asymmetry!
  // Also note the exclusive use of accessors.
  public final boolean equals(Object o) {
    if (!super.equals(o)) {
      return false;
    } else if (getClass().equals(o.getClass())) {
      Eclipse rhs = (Eclipse)o;
      return this.getMajor == rhs.getMajor()
          &amp;&amp; this.getMinor == rhs.getMinor();
    } else {
      return false;
    }
  }
}

public Circle extends Ellipse {
  public Circle(int radius) { major = minor = radius; }
  public int getRadius()    { return major; }
}
&lt;/pre&gt;
Note that this is probably a rather clumbersome hierachy.  A better approach would be:
&lt;pre&gt;
public abstract class Ellipse {
  public abstract int getMajor();
  public abstract int getMinor();
  public final boolean equals(Object o) {
    if (!super.equals(o)) {
      return false;
    } else {
      Eclipse rhs = (Eclipse)o;
      return this.getMajor == rhs.getMajor()
          &amp;&amp; this.getMinor == rhs.getMinor();
    }
  }
}

public class EllipseImpl {
  int major, minor;
  ...
}

public class CircleImpl {
  int radius;
  public int getMajor() { return radius; }
  ...
}
&lt;/pre&gt;
Note that an CircleImpl will still compare equal with an appropriate EllipseImpl.
&lt;/p&gt;&lt;p&gt;
Please.  If you are programming Java, believe me, these really are the only two options open to you.  I really am very tired of tracking down the subtle bugs that result when this advice is ignored.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109271829185039477?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109271829185039477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109271829185039477' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109271829185039477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109271829185039477'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/08/objectequals.html' title='Object.equals()'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109231866309993352</id><published>2004-08-12T23:41:00.000+10:00</published><updated>2004-08-12T23:51:03.100+10:00</updated><title type='text'>SICP Lectures.</title><content type='html'>&lt;p&gt;
A friend of mine is studying CS at UQ, and this year they are using &lt;a href="http://mitpress.mit.edu/sicp/"&gt;The Structure and Interpretation of Computer Programs&lt;/a&gt; as a first year text.  I am personally pleased to see UQ buck the 'vocational education' trend that has been decimating IT degree courses recently.  OTOH it does make life a little tougher on the students, and although this is a good thing, there are ways of making life a little easier.  One is to point students at the &lt;a href="http://swiss.csail.mit.edu/classes/6.001/abelson-sussman-lectures/"&gt;videos&lt;/a&gt; of SICP lectures given by Abelson and Sussman at MIT.  I have watched them and they are very good, I highly recommend them to anyone approaching the book looking for some extra insight into the material. It is also worth pointing at the &lt;a href="http://mitpress.mit.edu/sicp/full-text/book/book.html"&gt;online version of the book&lt;/a&gt; in case anyone wasn't aware it was available.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109231866309993352?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109231866309993352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109231866309993352' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109231866309993352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109231866309993352'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/08/sicp-lectures.html' title='SICP Lectures.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109230109344521391</id><published>2004-08-12T18:49:00.000+10:00</published><updated>2004-08-12T18:58:52.446+10:00</updated><title type='text'>Cale the Corporatist Corsair</title><content type='html'>&lt;p&gt;
Apparently the BSA are looking for a new name for their &lt;a href="http://news.com.com/Ferreting+out+copyright+scofflaws/2100-1012_3-5303966.html"&gt;new mascot&lt;/a&gt;.  I'm a little surprised at their honesty, personally I find a corporate extortionist weasel who attempts to indoctrinate tech-savvy kids into acquiescing to the corporatist annexation of their public-domain rights, rather appropriate for the BSA.
&lt;/p&gt;&lt;p&gt;
Personally I'm pushing for "Cale the Corporatist Corsair".
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109230109344521391?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109230109344521391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109230109344521391' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109230109344521391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109230109344521391'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/08/cale-corporatist-corsair.html' title='Cale the Corporatist Corsair'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109203929263840716</id><published>2004-08-09T18:01:00.000+10:00</published><updated>2004-08-09T18:14:52.636+10:00</updated><title type='text'>Why Java sucks.</title><content type='html'>&lt;p&gt;
Ok, so this could just have easily titled 'Why [C/C++/Ada/...] sucks', but I use Java more than either of these atm, so I went with Java. Back on &lt;a href="http://lambda-the-ultimate.org"&gt;lambda&lt;/a&gt; the 'Why types are interesting' thread continues unabated.  However &lt;a href="http://lambda-the-ultimate.org/node/view/100/1165#comment-1165"&gt;this post&lt;/a&gt; by Paul Snively grabbed my attention.  It is definately worth reading in its entirety, but two paragraphs in particular stand out.
&lt;blockquote&gt;
[Alan] Kay takes a hard opposite perspective to mine on the static typing vs. late binding question, saying, in summary (not a direct quote), "What to do until software engineering is invented... do late binding, which means being able to make the changes easily." Actually, perhaps it's not really opposite, since he could be interpreted to mean "either do software engineering if you can or make the cost of changes as low as possible, which is best done at the current state of the art with late binding." That is, get out of these tools that do neither software engineering nor dynamic change well (C, C++, Java...) and either head for software engineering (SML, O'Caml, Haskell, Concurrent Clean, Epigram, Alice...) or head for late binding (Common Lisp, Scheme, Smalltalk, Oz...). Formulated that way, I can't help but agree with him, and merely choose to focus on heading towards software engineering after spending decades in late binding.
&lt;/blockquote&gt;
&lt;blockquote&gt;
At the end of the day, I want modern type theoretic ideas in my programming language so that, at compile time, I can:
&lt;ul&gt;
&lt;li&gt;Know that my code is deadlock-free.&lt;/li&gt;
&lt;li&gt;Know that my code is race-condition free&lt;/li&gt;
&lt;li&gt;Know that my code doesn't leak authority.&lt;/li&gt;
&lt;li&gt;Know that my code is upgradable without violating encapsulation or leaking authority.&lt;/li&gt;
&lt;li&gt;Will parallelize across multiple processors automagically when possible and serialize when it's not.&lt;/li&gt;
&lt;li&gt;Will not throw an exception that will not be caught and handled.&lt;/li&gt;
&lt;li&gt;Will have inferred all memory allocation and deallocation and do it automagically for me, letting me know if the dynamic characteristics of my code require the linking of a garbage collector.&lt;/li&gt;
&lt;li&gt;Will let me know if I attempt to take the tail of an empty list. :-) &lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
In case anyone dosn't realise, all the above points are already possible, although AFAIK not yet demonstrated possible at the same time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109203929263840716?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109203929263840716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109203929263840716' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109203929263840716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109203929263840716'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/08/why-java-sucks.html' title='Why Java sucks.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109202030772832791</id><published>2004-08-09T12:57:00.000+10:00</published><updated>2004-08-09T13:00:58.243+10:00</updated><title type='text'>Interesting scripting language for Java.</title><content type='html'>&lt;p&gt;
I had a quick look at &lt;a href="http://groovy.codehaus.org/"&gt;groovy&lt;/a&gt; a few months back when it was announced on &lt;a href="http://lambda-the-ultimate.org/"&gt;lambda&lt;/a&gt;.  To be perfectly honest I wasn't particularly impressed.  If I want a latent-typed, 'agile' scripting language, and don't want to fight too hard to be allowed to use it, I will use &lt;a href="http://www.jython.org/"&gt;Jython&lt;/a&gt;; or if I'm writing for myself, or have a tech-savy boss, I'll use &lt;em&gt;the&lt;/em&gt; scripting language, aka &lt;a href="http://www.schemers.org/"&gt;scheme&lt;/a&gt; (specifically: &lt;a href="http://sisc.sourceforge.net/"&gt;SISC&lt;/a&gt; or possibly &lt;a href="http://jscheme.sourceforge.net/jscheme/main.html"&gt;JScheme&lt;/a&gt;).  As far as I can tell it's just Yet Another Scripting Language.  I mean, what's the point!?
&lt;/p&gt;&lt;p&gt;
Then I came across a comparison between groovy and another JVM scripting language, &lt;a href="http://nice.sourceforge.net/"&gt;Nice&lt;/a&gt;.  &lt;a href="http://www.xoltar.org/"&gt;Bryn Keller&lt;/a&gt; does a quick &lt;a href="http://www.xoltar.org/2004/aug/07/nice-groovy.html"&gt;comparison&lt;/a&gt; between groovy and nice on his blog.  So what makes nice interesting, when groovy is so yawn-worthy?  Well nice is statically typed! It looks like a serious attempt at dragging the java world into the world of real compile time type safety --- a world without NullPointer/ClassCastExceptions, and with the free-flowing syntactic style of your traditional latent-typed languages.
&lt;/p&gt;&lt;p&gt;
As an example compare the following (from the xoltar post):
&lt;blockquote&gt;
Groovy
&lt;pre&gt;
if (customer.orders.any { it.amount &gt; 1000 &amp;&amp; 
	it.product.type == "cheese"} ) {
  doSomething();
}
&lt;/pre&gt;
Nice
&lt;pre&gt;
if (customers.orders.any(Order ord =&gt; ord.amount &gt; 1000 &amp;&amp; 
	ord.product.type == "cheese")) {
  doSomething();
}
&lt;/pre&gt;
&lt;/blockquote&gt;
Which given you can infer the type of ord from its use is intended to shortly become:
&lt;pre&gt;
if (customers.orders.any(ord =&gt; ord.amount &gt; 1000 &amp;&amp; 
	ord.product.type == "cheese")) {
  doSomething();
}
&lt;/pre&gt;
Which differs from the groovy example in only the trivial matter of being able to name the parameter to the closure; and in the not-at-all-trivial matter that &lt;em&gt;the compiler will ensure static type saftey at compile time!&lt;/em&gt;.
&lt;/p&gt;&lt;p&gt;
Just skimming the nice website, I still suspect I will find ML a nicer language, still a language targeted at interoperation with Java that supports: real parametric-types, proper closures, multiple-dispatch (goodbye visitor pattern ;), and tuples; all in a statically typed language with HM inferencing.  What's not to like?
&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109202030772832791?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109202030772832791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109202030772832791' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109202030772832791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109202030772832791'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/08/interesting-scripting-language-for.html' title='Interesting scripting language for Java.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109188470296798695</id><published>2004-08-07T23:07:00.000+10:00</published><updated>2004-08-07T23:18:22.966+10:00</updated><title type='text'>Tired.</title><content type='html'>&lt;p&gt;
I just finished my third first-aid duty at the queensland royal show (aka Ekka).  It was only 6 hours, so I don't know why I'm feeling so exhausted.  For some reason duties seem to tire me out, this one wasn't even particularly eventful (fortunately); I wrote up incident reports for two almost identical injuries from one of the sideshow rides when I learnt there had been more than my two cases.  Hopefully something will be done about it, I hate to see kids hurt. Was assigned ringside during the leadup and through the fireworks which was nice, although the fireworks were rather disappointing they were still fun.
&lt;/p&gt;&lt;p&gt;
I wrote some quick examples of continuation passing style over lunch before I went on duty, but I'm too tired to write the commentary now, so I'll do that tommorrow or monday and post part-3 then.  Byron will be pleased though, one of them is a simple regex engine which I think comes out rather nicely using CPS.
&lt;/p&gt;&lt;p&gt;
For now it's bedtime I think ;).
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109188470296798695?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109188470296798695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109188470296798695' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109188470296798695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109188470296798695'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/08/tired.html' title='Tired.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109171701443809345</id><published>2004-08-06T00:42:00.000+10:00</published><updated>2004-08-06T16:46:24.146+10:00</updated><title type='text'>Continuations - part 2</title><content type='html'>&lt;p&gt;
Back to my attempt to explain &lt;a href="http://www.lambda-the-ultimate.org/node/view/86"&gt;continuations&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;
What is a continuation? The short answer is "What the program should do next". Another way of putting it would be "Everything the program hasn't done yet, wrapped up in something that looks sort-of like a function".  Now I'm going to make the possibly arrogant assumption that as that wasn't sufficient explaination for me, that wasn't sufficient here.
&lt;/p&gt;&lt;p&gt;
Let's go back and reconsider an LCO example, this time we want to write a sigma function: takes a non-empty list of numbers and returns the sum of the list.
&lt;pre&gt;
; (sigma '(1 2 3 4)) -&amp;gt; 10
(define (sigma lst)
  (if (null? (cdr lst))
      (car lst)
      (+ (car lst) (sigma (cdr list)))))
&lt;/pre&gt;
Now the astute reader will be wondering why I've defined sigma like this, associating to the right, rather than to the left (which would have been simpler).  The reason for this is that this function cannot be trivially converted into the accumulator form we used in the previous LCO example.  More importantly, there are a number of recursive functions which are easier to define associating to the right than the left (I recommend trying to use append in place of + to define map in this manner).  Now it would be nice to be able to manage this sort of function in constant stack, and this is a nice simple example to demonstrate how we can do exactly this. In case any readers are wondering what I mean by associating left vs. right, I suggest you compare the above to the left-associative version below and consider the order in which the elements of the list are combined.
&lt;pre&gt;
(1 + (2 + (3 + 4))) - right assoc
(((1 + 2) + 3) + 4) - left assoc
&lt;/pre&gt;
&lt;pre&gt;
; Left associative
(define (sigma lst)
  (letrec ((sigma-iter
    (lambda (lst accum)
       (if (null? lst)
           accum
           (sigma-iter (cdr lst) (+ accum (car lst)))))))
  (sigma-iter (cdr lst) (car lst))))
&lt;/pre&gt;
&lt;em&gt;(Note we could have defined sigma-iter the same way we did earlier, as a global with (define...), however it really is a helper function, and so is better defined locally to sigma.  --- besides, it also gives me a chance to introduce lambda, which we will be using later)&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
The secret to converting the right-associative version into LCO is to recognise that the last thing we want to do before returning is call sigma on the tail of the list. Now this looks difficult, as the last thing we need to do is the addition. Still, I'm a great believer in wishful thinking, so I'm going to pretend I have an function that will take the result of the recursive call and finish off everything I was supposed to do next for me. Then I can pass that into the next call to sigma and have it finish for me.
&lt;pre&gt;
(define (sigma lst finisher)
  (if (null? (cdr lst))
      (finisher (car lst))
      (finisher (sigma (cdr lst) finishing-function))))
&lt;/pre&gt;
Opps, now we have a call to 'finisher' in the road.  Still that's ok, we can just pretend that we have a new finishing-function each time that will both handle the addition for this call, and the call to the finisher we were passed.
&lt;pre&gt;
(define (sigma lst finisher)
  (if (null? (cdr lst))
      (finisher (car lst))
      (sigma (cdr lst) new-finishing-function)))
&lt;/pre&gt;
Now this is looking better, all we have to do is work out how to define an appropriate finishing function and we're done.  Before we do that however it is worth noting (as most of you will have noticed by now anyway) that the new-finishing-function's definition "finish off everything I want to do next" is just a rephrasing of the definition I gave for a continuation at the start.
&lt;/p&gt;&lt;p&gt;
Lets compare the non-tail-recursive call to the continuation based tail-recursive call:
&lt;pre&gt;
; non-tail-recursive
(+ (car lst) (sigma (cdr lst)))
; tail-recursive
(sigma (cdr lst) continuation)
&lt;/pre&gt;
Remember the definition of the continuation is that it will be receiving the result of the recursive call to sigma as a parameter so lets call that x and substitute into the non-tail-recursive version:
&lt;pre&gt;
; let x &amp;lt;- (sigma (cdr lst))
(+ (car lst) x)
&lt;/pre&gt;
This will calcuate the result of our call, but we have one thing left to do, we have to return the result to our caller.  However our caller has finished (its call to us was a tail-call remember), and the destination of our result was passed as a continuation.  So we don't actually return as much as make a tail-call to the continuation (note this is a major reason why LCO is so useful, if we didn't have LCO our stack frame would be leaked, but with LCO there is no leak).
&lt;pre&gt;
; pass (+ (car lst) x) to the continuation.
(continuation (+ (car lst) x))
&lt;/pre&gt;
So what we need is to define a small function that can capture this idea and pass this into the recursive call to sigma.
&lt;pre&gt;
; Scheme
(lambda (x) (continuation (+ (car lst) x)))

# Python - just in case it's useful understanding the closure above.
# NOTE: As python dosn't provide LCO this *will* leak stack.
lambda x: continuation(lst[0] + x)
&lt;/pre&gt;
Now put the pieces together and we're almost there:
&lt;pre&gt;
(define (sigma lst continuation)
  (if (null? (cdr lst))
      (continuation (car lst))
      (sigma (cdr lst)
	     (lambda (x) (continuation (+ (car lst) x))))))
&lt;/pre&gt;
The next step is to restore the original signature, and make this CPS version a helper function (along the way we rename continuation to k, it's shorter ;).
&lt;pre&gt;
(define (sigma-helper lst k)
  (if (null? (cdr lst))
      (k (car lst))
      (sigma (cdr lst) (lambda (x) (k (+ (car lst) x))))))

(define (sigma lst)
  (sigma-helper lst initial-continuation))
&lt;/pre&gt;
Final step.... what do we want as the initial-continuation? Well it will be passed the result of the outer sigma, and what we want is the result of the outer sigma.... sounds like a job for the most trivial function you can think of; also known as the I combinator, let me introduce id()
&lt;pre&gt;
(define (id x) x)

(define sigma lst)
  (sigma-helper lst id))
&lt;/pre&gt;
And we're done.  Lets step back and take a look at what we've done.  We have taken a non-tail-recursive function and split into two pieces seperated by a tail-call. We execute the first half, and pass the second half as a parameter, a continuation, to the tail-call. It is worth noting three points:
&lt;ul&gt;
	&lt;li&gt;There is nothing special about the precise point we decided to split the function, at any point we could have wrapped the rest of the function in a continuation and passed it into another function, we'll come back to this when we discuss call-with-current-continuation later&lt;/li&gt;
	&lt;li&gt;The continuation ends up being an ordinary function.  We can save this function and call it as many times as we like; from other places than inside the sigma call.  After all, once we have it, it's just a function. This dosn't make much sense with sigma, but other algorithms do make use of this trick.  Again, we will come back to this with call/cc.&lt;/li&gt;
	&lt;li&gt;The sigma-helper function &lt;strong&gt;never&lt;/strong&gt; returns! In every case the helper function substitutes return with a call to its continuation parameter.  For this reason the sort of continuation used in this example is called a return-continuation. &lt;em&gt;Every return in every function can be treated as a call to an implicit return-continuation&lt;/em&gt;.  There are other uses for continuations, return-continuations are just the easiest to grasp, hence the subject of this post.  Again, I'll come back to other uses when I discuss call/cc.
&lt;/ul&gt;
&lt;/p&gt;&lt;p&gt;
This technique where you pass return-continuations around instead of returning normally is called CPS.  It is a powerful approach to programming that is a common transformation, especially in compilers for functional languages.
&lt;/p&gt;&lt;p&gt;
I would also appreciate any feedback on this introduction, both positive and suggestions for improvement.  Hopefully I'll have time to do a worked example and a discussion on call/cc soon.
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109171701443809345?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109171701443809345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109171701443809345' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109171701443809345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109171701443809345'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/08/continuations-part-2.html' title='Continuations - part 2'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109167726335752090</id><published>2004-08-05T13:35:00.002+10:00</published><updated>2004-08-05T13:43:23.573+10:00</updated><title type='text'>Python and LCO.</title><content type='html'>&lt;p&gt;
&lt;a href="http://staff.dstc.edu.au/croy/"&gt;Clinton&lt;/a&gt; makes a valid &lt;a href="http://staff.dstc.edu.au/croy/2004/08/05/#lco"&gt;point&lt;/a&gt; I should have made clear myself.  Python dosn't support LCO, and probably never will.  I am only using python as a convenient language to provide anyone who dosn't already know scheme with a parallel implementation to help them pick up enough of the language to follow my later discussions on continuations.
&lt;/p&gt;&lt;p&gt;
I apologise to anyone who may have been confused.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109167726335752090?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109167726335752090/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109167726335752090' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109167726335752090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109167726335752090'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/08/python-and-lco_05.html' title='Python and LCO.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109162961932327540</id><published>2004-08-05T00:24:00.000+10:00</published><updated>2004-08-05T00:26:59.323+10:00</updated><title type='text'>Continuations - part 1.</title><content type='html'>&lt;p&gt;
Ok, so why did I write a post on last-call-optimisation?  Well I find it very difficult to explain continuations to someone who dosn't understand LCO, so I thought I should post a quick example of LCO before this.  Of course the reason behind this sudden urge to actually fulfil my promise to explain continuations here is &lt;a href="http://lambda-the-ultimate.org"&gt;Lambda&lt;/a&gt; again.  This time an extended discussion on &lt;a href="http://lambda-the-ultimate.org/node/view/86"&gt;continuations&lt;/a&gt; sparked by &lt;a href="http://keithdevens.com/weblog/archive/2004/Jul/11/continuations"&gt;Keith Devens'&lt;/a&gt; request for help understanding the things.  Itself sparked by a particularly interesting analogy by Luke Palmer in news:perl.perl6.language, now forever dubbed the &lt;a href="http://groups.google.com/groups?selm=20040629233129.GA3979@babylonia.flatirons.org"&gt;"Continuation Sandwich"&lt;/a&gt; --- the relevant part of his post is:
&lt;blockquote&gt;
Say you're in the kitchen in front of the refrigerator, thinking about a
sandwitch.  You take a continuation right there and stick it in your
pocket.  Then you get some turkey and bread out of the refrigerator and
make yourself a sandwitch, which is now sitting on the counter.  You
invoke the continuation in your pocket, and you find yourself standing
in front of the refrigerator again, thinking about a sandwitch.  But
fortunately, there's a sandwitch on the counter, and all the materials
used to make it are gone.  So you eat it. :-)
&lt;/blockquote&gt;
&lt;/p&gt;&lt;p&gt;
Now before we begin I'm going to deal with continuation-passing-style and call-with-current-continuation seperately, but as a taste of what we're in for interested parties can check my &lt;a href="http://haskell.org/hawiki/CpsInJava"&gt;CPS-in-Java&lt;/a&gt; example on the haskell.org wiki, or the most lucid description of &lt;a href="http://download.plt-scheme.org/doc/207/html/t-y-scheme/t-y-scheme-Z-H-15.html#node_chap_13"&gt;call/cc&lt;/a&gt; in Chapter 13 of &lt;a href="http://download.plt-scheme.org/doc/207/html/t-y-scheme/index.htm"&gt;Teach Yourself Scheme in Fixnum Days&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;
In the meantime, it's 0021 hours here, so I'm going to sleep first, and finish this later.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109162961932327540?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109162961932327540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109162961932327540' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109162961932327540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109162961932327540'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/08/continuations-part-1.html' title='Continuations - part 1.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109162884899004049</id><published>2004-08-05T00:11:00.000+10:00</published><updated>2004-08-05T00:14:08.990+10:00</updated><title type='text'>Last-Call-Optimisation</title><content type='html'>&lt;p&gt;
First lets consider the old hoary chestnut, the factorial.
&lt;/p&gt;&lt;p&gt;
&lt;pre&gt;
; Scheme
(define (fact n)
  (if (zero? n)
      1
      (* n (fact (- n 1)))))

# Python
define fact(n):
  if not n:
    return 1
  else:
    return n * fact(n - 1)
&lt;/pre&gt;
&lt;em&gt;Note: I am going to have to use scheme later, so for the next few examples I'll be using scheme and python together to give non-schemers a basis for comparason.&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
Now this is a very straight forward recursive definition of the function.  The only trouble is that we are going to grow the stack proportional to n.  So we end up with the following (abbreviated) call-tree:
&lt;pre&gt;
fact 4
  fact 3
    fact 2
      fact 1
        fact 0
        * 1 1
      * 2 1
    * 3 2
  * 6 4
-&gt; 24
&lt;/pre&gt;
Note that for (fact 4) we end up with five stack frames on our call stack, and unfortunately there is no alternative as the code is written.  We can however eliminate this efficiency by converting to an iterative version:
&lt;pre&gt;
; Scheme
(define (fact-iter n accum)
  (if (zero? n)
      accum
      (fact-iter (- n 1) (* n accum))))

(define (fact n)
  (fact-iter n 1)

# Python
def factiter(n, accum):
  if n == 0:
    return accum
  else:
    return factiter(n - 1, n * accum)

def fact(n):
  return factiter(n, 1)
&lt;/pre&gt;
Now the call stack looks like:
&lt;pre&gt;
fact 4
  fact-iter 4 1
    fact-iter 3 4
      fact-iter 2 12
        fact-iter 1 24
          fact-iter 0 24
-&gt; 24
&lt;/pre&gt;
Which dosn't look very useful until you consider that as each call to fact-iter returns, it's caller simply passes the resulting value up the call-chain.  In otherwords, the caller's stack-frame is never used after it calls the next fact-iter in the chain; and what is never used dosn't need to be kept. This is called last-call-optimisation, and is a very common optimisation used by many languages to make the above code as efficient as the while loop solution traditionally taught in imperative languages:
&lt;pre&gt;
/* C */
int fact(n) {
  int accum = 1;
  while (n) {
    accum = accum * n;
    n--;
  }
  return accum;
}
&lt;/pre&gt;
In fact the traditional code generated by a LCO supporting compiler looks alot like this:
&lt;pre&gt;
/* MIML ;) */
int fact(n) {
  int accum = 1;
factiter:
  if (n == 0)
    return accum;
  else
    accum = n * accum;
    n = n - 1;
    goto factiter;
}
&lt;/pre&gt;
Which is pretty much exactly what the while loop would compile to.  This still leaves the question: "Why?", what's wrong with the while loop?
&lt;/p&gt;&lt;p&gt;
The answer to this is that factorial is defined recursively:
&lt;pre&gt;
       / 0 -&gt; 1
  n! = |
       \ n -&gt; n * (n - 1)
&lt;/pre&gt;
and it is trivial to compare this definition to the first recursive example and check it is correct.  The tail-recursive expression in the second example isn't as easy to confirm, but it is at least in a form amenable to a trivial inductive proof by inspection.  Because the while loop dosn't abstract away the inductive step but incorperates it into the loop pre/post-conditions and invariants, it is less amenible to proof. In fact the three examples can be seen as reducing levels of abstraction: moving away from the problem domain (a maths definition) towards the raw metal; and almost a tautology, the closer we can stay to the problem domain the better.
&lt;/p&gt;&lt;p&gt;
Now this is great for linear algorithms, or algorithms that process linearly recursive datastructures (fancy name for linked-lists ;).  However consider a pre-order traversal of a binary tree?  This can be made tail-recusive, but it is a fair bit more involved, and the subject of my next post.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109162884899004049?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109162884899004049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109162884899004049' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109162884899004049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109162884899004049'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/08/last-call-optimisation.html' title='Last-Call-Optimisation'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109158279656106744</id><published>2004-08-04T15:45:00.000+10:00</published><updated>2004-08-04T16:59:19.936+10:00</updated><title type='text'>Rdf, indices, hypergraphs, and iTql</title><content type='html'>&lt;p&gt;
An rdf database is a set of declarative statements: [subject predicate object].  Now the traditional way of representing this is as a traditional directed-graph with 'object' nodes with 'predicate' edges linking them.  This is a useful representation which successfully visualises most rdf-graphs.  Unfortunately for visualisers, for rdf to be useful you need to be able to attach semantics to predicates, and the logical way to do this is to make statements.  A quick example:
&lt;pre&gt;
Fred parentOf John
John parentOf Lucy
John parentOf Jane
&lt;/pre&gt;
This becomes much more useful if we can utilise statements such as
&lt;pre&gt;
parentOf   subsetOf    relativeOf
relativeOf hasProperty transitive
relativeOf hasProperty symmetric
&lt;/pre&gt;
which allows us to match against &lt;tt&gt;match(Jane relativeOf $x)&lt;/tt&gt; and get back &lt;tt&gt;{ x=Fred, John, Lucy, Jane }&lt;/tt&gt;
&lt;/p&gt;&lt;p&gt;
This is all well and good until you try and visualise the union of these two graphs (often called  base-facts, and schema).  The first problem you face is multiple edges between the verticies - forcing you to move to a 'directed-graph with named edges'; not too hard to visualise, but it isn't looking too much like a traditional graph anymore.  The real kicker comes when you try and visualise the relationship between parentOf and relativeOf, now you have an edge between two edges -- and we're not in Kansas anymore Toto.
&lt;/p&gt;&lt;p&gt;
So what do we have?  It is certainly 'graph-like', but it long ago ceased to be a traditional graph.  More importantly, we haven't started considering 'statings', 'named-graphs', or 'reification'.  The real problem is that a predicate is a valid vertex in the graph; an equal partner (conceptually) with its more numerous subject and object bretheren.  Fortunately we're not the first to consider this problem.  First consider the definition of a graph (preempting my summary of Trudeau Ch 2).
&lt;blockquote&gt;
A graph is an object consisting of two sets called its vertex set and its edge set. The vertex set is a finite nonempty set. The edge set is a set of two-element subsets of the vertex set.
&lt;/blockquote&gt;
Looking at the definition, it becomes quite obvious that what we need is for the edge set to contain three-element subsets of the vertex set.  This conveniently has a name: a 3-hypergraph.  More importantly it can be easilly expanded to support named-graphs by using a 4-hypergraph, and as &lt;a href="http://gearon.blogspot.com/"&gt;Paul Gearon&lt;/a&gt; noted, this has immediate relevance to the indicies &lt;a href="http://www.kowari.org"&gt;kowari&lt;/a&gt; uses.  It also has immediate relevance to crystalising iTql's semantics, allowing us to integrate the trans(), walk(), and the new ???() graph constraints --- we're still arguing over a name for what I like to call exclude(); and the original Constraint constraint (include()???). Each of these then returns an element of the powerset of VxVxV (where V is the vertex set). The elements of these resolved constraints are then statements, and as such amenable to predicate logic; and iTql provides conjunction and disjunction operations (and, or) and returns a sum-of-products solution to the resulting compound predicate.
&lt;/p&gt;&lt;p&gt;
So iTql provides four levels of operations:
&lt;dl&gt;
&lt;dt&gt;Graph Operations&lt;/dt&gt;
&lt;dd&gt;union, intersection, and disjoint-union of 3-hypergraphs in the FROM clause.  Note the result of this is actually a 4-hypergraph.&lt;/dd&gt;
&lt;dt&gt;Graph Constraints&lt;/dt&gt;
&lt;dd&gt;inclusive, transitive, reachability, and soon exclusive constraints against a specific 4-hypergraph (by default the graph returned from the FROM clause).  Note these are parametised by variables, and the result is a set of variable bindings that substitute to statisfy the constraint. These form the primitive constraints in an iTql WHERE clause.&lt;/dd&gt;
&lt;dt&gt;Predicate Logic Expressions&lt;/dt&gt;
&lt;dd&gt;conjunction and disjunction of variable binding sets, and type specific boolean functions (ie. comparison operators &gt;, &lt;, ==, etc) forming the rest of the WHERE clause.  The result of this is a product-of-sums we represent as an implementation of the 'Tuples' interface.  It is probably worth noting two things.  First, a Tuples fails to be a relation only because the individual variable binding sets have differing cardinalities; we fake this by padding with a unique UNBOUND value which carries DONT-CARE semantics.  Second, this can only happen when the expression includes a non-union compatable disjunction.&lt;/dd&gt;
&lt;dt&gt;Projection, Aggregation, and Subqueries&lt;/dt&gt;
&lt;dd&gt;ie. the SELECT clause: a list of functions to apply to the padded-product-of-sums returned by the WHERE clause; the results of which are zip'ed into the conventional tabular format most application developers find most useful.&lt;/dd&gt;
&lt;/dl&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109158279656106744?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109158279656106744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109158279656106744' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109158279656106744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109158279656106744'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/08/rdf-indices-hypergraphs-and-itql.html' title='Rdf, indices, hypergraphs, and iTql'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-1091276480455092</id><published>2004-07-31T22:09:00.000+10:00</published><updated>2004-07-31T23:11:41.153+10:00</updated><title type='text'>Normal people in bad situations.</title><content type='html'>&lt;p&gt;
&lt;a href="http://staff.dstc.edu.au/croy"&gt;Clinton&lt;/a&gt; &lt;a href="http://staff.dstc.edu.au/croy/2004/07/31#S21"&gt;wonders aloud&lt;/a&gt; about the behaviour of the Khmer Rouge interrogators.  Unfortunately this sort of behaviour is both normal, and predicted; anyone who doesn't understand this needs to take the time to read about such experiments as &lt;a href="http://www.prisonexp.org/"&gt;"The Stanford Prison Experiment"&lt;/a&gt;
&lt;em&gt;&lt;blockquote&gt;
		Welcome to the Stanford Prison Experiment web site, which features an extensive slide show and information about this classic psychology experiment, including parallels with the recent abuse of Iraqi prisoners. What happens when you put good people in an evil place? Does humanity win over evil, or does evil triumph? These are some of the questions we posed in this dramatic simulation of prison life conducted in the summer of 1971 at Stanford University.
&lt;/blockquote&gt;&lt;/em&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-1091276480455092?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/1091276480455092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=1091276480455092' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/1091276480455092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/1091276480455092'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/normal-people-in-bad-situations.html' title='Normal people in bad situations.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-1091195013512055</id><published>2004-07-30T23:41:00.000+10:00</published><updated>2004-07-30T23:43:33.513+10:00</updated><title type='text'>Why types?  -- lambda, the main course</title><content type='html'>&lt;p&gt;
First the surreal, then possibly one of the most interesting threads I think I've seen on lambda.  Probably why I'm now clocking 10 hours catching up on lambda, and not only am I still at it, but I'm still motivated.
&lt;/p&gt;&lt;p&gt;
In &lt;a href="http://lambda-the-ultimate.org/node/view/100"&gt;Why type systems are interesting&lt;/a&gt;, Anton van Straaten lifted a comment by Luke Gorrie to a toplevel discussion:
&lt;blockquote&gt;
	If someone could next show what makes type systems so interesting in terms that I'll understand then I'll be well on my way into the modern functional programming world.. :-)
&lt;/blockquote&gt;
and in doing so launched a fascinating thread that has seen 44 posts so far and launched at least one independent thread.  I seriously recommend this thread to anyone who considers themselves a serious programmer.  A few highlights:
&lt;/p&gt;&lt;p&gt;
Anton managed to summarise the thread in the introduction:
&lt;blockquote&gt;
When you write code, even in the most dynamic language, you always know something about the types of the values you're operating on. You couldn't write useful code otherwise - if you doubt that, try coming up with some examples of operations you can perform on a value without knowing something about the type of that value.

Type systems provide a way to encode, manipulate, communicate and check this type knowledge. In an earlier thread, you mentioned that you write the types of functions in the comments. That's an informal type system! Why do you do use a type system? Because type systems are useful, important, and as a result, interesting.
&lt;/blockquote&gt;
Note that the first paragraph is deceptively simple.  Consider the most common example of a generic data-structure, the list.  If you have a truely hetrogeneous list, one whose contents are truely untyped, you your list is actually indistinguishable from a natural number!  The only operations you can perform on a completely typeless list form the monoid ([], Lists, concat) which of course form a monoid isomorphic with (0, Naturals, +), and supports the Isomorphic Arrow length() mapping lists and naturals.  For a fuller discussion of this I recommend &lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0262660717/qid=1091193105/sr=1-1/ref=sr_1_1/002-2674487-2020861?v=glance&amp;s=books"&gt;Basic Category Theory for Computer Scientists&lt;/a&gt;, Benjamin Pierce (and before I get asked, I borrowed it from my local university library).
&lt;/p&gt;&lt;p&gt;
Anyone who has been reading lambda much immediately recognises Frank Atanassow, his writing style is distinctive, and his opinions both strongly held, and consistent. One of the really exciting things about this thread was that Frank's comment &lt;a href="http://lambda-the-ultimate.org/node/view/100/681#comment-681"&gt;Rebuttal&lt;/a&gt; finally managed to clarify for me, what he has been talking about these past months. Although if you haven't been reading lambda much and intend to read that post I would strongly advise you read &lt;a href="http://lambda-the-ultimate.org/node/view/100/564#comment-564"&gt;No contraints[sic]&lt;/a&gt;, and keep in mind Anton's comment in &lt;a href="http://lambda-the-ultimate.org/node/view/100/635#comment-635"&gt;Constraints&lt;/a&gt;
&lt;blockquote&gt;
if b then 42 else "ha!"

becomes something like:

if b then Num 42 else Str "ha!"

...where Num and Str are type constructors for the Univ type. This is kind of ironic, considering that it's the latter language that's supposed to be able to inference types.

&lt;strong&gt;You can think of dynamically-typed languages as a shortcut syntax for creating programs which rely on a universal type. This demonstrates that statically-typed languages can be less expressive than dynamically-typed ones.&lt;/strong&gt; &lt;em&gt;emphasis mine&lt;/em&gt;
&lt;/blockquote&gt;
It was also very amusing to watch a curveball from Julian Squires who wanted to know how static type systems interact with his desire to actively develop an executing application (think smalltalk, or possibly php) in &lt;a href="http://lambda-the-ultimate.org/node/view/100/715#comment-715"&gt;Re: Software development as a static activity&lt;/a&gt;.  Personally I'm not sure any existing languages combine a modern static type system with the ability to do runtime modifications. Still even if you only consider static type checking a safety net, surely one time you would really really like to have it is when doing something as delicate as runtime development.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-1091195013512055?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/1091195013512055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=1091195013512055' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/1091195013512055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/1091195013512055'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/why-types-lambda-main-course.html' title='Why types?  -- lambda, the main course'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109119133549669630</id><published>2004-07-30T22:40:00.000+10:00</published><updated>2004-07-30T22:45:56.973+10:00</updated><title type='text'>Just surreal.</title><content type='html'>&lt;p&gt;
The past couple of evengings have been 'catch up on lambda' evenings.  So I only just stumbled across one of the most surreal threads I think I've ever read. &lt;a href="http://lambda-the-ultimate.org/node/view/93"&gt;Old computer science and technical books worth searching for&lt;/a&gt; certainly looked promising.  It started will, and I will definately have to keep an eye out for "ACM Turing Award Lectures: The First Twenty Years". Then someone mentioned generating functions and type derivatives, and before too long I end up &lt;a href="http://lambda-the-ultimate.org/node/view/93/745#comment-745"&gt;ambushed&lt;/a&gt; with
&lt;blockquote&gt;
The |x| &lt; 1 condition is a red herring in this case. It is quite standard to work with generating functions in the context of the ring of formal power series k[[x]] with coefficients in a field k. (You can generalize the heck out of this definition.) A formal power series is a polynomial except for the fact that we don't require the elements of its coefficient sequence to become zero after a certain point. We define addition in this ring in the obvious way and multiplication by convolution of the coefficient sequences, just like you would in a polynomial ring.
&lt;/blockquote&gt;
Ouch! My poor head.  I still need warning and a good runup when approaching this sort of thing.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109119133549669630?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109119133549669630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109119133549669630' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109119133549669630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109119133549669630'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/just-surreal.html' title='Just surreal.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109118967972047613</id><published>2004-07-30T22:13:00.000+10:00</published><updated>2004-07-30T22:14:39.720+10:00</updated><title type='text'>Trudeau: Ch 1.  Maths, Games, and Education.</title><content type='html'>&lt;p&gt;
I'm currently reading chapter 4 of Trudeau, but lets do this properly and I'll start with chapter 1.
&lt;/p&gt;&lt;p&gt;
Chapter 1 is the introduction, and like all introductions everywhere, is largely content free --- or more precisely, is the realm of opinion and motivation.  But, before I discuss Trudeau's opinion of why I should read this book, Introduction to Graph Theory has what is probably the most excuberant blurb I think I have ever read on a textbook.
&lt;blockquote&gt;
	This delightfully written introduction to graph theory offers a stimulating excursion into pure mathematics. It is aimed at those whom the author calls "the mathematically traumatized," but it is a treasury of challenging fun ... "The topics are so well motivated, the exposition so lucid and delightful, that the book's appeal should be virtually universal....[sic] Every library should have several copies"
&lt;/blockquote&gt;
Wow, somebody was certainly in a good mood.  You could almost be forgiven for forgetting that you're actually reading about a textbook. I think this gives new meaning to 'rave review'.
&lt;/p&gt;&lt;p&gt;
Anyway, back on topic, Trudeau would like us to approach pure mathematics as a game.
&lt;blockquote&gt;
	Basically pure mathmatics is a box of games. At last count it contained more than eighty of them. One of the is called "Euclidean geometry".
&lt;/blockquote&gt;
He then goes on to approach the closed-world nature of pure maths; something I as an engineer struggle to deal with.
&lt;blockquote&gt;
	Games have one more feature in common with pure mathematics. It is subtle but important. It is that the objects with which a game is played have no meaning outside the context of the game.
	...
	You may balk at this, since for historical reasons, chessmen have names and shapes that imply an essential correspondence with the external world. The key word is "essential"; there is indeed a correspondence, but it is inessential. ...this interpretation of the gaem, like all others, has nothing to do with chess &lt;em&gt;per se&lt;/em&gt;.
&lt;/blockquote&gt;
So in a similar way, while the words plane, point, and line suggest real-world analogues, it is only an implied interpretation.  In Euclidean geometry they are axiomatic, with specific properties, but without definition.
&lt;blockquote&gt;
	...no one knows what planes, points or lines are, except to say that they are objects which are related to one another in accordance with the axioms. The three words are merely convenient names for the three types of object geometers play with. Any other names would do as well.
&lt;/blockquote&gt;
Still the most interesting paragraph in the introduction is right at the beginning.  Along with a number of my peers, I cruised through High School mathematics.  In fact I largely finished read Lord of the Rings, and War and Peace in my maths classes.  It seemed that my teachers would take about a week to teach a days work, and yet it was obvious that dispite the slow pace many of my classmates were still being left behind. Naturally as a geek, I have spent a fair amount of time analysing and self analysing to try and understand the difference. While I was still at school, I just assumed I was just more intelligent.  However experience has since taught me I wasn't.  Which reopens the question, "What was I doing that made me so much more effective at learning High School maths?".  I certainly didn't work harder. I believe Trudeau's introduction gives us a clue:
&lt;blockquote&gt;
	To understand what mathematics is, you need to understand what pure mathematics is. Unfortunately, most people have either seen no pure mathematics at all, or so little that they have no real feeling for it. Consequently most people don't really udnerstand mathematics; I think this is why many people are afraid of mathematics and quick to proclaim themselves mathematically stupid.
	Of course, since pure mathematics is the foundation of applied mathematics, you can see the pure mathematics beneath the applications if you look hard enough. But what people see, and remember, is a matter of emphasis. People are told about bridges and missiles and computers. Usually they don't hear about the fascinating intellectual game that lies beneath it all.
&lt;/blockquote&gt;
My current hypothesis is that my gift was the ability to see past the smokescreen of 'applications', and rote-work, to the fundamental patterns and structure of the pure mathematics underneath. This would also explain why I find such a return on time spent studying Computer Science --- and consequently my interest in language semantics and hence why I'm reading a book on graph theory largely for fun. So assuming I am right, can this insight into how a 'naturally gifted' high-school maths student attains their aptitude be used to improve the pedalogy of our existing maths curriculums?
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109118967972047613?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109118967972047613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109118967972047613' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109118967972047613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109118967972047613'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/trudeau-ch-1-maths-games-and-education.html' title='Trudeau: Ch 1.  Maths, Games, and Education.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109115370055835403</id><published>2004-07-30T11:32:00.000+10:00</published><updated>2004-07-30T13:34:40.446+10:00</updated><title type='text'>Shiny Papers.</title><content type='html'>&lt;p&gt;
I'm a reading magpie.  I find it almost impossible to browse citeseer, or a amazon without walking away with at least a half dozen new books, and twenty or thirty new papers to read.  Citeseer is particularly bad... 'Ooo shiny paper', &lt;click&gt;, &lt;download&gt;, and I have yet another pdf to add to my already impossibly huge collection.  So I've decided to be a little more systematic about my reading.
&lt;/p&gt;&lt;p&gt;
I'm going to start posting summaries of the articles, papers, and books I'm reading.  This will hopefully result in a permanant record for my own reference, and if I'm lucky, suggestions for additional reading.
&lt;/p&gt;&lt;p&gt;
So for starters I thought I would post my current (heavilly abbreviated) reading list.
&lt;dl&gt;
&lt;dt&gt;&lt;a href="http://www.cs.indiana.edu/eopl/"&gt;Essentials of Programming Languages&lt;/a&gt;, Daniel Freidman&lt;/dt&gt;
&lt;dd&gt;I'll be working through this one concurrently with the other papers as I want to work the examples, and that will slow down the reading. I would be interested in advice; this is a textbook widely used in CS courses, would it be inappropriate for me to post my solutions?&lt;/dd&gt;
&lt;dt&gt;&lt;a href="http://www.cis.upenn.edu/~bcpierce/tapl/"&gt;Types and Programming Languages&lt;/a&gt;, Benjamin Pierce&lt;/dt&gt;
&lt;dd&gt;I will be starting this as soon as I finish EOPL.  Again I expect to work the examples, and a similar question arises, except that this is a graduate text so hopefully less chance of encouraging cheating&lt;/dd&gt;
&lt;/dl&gt;
And concurrently with this:
&lt;dl&gt;
&lt;dt&gt;&lt;a href="http://www.amazon.co.uk/exec/obidos/ASIN/0486678709/wwwlink-software-21/026-8559680-2190064"&gt;Introduction to Graph Theory&lt;/a&gt;, Richard J. Trudeau&lt;/dt&gt;
&lt;dt&gt;&lt;a href="http://www.sics.se/~joe/thesis/armstrong_thesis_2003.pdf"&gt;Making reliable distributed systems in the presesnce of software errors&lt;/a&gt;, Joe Armstrong&lt;/dt&gt;
&lt;dt&gt;&lt;a href="http://citeseer.ist.psu.edu/19489.html"&gt;The Polyadic PI Calculus : A Tutorial&lt;/a&gt;, Robin Milner&lt;/dt&gt;
&lt;dd&gt;I'll be rereading this one in order to summarise it properly.  I'm finding it too useful as a framework for thinking about OOP to not want a more concrete reference to my own understanding of this topic.&lt;/dd&gt;
&lt;dt&gt;&lt;a href="http://haskell.cs.yale.edu/yale/papers/haskellworkshop01/"&gt;Genuinely Functional User Interfaces&lt;/a&gt;, Antony Courtney, Conal Elliott&lt;/dt&gt;
&lt;dd&gt;This is my primary area of interest, so I am particularly interested in any interesting references on FRP, Arrows, and FRP/Arrows applied to GUI's&lt;/dd&gt;
&lt;dt&gt;&lt;a href="http://haskell.cs.yale.edu/yale/papers/oxford02/"&gt;Arrows, Robots, and Functional Reactive Programming&lt;/a&gt;, Paul Hudak, Henrik Nilsson, Antony Courtney, John Peterson&lt;/dt&gt;
&lt;/dl&gt;
There are more, but that will do for now.  I'll keep this list updated as I find other 'shiny papers', receive recommendations, or actually finish reading some of them ;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109115370055835403?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109115370055835403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109115370055835403' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109115370055835403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109115370055835403'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/shiny-papers.html' title='Shiny Papers.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109110901030309745</id><published>2004-07-29T22:52:00.000+10:00</published><updated>2004-07-30T00:03:02.423+10:00</updated><title type='text'>It's not as scary as it sounds.</title><content type='html'>&lt;p&gt;
&lt;a href="http://www.gbch.net/gjb/blog/"&gt;Greg Black&lt;/a&gt; &lt;a href="http://www.gbch.net/gjb/blog/2004/07/29#reliable-sw"&gt;comments&lt;/a&gt; that he took a look at Joe Armstrong's thesis I linked to below.  Just in case his discription makes it sound intimidating, the error handling philosophy discussion --- let it crash --- is one section of chapter 4 (ie. about 3 pages).  Of course, handling errors is only one step towards a reliable system.
&lt;/p&gt;&lt;p&gt;
In fact, the chapters of the thesis are largely approachable independently of each other. Chapters 2 and 4 (Architecture and Programming Principles) are particularly good in this regard.
&lt;/p&gt;&lt;p&gt;
In the meantime for those who are feeling too lazy to read the actual pdf, an executive summary:
&lt;ul&gt;
&lt;li&gt;We don't know how to write bug-free programs&lt;/li&gt;
&lt;li&gt;So every substantial program will have bugs&lt;/li&gt;
&lt;li&gt;Even if we are lucky enough to miss our bugs, unexpected interactions with the outside world (including the hardware we are running on) will cause periodic failures in any long-running process&lt;/li&gt;
&lt;li&gt;So make sure any faults that do occur can't interfere with the execution of your program&lt;/li&gt;
&lt;li&gt;Faults are nasty, subtle, vicious creatures with thousands of non-deterministic side-effects to compensate for&lt;/li&gt;
&lt;li&gt;So the only safe way to handle a bug is to terminate the buggy process&lt;/li&gt;
&lt;li&gt;So don't program defensively: Just let it crash, and make sure
&lt;ol&gt;
&lt;li&gt;Your runtime provides adequate logging/tracing/hot-upgrade support to detect/debug/repair the running system&lt;/li&gt;
&lt;li&gt;You run multiple levels of supervisor/watchdog all the way from supervisor trees to automatic, hot-failover hardware clusters&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
Simple really ;)
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109110901030309745?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109110901030309745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109110901030309745' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109110901030309745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109110901030309745'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/its-not-as-scary-as-it-sounds.html' title='It&apos;s not as scary as it sounds.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109099394072569007</id><published>2004-07-28T10:41:00.000+10:00</published><updated>2004-07-28T16:43:43.053+10:00</updated><title type='text'>Let it crash</title><content type='html'>&lt;p&gt;
&lt;a href="http://sourcefrog.net/weblog/"&gt;Martin Pool&lt;/a&gt; &lt;a href="http://sourcefrog.net/weblog/software/filesystems/crash-only.html"&gt;links&lt;/a&gt; to a usenix paper from last year on &lt;a href="http://www.usenix.org/events/hotos03/tech/candea.html"&gt;Crash only software&lt;/a&gt;. It is an interesting paper, the first I have seen applying this principle to J2EE.  Still I was rather disappointed that the only prior work on supervisorary fault recovery cited seem to be their own. For instance the &lt;a href="http://www.erlang.org"&gt;erlang&lt;/a&gt; community has made this a fundamental part of their culture, and the approach is pervasive from the &lt;a href="http://www.erlang.org/doc/r9c/doc/reference_manual/processes.html#10.6"&gt;language primitves&lt;/a&gt; thru &lt;a href="http://www.erlang.org/doc/r9c/lib/stdlib-1.12/doc/html/gen_server.html"&gt;standard libraries&lt;/a&gt; to &lt;a href="http://www.erlang.se/doc/programming_rules.shtml#REF42466"&gt;system architecture recommendations&lt;/a&gt; and &lt;a href="http://www.erlang.org/ml-archive/erlang-questions/200303/msg00113.html"&gt;community norms&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;
Anyone who might be interested in more detail on how this philosophy works in practice is encouraged to check out &lt;a href="http://www.sics.se/~joe/"&gt;Joe Armstrong's&lt;/a&gt; PhD thesis &lt;a href="http://www.sics.se/~joe/thesis/armstrong_thesis_2003.pdf"&gt;Making reliable systems in the presence of software errors.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109099394072569007?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109099394072569007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109099394072569007' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109099394072569007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109099394072569007'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/let-it-crash.html' title='Let it crash'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109045946333054638</id><published>2004-07-22T11:09:00.000+10:00</published><updated>2004-07-22T13:55:16.850+10:00</updated><title type='text'>The importance of checking references.</title><content type='html'>&lt;p&gt;
Jeff Pollock has &lt;a href="http://gearon.blogspot.com/2004/07/xml-rpc-i-was-little-distracted-today.html"&gt;responded&lt;/a&gt; to Paul Gearon's post on Jeff's recent comments to the RDF DAWG list.  In doing so he makes three points, I will address his other two points another time (if Paul dosn't beat me to it), but wanted to make a quick note here regarding the first.
&lt;/p&gt;&lt;p&gt;
Jeff's quote from the dawg charter didn't ring true to me in light of various comments on the dawg list, so I went and checked.  Jeff wrote:
&lt;blockquote&gt;
the DAWG charter says "It is a requirement that the query language be compatible with an XQuery context"
&lt;/blockquote&gt;
The &lt;a href="http://www.w3.org/2003/12/swa/dawg-charter#XQueryBinding"&gt;charter&lt;/a&gt; reads:
&lt;blockquote&gt;
There is a requirement for RDF data to be accessable within an XML Query context.
&lt;/blockquote&gt;
And in fact even this snipet looses signifigant, and important context.  A true contextual quote reads:
&lt;blockquote&gt;
At this stage, it is not clear to what extent XQuery technology is applicable to the task of querying RDF datasets. The RDF DAWG should aim to maximize W3C technology re-use, while also taking account of differences between the RDF graph data model and the XQuery data model.

There is a requirement for RDF data to be accessable within an XML Query context. The working group should specify at least one mechanism for exposing RDF query facilities in an XQuery environment; that is, a way to take a piece of RDF Query abstract syntax and map it into a piece of XML Query using some form of extension to XQuery.
...
While the data model of the query language of this protocol is dissimilar to that of XQuery, a non-XML concrete syntax might reuse syntactic elements from XQuery to aid learning time, even if XQuery is not chosen as the strawman.
&lt;/blockquote&gt;
Note that the sentence Jeff quoted is referring to an extension to XQuery to allow an RDF query to be embedded in, and accessed by, an XQuery.  This is very different from a requirement for compatibility, and falls far short of requiring the use of an XQuery syntax for the rdf query language.
&lt;p&gt;
It is also worth noting here that the charter explictly recognises the difficulty in mapping XML-infoset semantics to rdf.
&lt;blockquote&gt;
At this stage, it is not clear to what extent XQuery technology is applicable to the task of querying RDF datasets.
...
While the data model of the query language of this protocol is dissimilar to that of XQuery,
...
While RDF query addresses a different data domain (the RDF graph),
&lt;/blockquote&gt;
On the other hand, the charter also naturally recognises the value in cohesive standards that leverage off each other:
&lt;blockquote&gt;
The RDF DAWG should aim to maximize W3C technology re-use, while also taking account of differences between the RDF graph data model and the XQuery data model.
...
a non-XML concrete syntax might reuse syntactic elements from XQuery to aid learning time
...
any query mechanisms defined by this group must leverage off, and, where possible, interoperate with, the related XML recommendations
&lt;/blockquote&gt;
In conclusion I will repeat what I said in my first post on this subject.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;XML has a document centric, single-rooted, hierachial view of its data; and XQuery reflects that. RDF on the other hand is a open-world, non-rooted, cyclic directional graph-based view. It is not immediately obvious how to reconcile these two approaches; neither is it apparent that a syntax designed to query the former, will be appropriate for the latter.
&lt;/p&gt;
&lt;p&gt;I would have absolutely not problem with discovering that XQuery can be married with the semantics required by an RDF query language, in fact that would be great.
&lt;/p&gt;
&lt;/em&gt;
&lt;p&gt;
&lt;strong&gt;Update&lt;/strong&gt; Andy Seabourne has posted a link to a &lt;a href="http://jena.hpl.hp.com/~afs/RDF-XML.html"&gt;paper&lt;/a&gt; by the jena team which nicely illustrates how BRDF can be made &lt;em&gt;accessable&lt;/em&gt; to XQuery/XSLT.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109045946333054638?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109045946333054638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109045946333054638' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109045946333054638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109045946333054638'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/importance-of-checking-references.html' title='The importance of checking references.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109038920358816642</id><published>2004-07-21T15:44:00.000+10:00</published><updated>2004-07-21T15:53:23.586+10:00</updated><title type='text'>More DAWG links while waiting for time to blog...</title><content type='html'>&lt;p&gt;
Still far to busy with the new Resolver code to blog this properly, so I'm just going to link to a few posts on the dawg-public-list that I want to discuss later.  This way I won't have to go back and find them again when I finally find time to blog.
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://lists.w3.org/Archives/Public/public-rdf-dawg/2004JulSep/0109.html"&gt;Dan Connolly's respose to Jeff Pollock&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://lists.w3.org/Archives/Public/public-rdf-dawg/2004JulSep/0113.html"&gt;Jeff Pollock's response to Jim Hendler&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://lists.w3.org/Archives/Public/public-rdf-dawg/2004JulSep/0118.html"&gt;Rob Shearer's objection to provenance&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://lists.w3.org/Archives/Public/public-rdf-dawg/2004JulSep/0120.html"&gt;Dan Connolly asks for test cases for SOURCE (ie. provanance/data-management)&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://lists.w3.org/Archives/Public/public-rdf-dawg/2004JulSep/0024.html"&gt;Simon Raboczi's summary of alternatives for optional matches&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://lists.w3.org/Archives/Public/public-rdf-dawg/2004JulSep/0126.html"&gt;Rob Shearer's simple example of how NI envisiages an XQuery based RDF query language&lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109038920358816642?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109038920358816642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109038920358816642' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109038920358816642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109038920358816642'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/more-dawg-links-while-waiting-for-time.html' title='More DAWG links while waiting for time to blog...'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109031228370982248</id><published>2004-07-20T18:26:00.000+10:00</published><updated>2004-07-20T18:31:23.710+10:00</updated><title type='text'>Watch this space.</title><content type='html'>I've been rather busy this week trying to hammer the new Kowari Resolver SPI into shape, so I don't have time to comment properly on the DAWG discussions regarding NI's recent XQuery proposals.  I'll do that as soon as I can.  In the meantime Kendall Clark was kind enough to correct some inaccuracies in my earlier post, and I feel it is appropiate to give his corrections equal billing to my errors.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109031228370982248?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109031228370982248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109031228370982248' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109031228370982248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109031228370982248'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/watch-this-space.html' title='Watch this space.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109005622319968761</id><published>2004-07-17T19:03:00.000+10:00</published><updated>2004-07-17T19:23:43.200+10:00</updated><title type='text'>Objects and Relational Databases</title><content type='html'>&lt;a href="http://members.optusnet.com.au/benjamincarlyle/benjamin/blog/"&gt;Ben Carlyle&lt;/a&gt; has been rusing recently about Object-Orientation and Relational (or at least SQL) databases.  I suggested that some background reading on some of the theory supporting the two worlds might be useful.  As he didn't have pen and paper handy I'm blogging it.
&lt;p&gt;
For OO, Actor theory and the Pi-Calculus: &lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0521658691/qid=1090055511/sr=1-1/ref=sr_1_1/102-5351493-7014558?v=glance&amp;s=books"&gt;Robin Milner, Communicating and Mobile Systems: the Pi-Calculus&lt;/a&gt; and &lt;a href="http://citeseer.ist.psu.edu/19489.html"&gt;Robin Milner, The Polyadic pi-Calculus: a Tutorial (1991)&lt;/a&gt;
&lt;p&gt;
For Relational Theory: &lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0321197844/qid=1090055844/sr=1-1/ref=sr_1_1/102-5351493-7014558?v=glance&amp;s=books"&gt;Chris Date, Introduction to Database Systems, Eighth Edition&lt;/a&gt; and &lt;a href="http://citeseer.ist.psu.edu/darwen95third.html"&gt;Chris Date, The Third Manifesto (1995)&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109005622319968761?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109005622319968761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109005622319968761' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109005622319968761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109005622319968761'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/objects-and-relational-databases.html' title='Objects and Relational Databases'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-109001905390322161</id><published>2004-07-17T08:22:00.000+10:00</published><updated>2004-07-17T09:04:13.903+10:00</updated><title type='text'>Update on XQuery - RDF</title><content type='html'>As expected the DAWG has rejected Network Inferencing's proposal.  Jeff Pollock has &lt;a href="http://lists.w3.org/Archives/Public/public-rdf-dawg/2004JulSep/0101.html"&gt;responded&lt;/a&gt; on the public-rdf-dawg list.  While Jeff is obviously disappointed, I suspect that the dawg hasn't rejected XQuery.  NI's proposal was a syntactic one, and the DAWG decided months ago to defer syntax until after the semantics are decided.
&lt;p&gt;
Two weeks ago I wrote a new rdf-query language - it took me about half a day.  The parser was trivial, and the semantics a subset of iTql (&lt;a href="http://www.tucanatech.com"&gt;Tucana's&lt;/a&gt; rdf query language implemented in &lt;a href="http://www.kowari.org"&gt;Kowari&lt;/a&gt;).  At the end of the day, syntax isn't as important as semantics.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-109001905390322161?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/109001905390322161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=109001905390322161' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109001905390322161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/109001905390322161'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/update-on-xquery-rdf.html' title='Update on XQuery - RDF'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108998536799831118</id><published>2004-07-16T23:37:00.000+10:00</published><updated>2004-07-16T23:53:12.010+10:00</updated><title type='text'>MIML</title><content type='html'>Machine Independent Machine Language. AKA C.
&lt;p&gt;
Somehow I've managed to come across this acronymn twice today from independent sources. I still find it a beautifully accurate description of both C's greatest strength, and it's greatest weakness.
&lt;p&gt;
Still, somehow regardless of how many new languages I learn, I still seem to have a soft spot for C --- it is a remarkably elegant MIML.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-108998536799831118?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108998536799831118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108998536799831118' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108998536799831118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108998536799831118'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/miml.html' title='MIML'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108995208152021528</id><published>2004-07-16T13:51:00.000+10:00</published><updated>2004-07-16T17:52:11.116+10:00</updated><title type='text'>Jumping the gun.</title><content type='html'>Well the Data Access Working Group (DAWG) of the W3C is working towards standardising a query language for RDF.  Jeff Pollock from Network Inferencing recently posted to the DAWG mailing list &lt;a href="http://lists.w3.org/Archives/Public/public-rdf-dawg/2004JulSep/0091.html"&gt;Post&lt;/a&gt;/&lt;a href="http://lists.w3.org/Archives/Public/public-rdf-dawg/2004JulSep/att-0091/DAWG_req_proposal.pdf"&gt;Attached Proposal&lt;/a&gt;

&lt;blockquote&gt;
Therefore, NI proposes that a new requirement be considered by this group:
 
"The query language shall have an XQuery compatible concrete language syntax."
&lt;/blockquote&gt;
&lt;p&gt;
I don't think you could make a more premature proposal.  The DAWG is trying to avoid syntax issues, preferring to get the semantics right first --- a good idea.  To be proposing concrete syntax requirements at this stage is surely jumping the gun.  I am even more surprised to see a proposal to mandate as poor a prima-facie case as XQuery.
&lt;/p&gt;
&lt;p&gt;
XML has a document centric, single-rooted, hierachial view of its data; and XQuery reflects that.  RDF on the other hand is a open-world, non-rooted, cyclic directional graph-based view.  It is not immediately obvious how to reconcile these two approaches; neither is it apparent that a syntax designed to query the former, will be appropriate for the latter.  This becomes particularly apparent when you look at the block-and-layer diagram in Jeff's proposal pdf.  The only link between the XQ Data Model, and the RDF Triples is that both are sometimes serialised as XML --- ok XML tends to be serialised as XML, but lets not quibble, RDF often isn't.
&lt;/p&gt;
&lt;p&gt;
On the other hand, XQuery is itself quite a nice solution to its problem.  Particularly nice is its definition of two isomorphic concrete grammars sharing a common semantic model.  I would have absolutely not problem with discovering that XQuery can be married with the semantics required by an RDF query language, in fact that would be great.  Still I would like to see the DAWG finalise the required semantics first.
&lt;/p&gt;
&lt;p&gt;
I would be concerned if XQuery was even considered desirable at this stage, let alone a requirement.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-108995208152021528?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108995208152021528/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108995208152021528' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108995208152021528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108995208152021528'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/jumping-gun.html' title='Jumping the gun.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108976675943288879</id><published>2004-07-14T10:45:00.000+10:00</published><updated>2004-07-14T15:28:20.763+10:00</updated><title type='text'>When is an infinite loop not an infinite loop?</title><content type='html'>When it's body takes enough time that the transaction times out before the stack overflows.
&lt;p&gt;
This of course was aggrivated by the fact that everytime I identified precisely when the transaction was marked for rollback, it was iterating over a Tuples.  This isn't surprising given we spend alot of our time iterating over Tuples.  Not that that occurred to me until after I found the bug. Hence I spent all of yesterday looking inside the TuplesOperations and half a dozen Tuples subclasses.
&lt;p&gt;
Yesterday was definately the most fustrating days I've had in some time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-108976675943288879?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108976675943288879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108976675943288879' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108976675943288879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108976675943288879'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/when-is-infinite-loop-not-infinite.html' title='When is an infinite loop not an infinite loop?'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108968113716856427</id><published>2004-07-13T10:25:00.000+10:00</published><updated>2004-07-13T11:12:17.166+10:00</updated><title type='text'>UML Editors</title><content type='html'>Sometimes all you want to do is draw a diagram.  I have periodically wanted a simple UML editor to allow me to produce diagrams to help explain the occasionally complicated class and message structures periodically required by the OO paradigm.  UML does a good job of providing a vocabulary to support such informal, explainatory diagrams.  Unfortunately UML comes from a high-ceremony community that inspired and supports RUP, Rational Rose, and is currently pursuing executable UML and MDA with a vengence.  Hence every UML product I have been able to find is either a high-ceremony UML based IDE (ie. ArgoUML, Rational Rose), or an extension to a traditional charting program (ie. Visio, Dia).  All of them suck if all you want is to quickly draw a single sequence diagram to enhance some documentation; Visio even manages the worst of both worlds, by trying to play the pseudo-ide game while retaining the lack of structured assistance of your charting programs.
&lt;p&gt;
Why mention this?  Because I have finally found a UML program that is probably close-enough that I can live with it's short-comings; and shows sufficient promise that I might even be convinced it's worth contributing to.
&lt;p&gt;
So I would like to recommend that the next time you want to throw together a quick UML diagram, you check out &lt;a href="http://www.horstmann.com/violet/"&gt;Violet&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-108968113716856427?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108968113716856427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108968113716856427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108968113716856427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108968113716856427'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/uml-editors.html' title='UML Editors'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108961325464867653</id><published>2004-07-12T16:12:00.000+10:00</published><updated>2004-07-12T16:20:54.646+10:00</updated><title type='text'>Continuations.</title><content type='html'>I wrote these a while back, and I make reference to them occasionally.  Now I have a blog, I should probably blog them properly.
&lt;p&gt;
&lt;a href="http://haskell.org/hawiki/CpsInJava"&gt;Continuation Passing Style in Java&lt;/a&gt;
&lt;p&gt;
&lt;a href="http://haskell.org/hawiki/CpsInCee"&gt;Continuation Passing Style in C&lt;/a&gt;
&lt;p&gt;
One of these days I'll actually get around to setting up my own wiki :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-108961325464867653?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108961325464867653/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108961325464867653' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108961325464867653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108961325464867653'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/continuations.html' title='Continuations.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108936241312613406</id><published>2004-07-12T14:20:00.000+10:00</published><updated>2004-07-12T14:22:39.370+10:00</updated><title type='text'>Worthwhile languages.</title><content type='html'>There are literally thousands of computer languages, and several paradigms.  Here's a few languages I consider worth looking at.

Languages I know, use, and admire:
&lt;p&gt;
&lt;a href="http://gcc.gnu.org/"&gt;C&lt;/a&gt; - Some people describe this as portable assembly.  They are right.  C feels remarkably close to the ideal minimal abstraction from the concerns of computer architecture.  I can't think of a good programmer who dosn't know C well, there is a good reason for this.
&lt;p&gt;
&lt;a href="http://www.python.org"&gt;Python&lt;/a&gt; - Possibly the most pleasant language I know.  Also by far the easiest language I know of to teach to absolute beginners.  Python has the advantage of supporting both imperative, functional, and object-oriented paradigms. However it's best feature is its truely remarkable community. I am unaware of any community that has such a healthy focus on usability, readability, and statistics-driven optimisation.  I don't do much python programming anymore, but I still enjoy reading the community.
&lt;p&gt;
&lt;a href="http://www.schemers.org/"&gt;Scheme&lt;/a&gt; - Take one very powerful language; add very simple syntax; mixin safe syntactic closure and you get scheme.  Hence it is widely used in the language research community, where people are understandably more interested in the power and facilities of their language than popularity.  
&lt;p&gt;
Languages I know, want to use, and admire:
&lt;p&gt;
&lt;a href="http://www.erlang.org"&gt;Erlang&lt;/a&gt; - One of the nicest languages I've come across.  Scalable, safe concurrency, with pattern matching, and a whole gamult of features supporting fault-tolerant computing all the way down to low-level wire-protocol work.
&lt;p&gt;
&lt;a href="http://www.haskell.org"&gt;Haskell&lt;/a&gt; - This is a language for thinking outside the box.  Lazy, pure-functional, static-strong typing, advanced HM type inferencing, monads, arrows, the list goes on.  If you have only ever done imperative procedual or object-oriented code (read java, C, C++, smalltalk, python, perl, etc) learn the exceptions to most of the rules you have osmosed.
&lt;p&gt;
&lt;a href="http://www.smlnj.org"&gt;SML&lt;/a&gt;/&lt;a href="http://www.ocaml.org"&gt;OCaml&lt;/a&gt;; Clean, elegant, safe, and fast!  What's not to like about ML? Yes you can pick a single metric on which your language of choice wins against ML, but you'll be hard pressed to find two.
&lt;p&gt;
Yes, I recognise the distinct lack of logic and constraint languages in this list so I'll just point at two I have been recommended but haven't found time to investigate sufficiently to add to the list above: &lt;a href="http://www.cs.mu.oz.au/research/mercury/"&gt;Mercury&lt;/a&gt;, &lt;a href="http://www.mozart-oz.org/"&gt;Mozart&lt;/a&gt;, and one that looks very promising Paul Reppy's &lt;a href="http://moby.cs.uchicago.edu/"&gt;Moby&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-108936241312613406?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108936241312613406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108936241312613406' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108936241312613406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108936241312613406'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/worthwhile-languages.html' title='Worthwhile languages.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108959376659721385</id><published>2004-07-12T10:44:00.000+10:00</published><updated>2004-07-12T10:57:22.860+10:00</updated><title type='text'>An impressive rant.</title><content type='html'>I mentioned this amusing rant to Steve last friday night, and promised to provide a link.  I'm just going to assume that blogging it counts as fulfilling that promise :).  I came across this on the c2 wiki, it is probably the most impressive and entertaining anti-C++ rant I've ever read.
&lt;p&gt;
&lt;a href="http://groups.google.com/groups?selm=3103356827666810%40naggum.no&amp;output=gplain"&gt;Erik Naggum on C++&lt;/a&gt;
&lt;blockquote&gt;
  C++ is philosophically and cognitively unsound as it forces a violation
  of all known epistemological processes on the programmer.  as a language,
  it requires you to specify in great detail what you do not know in order
  to obtain the experience necessary to learn it.  C++ has taken premature
  optimization to the level of divine edict since it _cannot_ be vague in
  the way the state of the system necessarily is.
&lt;/blockquote&gt;
&lt;blockquote&gt;
C++ is a language strongly optimized for
  liars and people who go by guesswork and ignorance.
&lt;/blockquote&gt;
&lt;blockquote&gt;
C++ turns otherwise good people into paranoid,
  insecure prostitutes, and it comes from creating such horrible living
  environments for themselves and compounded by trying to explain to
  themselves that "it's OK, really".
&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-108959376659721385?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108959376659721385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108959376659721385' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108959376659721385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108959376659721385'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/impressive-rant.html' title='An impressive rant.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108934331920150963</id><published>2004-07-09T13:14:00.000+10:00</published><updated>2004-07-09T16:20:25.503+10:00</updated><title type='text'>Database Abstraction Layers.</title><content type='html'>Interesting post on lambda regarding database abstraction layers.  For quite a while I have been wondering about clean ways to provide persistency in modern languages.
Specifically you want to provide:
&lt;ul&gt;
&lt;li&gt;Persistence&lt;/li&gt;
&lt;li&gt;Integrity&lt;/li&gt;
&lt;li&gt;Closure&lt;/li&gt;
&lt;/ul&gt;
I dicuss these issues later, but for now the link to the existing discussion
&lt;p&gt;
&lt;a href="http://lambda-the-ultimate.org/node/view/76#comment"&gt;Database Abstraction Layers and Programming Languages&lt;/a&gt;
&lt;p&gt;
&lt;a href="http://www.erlang.org/doc/r9c/lib/mnemosyne-1.2.5/doc/html/index.html"&gt;Mnemosyne&lt;/a&gt;, the best persistence/query/language integration attempt I am personally aware of.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-108934331920150963?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108934331920150963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108934331920150963' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108934331920150963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108934331920150963'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/database-abstraction-layers.html' title='Database Abstraction Layers.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108916957754713847</id><published>2004-07-07T12:43:00.000+10:00</published><updated>2004-07-09T16:19:39.846+10:00</updated><title type='text'>A very cute use for egrep.</title><content type='html'>Local UUG is currently in the midst of a cascade on funky shell tricks; I found this one from Russell Stuart, particularly cool.
&lt;blockquote&gt;
tr "[:print:]" "[x*]" &lt; FILE | egrep -vno '^(..+)\1+$'
&lt;/blockquote&gt;
&lt;a href="http://archive.humbug.org.au/humbug-chat/2004-07/msg00004.html"&gt;[H-CHAT] What's your top three shell tricks?&lt;/a&gt;
&lt;p&gt;
The thread explains what it does, and I would probably replace the .'s in the egrep pattern with x's; still very cute.
&lt;p&gt;
It can also provide a good example of when cs theory can occasionally be useful:  Given the provided solution uses a gnu-extensions to regex(7), can this be done with a pure POSIX regular expression?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-108916957754713847?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108916957754713847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108916957754713847' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108916957754713847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108916957754713847'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/07/very-cute-use-for-egrep.html' title='A very cute use for egrep.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108860148279217023</id><published>2004-06-30T22:45:00.000+10:00</published><updated>2004-07-09T16:21:25.343+10:00</updated><title type='text'>Programming Language Pragmatics</title><content type='html'>Programming Language Pragmatics&lt;br&gt;
&lt;emp&gt;Michael Scott; Morgan Kaufmann; 1-55860-442-1&lt;/emp&gt;
&lt;p&gt;
I recently finished reading this and thought I should provide a review as it is a truely remarkable book.  Fundamentally the book is an informal survey of the various fields of computer science and engineering that impact the design and implementation of programming languages, their interpreters, and compilers --- and it succeeds admirably.  Specifically the chapters include:
&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Programming Language Syntax. (FA/PDA's; regular expressions; context-free grammars; LL/LR parsers, including one of the clearest descriptions of LR parsing I have come across.)&lt;/li&gt;
&lt;li&gt;Names, Scopes, and Bindings. (Value lifetime; garbage collection; different scoping rules; different implementation approaches to scoping.)&lt;/li&gt;
&lt;li&gt;Semantic Analysis. (Attribute grammars; attribute flow. While well written, I personally found this one of the weaker chapters.)&lt;/li&gt;
&lt;li&gt;Assembly-Level Computer Architecture. (Effectively a one chapter synopsis of Hennersey and Patterson.)&lt;/li&gt;
&lt;li&gt;Control Flow. (Selection; Iteration; Recursion; and Non-determinisim)&lt;/li&gt;
&lt;li&gt;Data Types. (Static and Dynamic checking; discussion of implementation; A short discussion of HM-style type inference; as well as discussions on the particular issues associated with Records, Arrays, Pointers, Lists, and IO.)&lt;/li&gt;
&lt;li&gt;Subroutines and Control Abstraction. (Calling sequences and conventions; call-stack/tree management; exceptions - including continuations; coroutines.)&lt;/li&gt;
&lt;li&gt;Building a running program. (Compiler backends; intermediate code; register allocation; linking - including dynamic linking and pic.)&lt;/li&gt;
&lt;li&gt;Data Abstraction and Object Orientation. (OOP, including semantics and implementation concerns of encapsulation; inheritance; finalisation; polymorphism.  All discusses with reference to a multitude of different languages and approaches to OOP).&lt;/li&gt;
&lt;li&gt;Nonimperative Programming Models: Functional and Logic Languages. (Split into two sections, one on functional and one on logic programming. Of particular interest are introductions to both the lambda and first-order predicate calculi; and discussions on the advantages these mathmatical groundings provide programmers).&lt;/li&gt;
&lt;li&gt;Concurrency. (Background; Theory; Shared-memory; and Message-Passing. A very impressive introduction to concurrency.)&lt;/li&gt;
&lt;li&gt;Code Improvement. (By necessity of space, a very limited introduction to code optimisation. Still it manages to cover a reasonable amount of ground, although I would have liked more discussion on cache optimisation techniques.  Peephole Optimisation; Global Redundancy; Data Flow Analysis; Loop Invariants and Unrolling; Instruction Scheduling; Register Allocation).&lt;/li&gt;
&lt;/ol&gt;
Given the breadth of the coverage, the reader will require additional reading to gain any appreciable capacity in any specific area.  However  this book does provide a very reasonable introduction to areas that will provide much needed context when approaching any more focused work. It's not going to replace the Dragon Book, but it will make the Dragon Book far more approachable, and I wish I had read PLP before I had to wade my way through the much less approachable prose of Aho, Sethi and Ullman. Similarly, the reader is still going to want to read Patterson and Hennersey. However the discussions of language semantics and their associated demands on computer architecture will answer many questions of motivation given short treatment in the more advanced work.
&lt;p&gt;
&lt;p&gt;
In conclusion, I would highly recommend this to any programmer who has experience in only one or two languages; any undergraduate wanting to broaden their understanding of programming; any professional wanting to learn more about compiler/interpreter/parser theory and implementation and wants context for the more focuses works in this field.
&lt;p&gt;
5-stars.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-108860148279217023?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108860148279217023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108860148279217023' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108860148279217023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108860148279217023'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/06/programming-language-pragmatics.html' title='Programming Language Pragmatics'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108847608396792825</id><published>2004-06-29T11:20:00.000+10:00</published><updated>2004-06-29T12:38:35.793+10:00</updated><title type='text'>Domain Specific Languages</title><content type='html'>I came across this article on &lt;a href="http://lambda-the-ultimate.org/node/view/46"&gt;Lambda&lt;/a&gt; by Simon Johnston on &lt;a href="http://www-106.ibm.com/developerworks/blogs/dw_blog_comments.jspa?blog=352&amp;entry=53398"&gt;DSL's&lt;/a&gt;.  He takes two examples from the world of art, and asks that we consider possible parallels in software.
&lt;blockquote&gt;
   1. My son and I recently read a book on Leonardo da Vinci (great link), in particular looking at the way Leonardo’s work contained a great body of work from very rough sketches to beautiful and complete works of art. Explaining how artists start with rough pencil sketches, refining the lines, the perspective and then move onto oil to complete was a particularly interesting discussion.

   2. I know there are many analogies that we in computer science draw between our world and that of construction – here’s another. Look at how buildings are really constructed, the architect does not build blue prints, they draw or make a model of the envisioned building (some of these drawings have become as well known as the actual buildings themselves). For example, Frank Lloyd Wright’s Fallingwater started with a truly beautiful drawing that sold the client. Then followed floor plans and blueprints. Only then did wiring diagrams, plumbing details and specific engineering drawings for features such as the cantilevered balconies complete the story.
&lt;/blockquote&gt;
Simon then goes on to state his position:
&lt;blockquote&gt;
My position is that the creation of domain specific languages that do not seamlessly support the ability to transform information along the refinement scale are not helpful to us. So, for example, a component designer that is a stand alone tool unconnected to the class designer that provides the next logical level of refinement (classes being used to construct components) is a pot hole in the road from concept to actual implementation. Now, this is not as I have said to indicate that domain specific languages are bad, just that many of us in this industry love to create new languages be they graphical, textual or conceptual. We have to beware of the tendency to build these disjoint languages that force the user to keep stopping and jumping across another gap.
&lt;/blockquote&gt;
I couldn't read this and not immediately be struck by Paul Graham's reflections on creating what became &lt;a href="http://www.paulgraham.com/icad.html"&gt;Yahoo Store&lt;/a&gt;, specifically his comments regarding &lt;a href="http://www.paulgraham.com/avg.html"&gt;lisp&lt;/a&gt;.  Writing this it also occurred to me that RMS's comment in &lt;a href="http://www.base.com/gordoni/web/tcl-rms.html"&gt;Why you should not use Tcl&lt;/a&gt; is also appropriate:
&lt;blockquote&gt;
The principal lesson of Emacs is that a language for extensions should
not be a mere "extension language".  It should be a real programming
language, designed for writing and maintaining substantial programs.
Because people will want to do that!

Extensions are often large, complex programs in their own right, and
the people who write them deserve the same facilities that other
programmers rely on.
&lt;/blockquote&gt;
...which can only apply doubly for &lt;emp&gt;applications&lt;/app&gt; written in a DSL.
&lt;p&gt;
It also brings to mind the miriad of embedded dsl's spawned by the &lt;a href="http://www.haskell.org/"&gt;Haskell&lt;/a&gt; community though their wholesale adoption and exploitation of monads (and more recently arrows).
&lt;p&gt;
It only reinforces my increasing belief that &lt;strong&gt;the biggest gap in many popular modern languages is the lack of syntactic closure; the ability to introduce new syntatic support for a feature that becomes a first-class citizen of your programming environment.&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-108847608396792825?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108847608396792825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108847608396792825' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108847608396792825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108847608396792825'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/06/domain-specific-languages.html' title='Domain Specific Languages'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108842561833351077</id><published>2004-06-28T22:09:00.000+10:00</published><updated>2004-06-28T22:26:58.333+10:00</updated><title type='text'>...but at least it's done.</title><content type='html'>In the original, memory based, version of tks queryies returned answers; and answers had a method getRowCount() which did exactly that.  The problem with that is that memory dosn't scale as well as disk does.  So we moved to a disk backed architecture.  Now when you are memory based, you want to release your memory as soon as possible, so you want to resolve (and subsequently release) any intermediate results immediately.  Once you are backed by disk, you have much better uses for memory than storing an answer the user isn't using yet, so you want to evaluate your query as lazilly as possible.  Hence Kowari/TKS has this concept of a Tuples, which is a thunked, localised, intermediate result.  This gets wrapped in an Answer object, which is returned to the user, and resolves the Tuples by need.
&lt;p&gt;
The problem is that calculating an accurate row count becomes a potentially expensive operation; you can generally only afford an upper-bound instead.  So unfortunately while the semantics changed, the name stayed the same, to the general confusion of all.
&lt;p&gt;
Subsequentely I have spent the past 2.5 days reverting the semantics, and introducing new methods to access the upper-bound (and cardinality).  Tedious work, but at least it's done.
&lt;p&gt;
Now on to getting resolvers to play nicely with transactions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-108842561833351077?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108842561833351077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108842561833351077' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108842561833351077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108842561833351077'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/06/but-at-least-its-done.html' title='...but at least it&apos;s done.'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108837770512451145</id><published>2004-06-28T08:24:00.000+10:00</published><updated>2004-06-28T09:08:25.126+10:00</updated><title type='text'>"So, what do you do for a living?"</title><content type='html'>Like most people I am forever being asked to explain what I do for a living.  Answering that question got harder when I started my current job.  
&lt;p&gt;
My last job was with a company called &lt;a href="http://www.braintree.com.au"&gt;Braintree&lt;/a&gt;, who make world class communication gateways --- mainly for the eftpos and financial industry.  So I could always answer "I help design boxes to connect old EFTPOS machines to the bank using new technologies".  It glosses over a lot, is largely incomplete, but remains something most people could comprehend.  The worst job I've had to try and explain was my first.  "I am writing the user-interface to an Electron Paramagnetic Resonance simulation"?  I've seen geeks eyes glaze over on that one :).
&lt;p&gt;
So far for my current job I've had to revert to the classic "I'm a programmer in an IT company", which is sufficiently devoid of information to be mutually unsatisfying.  So what am I currently working on?  I am employed by &lt;a href="http://www.tucanatech.com"&gt;Tucana Technologies&lt;/a&gt; to work on an open-source RDF database &lt;a href="http://www.kowari.org"&gt;Kowari&lt;/a&gt;.  Kowari is used by Tucana as the base on which we build our enterprise rdf-datastore &lt;a href="http://www.tucanatech.com/solutions/products.htm"&gt;TKS&lt;/a&gt;.  OTOH, if having difficuty explaining my job is the price to pay for having this much fun I suppose it's worth it.  Tucana is a great company to work for, and Kowari is really fun engineering.  Still, if anyone can think of a one or two sentence description that isn't quite as insipid I would appreciate it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7421391-108837770512451145?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108837770512451145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108837770512451145' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108837770512451145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108837770512451145'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/06/so-what-do-you-do-for-living.html' title='&quot;So, what do you do for a living?&quot;'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7421391.post-108811843098180101</id><published>2004-06-25T08:50:00.000+10:00</published><updated>2004-06-25T11:33:44.530+10:00</updated><title type='text'>Once more with feeling...</title><content type='html'>Well not an auspicious start for blogger.  I posted a short note last night, mainly to avoid leaving an empty blog.  Somehow blogger has managed to lose it.
&lt;p&gt;
Let us start with my morning reading:
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://lambda-the-ultimate.org/"&gt;Lambda The Ultimate&lt;/a&gt;  - Probably the premiere blog on the topic of computer languages; their design, semantics, and implementation.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.sidhe.org/~dan/blog/"&gt;Squawks of the Parrot&lt;/a&gt; - The blog of Dan  Suglaski, the lead developer on parrot --- the new perl-6 vm.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.kimbly.com/blog/"&gt;About Kim&lt;/a&gt; - Another blog.  Kim's posts invariably betray a striking intelligence; are always thought provoking; and periodically on programming language topics.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.groklaw.net"&gt;Groklaw&lt;/a&gt; - Because even geeks need soap-opera sometimes.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.irregularwebcomic.net/"&gt;Irregular Web Comic&lt;/a&gt; - There are other web comics I enjoy, but this has rapidly become my favourate.&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/7421391-108811843098180101?l=etymon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://etymon.blogspot.com/feeds/108811843098180101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7421391&amp;postID=108811843098180101' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108811843098180101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7421391/posts/default/108811843098180101'/><link rel='alternate' type='text/html' href='http://etymon.blogspot.com/2004/06/once-more-with-feeling.html' title='Once more with feeling...'/><author><name>Andrae Muys</name><uri>http://www.blogger.com/profile/04967415260912980895</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_cIcQKLMH1_o/SpyQOPz5ZKI/AAAAAAAAABU/z4I3W4QKb68/S220/profile.jpg'/></author><thr:total>0</thr:total></entry></feed>
