<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>My Diversions &#187; CAL and Open Quark</title>
	<atom:link href="http://www.kablambda.org/blog/category/computer-science/cal/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kablambda.org/blog</link>
	<description>Notes on things I'm thinking and doing</description>
	<lastBuildDate>Tue, 20 Oct 2009 11:31:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Functional Programming on Android</title>
		<link>http://www.kablambda.org/blog/2009/07/27/functional-programming-on-android/</link>
		<comments>http://www.kablambda.org/blog/2009/07/27/functional-programming-on-android/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 13:57:08 +0000</pubDate>
		<dc:creator>Tom Davies</dc:creator>
				<category><![CDATA[CAL and Open Quark]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.kablambda.org/blog/?p=99</guid>
		<description><![CDATA[I&#8217;ve integrated CAL with a variety of Java based frameworks/environments: Tapestry, GWT and Google AppEngine for instance.

Recently someone asked on the CAL Google Group whether CAL programs could run on Android mobile devices. Android doesn&#8217;t use a standard JVM, it uses Dalvik, and it provides a subset of the normal JRE library.

I have put together [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve integrated <a href="http://openquark.org">CAL</a> with a variety of Java based frameworks/environments: <a href="http://www.kablambda.org/blog/2007/09/24/cal-and-the-tapestry-5-tutorial/">Tapestry</a>, <a href="http://www.kablambda.org/blog/2008/03/15/gwt-as-a-cal-client/">GWT</a> and <a href="http://www.kablambda.org/blog/2009/04/27/cal-hangman-on-google-appengine-part-1/">Google AppEngine</a> for instance.</p>

<p>Recently someone asked on the <a href="http://groups.google.com/group/cal_language">CAL Google Group</a> whether CAL programs could run on Android mobile devices. Android doesn&#8217;t use a standard JVM, it uses <a href="http://en.wikipedia.org/wiki/Dalvik_virtual_machine">Dalvik</a>, and it provides a subset of the normal JRE library.</p>

<p>I have put together a trivial proof of concept to show that CAL does indeed work on Android &#8212; although it doesn&#8217;t cover a great deal of CAL&#8217;s runtime behaviour, so there might be problems with larger programs which I haven&#8217;t detected.</p>

<p>My sample application just accumulates keypresses and displays the resulting string.</p>

<h2>The Android Activity</h2>

<p>This class delegates calls to <code>onCreate</code> and <code>onKeyUp</code> to CAL functions.</p>

<p>The state of the application (a <code>String</code> in this case) is initialised to the value returned by the CAL <code>onCreate</code> function, and is then passed to and returned from the <code>onKeyUp</code> function.</p>

<pre><code>public class CalActivity extends Activity {
    private ExecutionContext ec;
    private TextView tv;
    private String state = null;

    public CalActivity() {
        System.setProperty("org.openquark.cal.machine.lecc.non_interruptible", "true");
        ec = StandaloneRuntime.makeExecutionContext(CalActivity.class);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        tv = new TextView(this);
        try {
            state = Test.onCreate(CAL_Opaque.make(this), CAL_Opaque.make(savedInstanceState), ec);
            tv.setText(state.toString());
        } catch (CALExecutorException e) {
            tv.setText(e.getMessage());
        }
        setContentView(tv);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        char c = (char)event.getUnicodeChar();
        // ignore events which aren't characters
        if (c != 0) {
            try {
                state = Test.onKeyUp(CAL_Opaque.make(this), c, state, ec);
            } catch (CALExecutorException e) {
                tv.setText(e.getMessage());
            }
            tv.setText(state.toString());
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }
}
</code></pre>

<h2>The CAL Module</h2>

<pre><code>module Org.Kablambda.Android.Test;

... imports omitted ...

onCreate :: Activity -&gt; Bundle -&gt; String;
public onCreate activity bundle = "Hello from CAL!\n";

onKeyUp :: Activity -&gt; Char -&gt; String -&gt; String;
public onKeyUp activity ch s = s ++ (fromChar ch);
</code></pre>

<p><code>Activity</code> and <code>Bundle</code> are declared as foreign types, but don&#8217;t have any functions defined on them at present.</p>

<h2>Modifications to the build process</h2>

<p>I added some new targets to the standard <code>build.xml</code> file created by the android SDK.</p>

<pre><code>&lt;property name="quark.dir" location="${user.home}/dev/tools/cal-1.7.1" /&gt;
&lt;property name="moduleName" value="Org.Kablambda.Android.Test"/&gt;
&lt;property name="className" value="org.kablambda.android.Test"/&gt;
</code></pre>

<p>These properties set the location of our CAL installation, the name of the CAL module we want to call from Java, and the name of the class we want that module&#8217;s functions to be exposed in.</p>

<p>The <code>copy-quark-jars</code> target copies the jar files needed by CAL at runtime. They are copied into a temporary directory.</p>

<pre><code>&lt;target name="copy-quark-jars"&gt;
    &lt;mkdir dir="tmp"/&gt;
    &lt;copy
            todir="tmp"
            flatten="true"&gt;
          &lt;fileset dir="${quark.dir}/Quark/bin/java/release"&gt;
            &lt;include name="**/calLibraries.jar" /&gt;
            &lt;include name="**/calRuntime.jar" /&gt;
            &lt;include name="**/calUtilities.jar" /&gt;
          &lt;/fileset&gt;
          &lt;fileset dir="${quark.dir}/Quark/lib/Resources/External/java/"&gt;
            &lt;include name="**/icu4j.jar" /&gt;
            &lt;include name="**/log4j.jar" /&gt;
          &lt;/fileset&gt;
        &lt;/copy&gt;
  &lt;/target&gt;
</code></pre>

<p>The <code>build-quark-standalone</code> target compiles the CAL workspace <code>workspace.cws</code> into a jar file. This workspace must contain the module specified above and its dependencies. This target assumes that <code>${quarkdir}/Quark</code> is on the <code>PATH</code>.</p>

<pre><code>  &lt;target name="build-quark-standalone" depends="copy-quark-jars"&gt;
    &lt;exec executable="quarkc.sh"&gt;
        &lt;arg value="workspace.cws"/&gt;
        &lt;arg value="-lib"/&gt;
        &lt;arg value="${moduleName}"/&gt;
        &lt;arg value="public"/&gt;
        &lt;arg value="${className}"/&gt;
        &lt;arg value="tmp/calmodule.jar"/&gt;
        &lt;arg value="-src"/&gt;
        &lt;arg value="calmodule-src.zip"/&gt;
        &lt;env key="QUARK_CP" value="src:bin:${sdk-location}/platforms/android-1.5/android.jar"/&gt;
    &lt;/exec&gt;
  &lt;/target&gt;
</code></pre>

<p>Because several of the CAL jars contain duplicate files, which Android doesn&#8217;t tolerate, we merge all our jars into a single file, ignoring duplicates.</p>

<pre><code>&lt;target name="merge-jars" depends="build-quark-standalone"&gt;
    &lt;zip destfile="libs/cal.jar" duplicate="preserve"&gt;
        &lt;zipgroupfileset dir="tmp" includes="*.jar"/&gt;           
    &lt;/zip&gt;
&lt;/target&gt;
</code></pre>

<p>To deploy your application to the Android Emulator you need to run <code>ant merge-jars reinstall</code>.</p>

<p>Note that during the process of converting the <code>cal.jar</code> file to Dalvik bytecode you&#8217;ll see a large number of error messages like this:</p>

<pre><code>[apply] ...while processing com/ibm/icu/util/TimeZoneData.class
[apply] warning: Ignoring InnerClasses attribute for an anonymous inner class that doesn't come with an associated EnclosingMethod attribute. (This class was probably produced by a broken compiler.)
</code></pre>

<p>This is something to do with the rather old version of IBM&#8217;s <a href="http://site.icu-project.org/home">International Components for Unicode library</a> &#8212; it would be interesting to recompile CAL with a more recent version &#8212; or just recompiling that version of <code>icu4j</code> with the Sun compiler.</p>

<h2>Further Work</h2>

<p>The Android API needs to be exposed to CAL, and a Monad written to sequence Android API operations which have side effects. The <code>CalActivity</code> implementation should store the state as an opaque <code>CalValue</code>, so that implementations can choose what type to use for their state, and of course it needs to delegate all the possible events to CAl functions. There&#8217;s plenty of scope for more scaffolding on the CAL side.</p>

<p>As I don&#8217;t have an Android phone I doubt that I&#8217;ll do any further work on this &#8212; unless Dalvik gets an iPhone port <img src='http://www.kablambda.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.kablambda.org/blog/2009/07/27/functional-programming-on-android/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Reconsidering my Combinators</title>
		<link>http://www.kablambda.org/blog/2009/05/25/reconsidering-my-combinators/</link>
		<comments>http://www.kablambda.org/blog/2009/05/25/reconsidering-my-combinators/#comments</comments>
		<pubDate>Mon, 25 May 2009 12:00:14 +0000</pubDate>
		<dc:creator>Tom Davies</dc:creator>
				<category><![CDATA[AppEngine]]></category>
		<category><![CDATA[CAL and Open Quark]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.kablambda.org/blog/?p=86</guid>
		<description><![CDATA[Since writing my set of function combinators for matching HTTP requests I&#8217;ve realised that there are better approaches.

While the combinators read nicely, once you start extracting attributes from the request things become messy, due to the hAnd combinator composing results as nested pairs.

Here&#8217;s an example:

skitchPutHandler =
    let
      [...]]]></description>
			<content:encoded><![CDATA[<p>Since writing my set of function combinators for matching HTTP requests I&#8217;ve realised that there are better approaches.</p>

<p>While the combinators read nicely, once you start extracting attributes from the request things become messy, due to the <code>hAnd</code> combinator composing results as nested pairs.</p>

<p>Here&#8217;s an example:</p>

<pre><code>skitchPutHandler =
    let
        storeImage p =
            let (p2, path) = p;
                (maybeContentType,imageData) = p2;
                ...
            in ...
    in
        matchMethod "PUT" `hThen` matchUrl "/skitch" `hThen`
            (getHeader "Content-Type") `hAnd` requireRawData `hAnd` requirePathInfo `hApply` storeImage;
</code></pre>

<p>Unpacking the values extracted from the request is cumbersome, and because many are <code>String</code>s, error prone.</p>

<p>A better approach is to simply use the <code>Maybe</code> monad with the same extraction functions:</p>

<pre><code>simpleSkitchPutHandler req =
    let
        maybeContentType = requireHeader "Content-Type" req;
        ...
    in
        matchMethod "PUT" req `anonymousBind` matchUrl "/skitch" req `anonymousBind`
            requireRawData req `bind` (\rawData -&gt;
            requirePathInfo req `bind` (\path -&gt;
            return $ storeImage path rawData (actualContentType path)));
</code></pre>

<p>Optional values are extracted in let expressions, and required values and tests are composed with the monadic <code>bind</code> operators in the main expression.
You can make the function a bit more concise and &#8216;point free&#8217; by writing a monad which composes the <code>Maybe</code> and <code>Reader</code> monads to supply the HTTP request parameter to functions implicitly:</p>

<pre><code>readerMonadSkitchPutHandler =
    let
        ...
    in
        runHttpRequestM (
        method "PUT" `anonymousBind` matchUrlM "/skitch" `anonymousBind`
            rawData `bind` (\rawData -&gt;
            pathInfo `bind` (\path -&gt;
            (optional (header "Content-Type")) `bind` (\maybeContentType -&gt;
            return $ storeImage path rawData (actualContentType path maybeContentType)))));
</code></pre>

<p>The function <code>optional</code> has the type <code>HttpRequestM a -&gt; HttpRequestM (Maybe a)</code>, that is, it allows a function to succeed by wrapping its result in a &#8216;Just&#8217;.</p>

<p>I&#8217;m not convinced that the improvement in readability gained by removing the request parameter is worth the increase in complexity.</p>

<p>So I&#8217;ll remove the combinators from my <code>Http</code> module and will rewrite Hangman using just the Maybe monad. I&#8217;ll keep the more complicated Monad on the back-burner in case I discover a compelling advantage.</p>

<p>I&#8217;d be interested to know what someone with a deeper understanding of functional programming would say.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kablambda.org/blog/2009/05/25/reconsidering-my-combinators/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CAL Hangman on GAE Part 2 &#8212; The Datastore</title>
		<link>http://www.kablambda.org/blog/2009/05/12/cal-hangman-on-gae-part-2-the-datastore/</link>
		<comments>http://www.kablambda.org/blog/2009/05/12/cal-hangman-on-gae-part-2-the-datastore/#comments</comments>
		<pubDate>Tue, 12 May 2009 12:48:48 +0000</pubDate>
		<dc:creator>Tom Davies</dc:creator>
				<category><![CDATA[AppEngine]]></category>
		<category><![CDATA[CAL and Open Quark]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.kablambda.org/blog/?p=83</guid>
		<description><![CDATA[Introduction

My implementation of Hangman has only very simple data storage requirements, so my CAL module Datastore doesn&#8217;t cover the entire capabilities of Bigtable.

All the application needs is to be able to save a Game instance, put the key of that instance into a cookie in the user&#8217;s browser, and then retrieve and update that instance [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>

<p>My implementation of Hangman has only very simple data storage requirements, so my CAL module <code>Datastore</code> doesn&#8217;t cover the entire capabilities of Bigtable.</p>

<p>All the application needs is to be able to save a <code>Game</code> instance, put the key of that instance into a cookie in the user&#8217;s browser, and then retrieve and update that instance as the user makes each guess, or delete it if the user chooses to restart the game.</p>

<p>Important unexplored areas are:</p>

<ul>
<li><p>The creation of entities having another entity as a parent. This is important in Bigtable, because a transaction can only operate on entities in the same &#8216;entity group&#8217; &#8212; that is, entities which share a common parent.</p></li>
<li><p>The persistence of references to other entities, and special treatment of these references when performing operations on the entity containing the reference &#8212; that is, there is no support for modelling relationships between entities.</p></li>
<li><p>No error handling support &#8212; any exception will result in a 500 response. In particular, <code>ConcurrentModificationException</code> should be treated differently, as this indicates that a transaction failed due to another transaction modifying the same records. A failure of this type should either be retried, or reported to the user in an application specific manner.</p></li>
<li><p>The module is limited to storing types with a single constructor, although there is no difficulty in extending this to support multiple constructor ADTs.</p></li>
</ul>

<p>It is implemented using the <a href="http://code.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/package-summary.html">low level api</a>, not JDO.</p>

<h2>Datastore Module</h2>

<p>The <code>Datastore</code> module provides a <code>Monad</code> instance for using the AppEngine data store, and a <code>Storeable</code> type class. The source is <a href="http://bazaar.launchpad.net/%7Etgdavies/cal-on-gae/main/annotate/head%3A/src/CAL/Org/Kablambda/AppEngine/Datastore.cal">here</a>.</p>

<h3>The Storeable Type Class</h3>

<p>Algebraic data types which need to be persisted must be instances of <code>Storeable</code>, which provides metadata needed to persist instances of the type. The metadata includes:</p>

<ul>
<li><p>The &#8216;kind&#8217; of the record &#8212; analogous to the name of the table to store instances of the type in, not to kind in the type theory sense.</p></li>
<li><p>The data store property names to use for each of the constructor arguments.</p></li>
</ul>

<p>When using CAL in statically compiled mode the names of types and the names of constructor parameters are not easily available at runtime. The constructor arguments could simply be stored in properties named <code>arg0...n</code>, but this would make querying and debugging more difficult.</p>

<pre><code>data public Store a = public Store kind :: String fields :: [String];

public class (Outputable a, Inputable a) =&gt; Storeable a where
    store :: a -&gt; Store a;
    ;
</code></pre>

<p>Note that the type parameter <code>a</code> is not used in the declaration of the constructor arguments &#8212; it simply labels the store to ensure that the store used with, for example <code>fromEntity</code> below, is consistent with the type of <code>Storeable</code> we are expecting <code>fromEntity</code> to return. For this reason functions which construct a <code>Store</code> must be explicitly typed, like <code>gameStore</code> below, as otherwise no more specific type than <code>Store a</code> can be inferred.</p>

<p>So the instance for a game of hangman is:</p>

<pre><code>data public Game = 
    private Game word :: String guesses :: String deriving Show, Inputable, Outputable;

gameStore :: Store Game;
public gameStore = Store "Org.Kablambda.AppEngine.Test.Game" ["word","guesses"];

instance Storeable Game where
    store = gameStoreA;
    ;

private gameStoreA a = gameStore;
</code></pre>

<p>The public <code>gameStore</code> function is used when we wish to query.</p>

<h3>Converting between CAL values and AppEngine Entities</h3>

<p>Two conversion functions are used, one in each direction. In both cases the bulk of the work is carried out in Java functions.</p>

<h4>From a CAL value to an Entity</h4>

<pre><code>toEntity :: Storeable a =&gt; a -&gt; Entity;
public toEntity !r =
    jObjectToEntity (store r).Store.kind (outputList $ (store r).Store.fields) (output r);
</code></pre>

<p>where:</p>

<pre><code>foreign unsafe import jvm "static method org...jObjectToEntity" 
    public jObjectToEntity :: String -&gt; JList -&gt; JObject -&gt; Entity;
</code></pre>

<p>The parameters passed to <code>jObjectToEntity</code> are the kind of entity to create, the list of names to use for the fields of the CAL value, and the CAL value, converted to a <code>JObject</code> by the <code>output</code> function. <code>Storeable</code> instances should all derive <code>Outputable</code>, so <code>output r</code> uses the default implementation of <code>output</code> to convert the algebraic data type instance to an instance of the CAL Java support class <code>AlgebraicValue</code>. The fields are transferred to the AppEngine entity like this:</p>

<pre><code>Entity entity = new Entity(kind);
AlgebraicValue av = ...;
entity.setProperty(DC_NAME, av.getDataConstructorName());
entity.setProperty(DC_ORDINAL, av.getDataConstructorOrdinal());
for (String fieldName : fieldNames) {
    entity.setProperty(fieldName, av.getNthArgument(i++));
}
</code></pre>

<h4>From an Entity to a CAL value</h4>

<pre><code>fromEntity :: Storeable a =&gt; Store a -&gt; Entity -&gt; a;
public fromEntity !s !e =
    input $ jEntityToJObject (outputList s.Store.fields) e;
</code></pre>

<p>where:</p>

<pre><code>foreign unsafe import jvm "static method org...entityToJObject" 
   public jEntityToJObject :: JList -&gt; Entity -&gt; JObject;
</code></pre>

<p><code>jEntityToJObject</code> reverses the process, creating an <code>AlgebraicValue</code> which is converted to a CAL value by the <code>input</code> function.</p>

<h3>The Data Store Monad</h3>

<p>Because data store operations operate via side effects we need to create a <code>Monad</code> instance to manage them. This is required or two reasons:</p>

<ul>
<li><p>We need to ensure that our data store operations happen in a definite sequence &#8212; our puts must happen before we commit the transaction, for example. Lazy evaluation won&#8217;t guarantee this without special attention.</p></li>
<li><p>Some operation don&#8217;t produce results, or produce results which will be ignored, so lazy evaluation won&#8217;t cause these operations to happen at all.</p></li>
</ul>

<p>We define the following functions for use with our <code>Monad</code> (the type of which is <code>DSM</code>):</p>

<pre><code>put :: Storeable a =&gt; a -&gt; DSM Key;
</code></pre>

<p>The <code>put</code> function creates a new record, returning the <code>Key</code> it was assigned by the data store.</p>

<pre><code>update :: Storeable a =&gt; Entity -&gt; a -&gt; DSM Key;
</code></pre>

<p>The <code>update</code> function replaces a previously retrieved entity with a new value, returning the <code>Key</code> (which will always be the same as the old key). Note that the original Entity is used only for the value of its key &#8212; all the replacement fields come from the new <code>Storeable</code> value.</p>

<pre><code>delete :: Entity -&gt; DSM ();
</code></pre>

<p>The <code>delete</code> function deletes a previously retrieved entity.</p>

<pre><code>find :: (Storeable a) =&gt; Store a -&gt; Key -&gt; DSM (Maybe (Entity,a));
</code></pre>

<p>The <code>find</code> function looks for a record using a <code>Key</code> and returns it or <code>Nothing</code> if it does not exist. The return value consists of a pair of values: the raw <code>Entity</code> and its value when converted to a <code>Storeable</code> instance. This allows update to be used later. An alternative design would have been to require <code>Storeable</code> instances to be able to store a key, but I think the current design better separates the concerns of data storage from the domain objects.</p>

<pre><code>query :: (Storeable a, Outputable b) =&gt; Store a -&gt; [(String,FilterOperator,b)] -&gt; [(String,SortDirection)] -&gt; DSM [(Entity,a)];
</code></pre>

<p>The <code>query</code> function returns a sorted list of (Entity,Storeable) pairs, based on a list of filter criteria applied to attributes of the records.</p>

<pre><code>commit :: DSM ();
</code></pre>

<p>The <code>runDSM</code> function described below starts and commits the transaction within which the monad is being run, but if you need to operate on entities from more than one entity group you must commit the original transaction and start a new one using the <code>commit</code> function.</p>

<p>These functions are combined with the normal monad operators of <code>bind</code> and <code>anonymousBind</code>, and then the resulting function is &#8216;run&#8217; with <code>runDSM</code>:</p>

<pre><code>runDSM :: DSM a -&gt; a;
</code></pre>

<h3>Key Conversion</h3>

<p>In the context of a web application we may wish to store keys in cookies or generated URLs. The following functions are provided for extracting <code>Key</code>s from <code>Entity</code> instances, and converting <code>Key</code>s to and from strings.</p>

<pre><code>public keyToString :: Key -&gt; String; 
public stringToKey :: String -&gt; Key;
public getKey :: Entity -&gt; Key;
</code></pre>

<h2>Example</h2>

<p>Suppose we want to retrieve a <code>Game</code>, add a letter to the set of guesses and store it again:</p>

<pre><code>    updateGame :: Key -&gt; Char -&gt; Key;
    updateGame key letter =
        runDSM (find gameStore key `bind` (\p -&gt;
            let (entity, game) = fromJust p;
            in update entity (addGuess letter game)
        ));
</code></pre>

<p>where <code>addGuess</code> returns a new game with the given letter added to its set of guesses. This function will terminate with an error if the <code>Game</code> is not found, that is, if <code>find</code> returns <code>Nothing</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kablambda.org/blog/2009/05/12/cal-hangman-on-gae-part-2-the-datastore/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CAL Hangman on Google AppEngine, Part 1</title>
		<link>http://www.kablambda.org/blog/2009/04/27/cal-hangman-on-google-appengine-part-1/</link>
		<comments>http://www.kablambda.org/blog/2009/04/27/cal-hangman-on-google-appengine-part-1/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 08:55:46 +0000</pubDate>
		<dc:creator>Tom Davies</dc:creator>
				<category><![CDATA[AppEngine]]></category>
		<category><![CDATA[CAL and Open Quark]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.kablambda.org/blog/?p=78</guid>
		<description><![CDATA[This post describes a simple implementation of the game &#8216;Hangman&#8217;, written in CAL for Google Appengine.

Introduction

Hangman is a simple word guessing game &#8212; the computer chooses a word, telling you only how many letters it has. You that it contains a particular letter. Correct guesses fill in those letters in the word, until you have [...]]]></description>
			<content:encoded><![CDATA[<p>This post describes a simple implementation of the game &#8216;Hangman&#8217;, written in <a href="http://openquark.org">CAL</a> for <a href="http://code.google.com/appengine">Google Appengine</a>.</p>

<h2>Introduction</h2>

<p>Hangman is a simple word guessing game &#8212; the computer chooses a word, telling you only how many letters it has. You that it contains a particular letter. Correct guesses fill in those letters in the word, until you have guessed all the letters in the word, or you  make too many incorrect guesses and lose.</p>

<p>You can try my <a href="http://aet-tgdavies.appspot.com/hangman/play">Hangman for AppEngine</a> implementation to understand the game. The source is available at <a href="https://code.launchpad.net/cal-on-gae">launchpad</a>.</p>

<p>Hangman is a very simple game &#8212; the state is just the word being guessed, and the letters guessed so far. The point of implementing it in CAL on AppEngine is to develop CAL modules for the AppEngine API classes.</p>

<h2>Design</h2>

<p>It would be easy to implement hangman as a mostly client-side browser based application, but that wouldn&#8217;t have exercised much of the AppEngine API.</p>

<p>To make the task interesting, I decided that the game state would be persisted on the server, and a user&#8217;s current game would be identified by a cookie in their browser. So you can make some guesses, close your browser, and come back to the same game later.</p>

<h2>Http Module</h2>

<p>The <code>Http</code> module provides function for creating a server which handles requests and creates responses. The source is <a href="http://bazaar.launchpad.net/%7Etgdavies/cal-on-gae/main/annotate/head%3A/src/CAL/Org/Kablambda/AppEngine/Http.cal">here</a>.</p>

<h3>The Server Function</h3>

<p>All requests go through a single servlet, which is configured with <code>init-param</code>s to reflectively call a static method generated by the CAL stand-alone jar builder.</p>

<p>The function called by the servlet must have the type <code>HttpServletRequest -&gt; JHttpServletResponse</code>. These CAL types are simply imports of the Java <code>HttpServletRequest</code> and <code>HttpServletResponse</code> classes.</p>

<pre><code>data foreign unsafe import jvm "javax.servlet.http.HttpServletRequest"
    public HttpServletRequest deriving Inputable, Outputable;

data foreign unsafe import jvm "javax.servlet.http.HttpServletResponse"
    private JHttpServletResponse deriving Inputable, Outputable;
</code></pre>

<p><code>JHttpServletResponse</code> is private to the module because it is mutable and so shouldn&#8217;t be exposed to clients of the module. Instead <code>Http</code> provides a data type <code>HttpServletResponse</code>:</p>

<pre><code>data public HttpServletResponse =
    private HttpServletResponse cookies :: [Cookie] headers :: [Header] body :: HttpServletResponseBody;

data public HttpServletResponseBody =
    private Ok contentType :: String content :: (Array Byte) |
    private Error code :: Int message :: (Maybe String) |
    private Redirect url :: String;
</code></pre>

<p>This allows the client to assemble the state of a response, which is then applied to the response in a single operation by the <code>Http</code> module. A monad to sequence operations on the Java response object would have been another alternative, but that wouldn&#8217;t enforce correct construction of the response to the same degree &#8212; e.g. the client might not set a content type. Note that the actual constructors are private so that the structure of the type is not exposed to clients of this module.</p>

<p>The current data type doesn&#8217;t allow the response to be streamed.</p>

<p>As clients can&#8217;t see or use <code>JHttpServletResponse</code> they need to use the <code>server</code> function to create a web server:</p>

<pre><code>server :: [HttpServletRequest -&gt; Maybe HttpServletResponse] -&gt; HttpServletRequest -&gt; JHttpServletResponse -&gt; ();
</code></pre>

<p>This function takes a list of handlers, each of which is tried in sequence until one returns a response. So the server function for the hangman web application is:</p>

<pre><code>public service =
    server [currentGameHandler, newGameHandler, guessHandler, restartHandler];
</code></pre>

<h3>Writing Handlers</h3>

<p>The <code>Http</code> module provides functions to test and retrieve properties of the request, and combinators to build handlers from these individual functions. The combinators are inspired by Mark Tullsen&#8217;s <em>First Class Patterns</em>.</p>

<p>Each combinator combines two functions, each of which extracts a property of the request, and returns a function of the type <code>HttpServletRequest -&gt; Maybe a</code>.</p>

<p>It isn&#8217;t clear to me that this is the very best approach &#8212; experimenting with a <code>Maybe/Reader</code> monad stack would be interesting.</p>

<h4>Combinators</h4>

<pre><code>hOr :: (HttpServletRequest -&gt; Maybe a) -&gt; (HttpServletRequest -&gt; Maybe a) -&gt; (HttpServletRequest -&gt; Maybe a);
</code></pre>

<p><code>hOr</code> requires that at least one of two extraction functions succeeds, i.e. returns <code>Just x</code>. The final result is the result of the first extraction function to succeed (if the first extraction function succeeds, the second is not evaluated).</p>

<pre><code>hThen :: (HttpServletRequest -&gt; Maybe a) -&gt; (HttpServletRequest -&gt; Maybe b) -&gt; (HttpServletRequest -&gt; Maybe b);
</code></pre>

<p><code>hThen</code> requires that both the extraction functions succeed, but it discards the result of the first extraction function.</p>

<pre><code>hAnd :: (HttpServletRequest -&gt; Maybe a) -&gt; (HttpServletRequest -&gt; Maybe b) -&gt; (HttpServletRequest -&gt; Maybe (a,b));
</code></pre>

<p><code>hAnd</code> requires that both extraction functions succeed, and returns their results as a pair.</p>

<pre><code>hNot :: (HttpServletRequest -&gt; Maybe a) -&gt; (HttpServletRequest -&gt; Maybe ());
</code></pre>

<p><code>hNot</code> reverses the sense of an extractor, succeeding if it fails and vice-versa.</p>

<p>The following combinators have specialised functions, rather than acting to combine two extraction functions.</p>

<pre><code>hCompose :: (HttpServletRequest -&gt; Maybe a) -&gt; (a -&gt; b) -&gt; (HttpServletRequest -&gt; Maybe b);
</code></pre>

<p><code>hCompose</code> transforms the result of an extraction function.</p>

<pre><code>hApply :: (HttpServletRequest -&gt; Maybe a) -&gt; (a -&gt; HttpServletResponse) -&gt; (HttpServletRequest -&gt; Maybe HttpServletResponse);
</code></pre>

<p><code>hApply</code> combines a sequence of extraction functions with a function that produces a response.</p>

<pre><code>hAttempt :: (HttpServletRequest -&gt; Maybe a) -&gt; (a -&gt; Maybe HttpServletResponse) -&gt; (HttpServletRequest -&gt; Maybe HttpServletResponse);
</code></pre>

<p><code>hAttempt</code> is like <code>hApply</code>, but the response generation function returns <code>Maybe HttpServletResponse</code>, allowing further conditional processing outside the context of combined extraction functions.</p>

<h4>Request Attribute Extractors</h4>

<p>These functions look at attributes of the response and return their values (which may amount to just signalling their presence or absence).</p>

<pre><code>getParameter :: String -&gt; HttpServletRequest -&gt; Maybe (Maybe String);
</code></pre>

<p><code>getParameter</code> extracts the value of a named parameter from the request. It always succeeds, returning <code>Just Nothing</code> or <code>Just $ Just paramValue</code>.</p>

<pre><code>requireParameter :: String -&gt; HttpServletRequest -&gt; Maybe String;
</code></pre>

<p><code>requireParameter</code> extracts the value of a named parameter, but fails (i.e. returns <code>Nothing</code>) if it is not set.</p>

<p>There are similar <code>get/require</code> <code>Header/Cookie</code> functions.</p>

<pre><code>matchUrl :: String -&gt; HttpServletRequest -&gt; Maybe ();
</code></pre>

<p><code>matchUrl</code> takes a string containing a regular expression, and succeeds if the regular expression matches the path info of the request. It would be useful to have another function which returns the values of capturing groups of the regular expression.</p>

<h3>Creating the Response</h3>

<p>Utility functions are provided for each common response type.</p>

<pre><code>ok :: HasByteRep a =&gt; String -&gt; a -&gt; HttpServletResponse;
public ok contentType content = ...

textHtml :: HasByteRep a =&gt; a -&gt; HttpServletResponse;
public textHtml = ok "text/html";

redirect :: String -&gt; HttpServletResponse;
public redirect url = ...

err :: Int -&gt; Maybe String -&gt; HttpServletResponse;
public err code msg = ...
</code></pre>

<p>These functions all create requests with default headers. Headers and Cookies are added by applying a function to the request.</p>

<pre><code>addHeader :: Header -&gt; HttpServletResponse -&gt; HttpServletResponse;
addCookie :: Cookie -&gt; HttpServletResponse -&gt; HttpServletResponse;  
</code></pre>

<h2>Example</h2>

<p>Rather than an example from the hangman game, here&#8217;s a simple example which uses the functions discussed directly.</p>

<pre><code>helloHandler =
    let
        page p = 
            let (firstName, maybeLastName) = p;
            in ok "text/plain" (
                case maybeLastName of
                    Just lastName -&gt; "Greetings, " ++ firstName ++ " " ++ lastName;
                    Nothing -&gt; "Hi there " ++ firstName;
                );
    in
        matchUrl "/hello" `hThen`
        (requireParameter "firstName") `hAnd`
        (getParameter "lastName") `hApply` page;
</code></pre>

<p>This handler will return a page for the url <code>/hangman/hello</code> <em>if</em> the <code>firstName</code> parameter is present. To keep the example as simple as possible it uses the <code>text/plain</code> content type to avoid the verbiage of an HTML page.</p>

<h2>To be continued&#8230;</h2>

<p>In the next instalment I&#8217;ll describe the CAL module which supports the AppEngine datastore.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kablambda.org/blog/2009/04/27/cal-hangman-on-google-appengine-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Functional Programming on Google AppEngine</title>
		<link>http://www.kablambda.org/blog/2009/04/09/functional-programming-on-google-appengine/</link>
		<comments>http://www.kablambda.org/blog/2009/04/09/functional-programming-on-google-appengine/#comments</comments>
		<pubDate>Thu, 09 Apr 2009 08:17:33 +0000</pubDate>
		<dc:creator>Tom Davies</dc:creator>
				<category><![CDATA[AppEngine]]></category>
		<category><![CDATA[CAL and Open Quark]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.kablambda.org/blog/?p=72</guid>
		<description><![CDATA[I&#8217;ve always hoped that Java would be the next Google App Engine language. Google have provided a solid platform with a &#8216;real&#8217; JVM and few restrictions.

I deployed the sample application created with the Eclipse plugins a few minutes after my account was upgraded to support Java, and then I went on to deploy an application [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve always hoped that Java would be the next Google App Engine language. Google have provided a solid platform with a &#8216;real&#8217; JVM and few restrictions.</p>

<p>I deployed the sample application created with the Eclipse plugins a few minutes after my account was upgraded to support Java, and then I went on to deploy an application written in <a href="http://openquark.org">CAL</a>.</p>

<p>There are two ways of integrating CAL and Java. The first is to dynamically load and compile a workspace at run time, and then reflectively call functions in the workspace&#8217;s modules. I&#8217;ve used this approach in the past, for example for <a href="http://www.kablambda.org/blog/2008/03/27/a-cal-webapp-with-persistent-data-using-gwt-stm-and-bdb/">CAL/GWT integration</a>.</p>

<p>There are two reasons not to use this approach for an AppEngine application. Firstly, when CAL loads a workspace it uses a SecurityManager, which GAE doesn&#8217;t allow. It&#8217;s just used to get the class of the caller of a function so the code could probably be replaced by looking at the stack trace of an un-thrown Exception, but that would involve a custom CAL build. I suspect that this approach would also want to create some local files, which also wouldn&#8217;t work on AppEngine.</p>

<p>The other reason not to use this approach is that AppEngine runs your application on (potentially) many different JVM instances, and may stop your application when it is idle and restart it when it receives a request. Nothing I&#8217;ve read so far indicates how often this happens, but start up overhead which would be perfectly acceptable in a normal application server is likely to be a bad idea in AppEngine.</p>

<p>CAL modules can also be compiled statically to a &#8217;stand-alone&#8217; jar file.</p>

<p>Each public function in the module becomes a static function on the resulting class, e.g.:</p>

<pre><code>square :: Int -&gt; Int;
public square n = n * n;
</code></pre>

<p>becomes:</p>

<pre><code>public static int square(int n, ExecutionContext context)
</code></pre>

<p>If we hadn&#8217;t explicitly typed square, it would have the inferred type <code>Num a =&gt; a -&gt; a</code> and the function would have the signature</p>

<pre><code>public static CalValue square(CalValue n, ExecutionContext context);
</code></pre>

<p>Where a <code>CalValue</code> can hold any Java types which CAL knows how to convert to CAL types via the <code>input</code> function, and <code>ExecutionContext</code> really just caches <a href="http://haskell.org/haskellwiki/Constant_applicative_form">Constant Applicative Forms</a>.</p>

<p>So the components of a minimal CAL application for AppEngine are:</p>

<ol>
<li>A module which imports <code>HttpServletRequest</code> and <code>HttpServletResponse</code> and provides suitable functions to get their properties and to set attributes of the response.</li>
<li>A function with the type <code>HttpServletRequest -&gt; HttpServletResponse -&gt; ()</code>.</li>
<li>A servlet which calls that function.</li>
<li>Extensions to the example <code>build.xml</code> provided by Google which package up the CAL modules into a stand-alone jar, and include the runtime support jars CAL needs.</li>
</ol>

<p>Additionally all the other AppEngine Services (Data Store, Cache, Mail etc.) need to be made available to CAL (in Monads of course <img src='http://www.kablambda.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ), but that can be done piecemeal as you need them.</p>

<p>I&#8217;ll just give one example from the Http module, as it illustrates the issue of dealing with <code>null</code> being returned by Java methods.</p>

<p>First I import the <code>HttpServletRequest.getParameter</code> method:</p>

<pre><code>foreign unsafe import jvm "method getParameter"
    jGetParameter :: HttpServletRequest -&gt; String -&gt; String;
</code></pre>

<p>But it isn&#8217;t made public. The &#8216;real&#8217; getParameter function is defined like this:</p>

<pre><code>public getParameter req s =
    let v = jGetParameter req s;
    in if isNullString v then Nothing else Just v;
</code></pre>

<p>Allowing the <code>Maybe</code> type to handle the possibility that a parameter may not be set.</p>

<p>The <code>build.xml</code> changes are:</p>

<pre><code>&lt;target name="copy-quark-jars"&gt;
    &lt;copy
            todir="war/WEB-INF/lib"
            flatten="true"&gt;
          &lt;fileset dir="${quark.dir}/Quark/bin/java/release"&gt;
            &lt;include name="**/calLibraries.jar" /&gt;
            &lt;include name="**/calPlatform.jar" /&gt; &lt;!-- maybe don't need? --&gt;
            &lt;include name="**/calRuntime.jar" /&gt;
            &lt;include name="**/calUtilities.jar" /&gt;
          &lt;/fileset&gt;
          &lt;fileset dir="${quark.dir}/Quark/lib/Resources/External/java/"&gt;
            &lt;include name="**/icu4j.jar" /&gt;
            &lt;include name="**/log4j.jar" /&gt;
          &lt;/fileset&gt;
        &lt;/copy&gt;
&lt;/target&gt;

&lt;target name="build-quark-standalone" depends="copyjars"&gt;
    &lt;exec executable="quarkc.sh"&gt;
        &lt;arg value="workspace.cws"/&gt;
        &lt;arg value="-lib"/&gt;
        &lt;arg value="${moduleName}"/&gt;
        &lt;arg value="public"/&gt;
        &lt;arg value="${className}"/&gt;
        &lt;arg value="war/WEB-INF/lib/calmodule.jar"/&gt;
        &lt;env key="QUARK_CP" value="src:war/WEB-INF/lib/appengine-api-1.0-sdk-1.2.0.jar:${sdk.dir}/lib/shared/geronimo-servlet_2.5_spec-1.2.jar"/&gt;
    &lt;/exec&gt;
&lt;/target&gt;
</code></pre>

<p>Now to do something useful with it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kablambda.org/blog/2009/04/09/functional-programming-on-google-appengine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Take Two</title>
		<link>http://www.kablambda.org/blog/2008/07/09/take-two/</link>
		<comments>http://www.kablambda.org/blog/2008/07/09/take-two/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 03:32:52 +0000</pubDate>
		<dc:creator>Tom Davies</dc:creator>
				<category><![CDATA[CAL and Open Quark]]></category>
		<category><![CDATA[Computer Science]]></category>

		<guid isPermaLink="false">http://diversions.nfshost.com/blog/2008/07/09/take-two/</guid>
		<description><![CDATA[I&#8217;m much happier with the second version:

out3 a =
    let
        renderGroup g =
            let 
                char = head g;
 [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m much happier with the second version:</p>

<pre><code>out3 a =
    let
        renderGroup g =
            let 
                char = head g;
                count = length g;
                renderChars :: Int -&gt; String;
                renderChars n =
                    (fromChar char) ++
                    (if n &gt;1 then  " " ++ (renderChars $ n-1) else "");
            in
                if count &gt; 2 then
                    (renderChars 2) ++ 
                    " &lt;span&gt;" ++ (renderChars (count - 2)) ++ "&lt;/span&gt;"
                else
                    renderChars count;
        concatWithSep list = (head list) ++ concatMap (\s -&gt; " " ++ s) (tail list);
    in
        concatWithSep $ map renderGroup (group a);
</code></pre>

<p>This only uses one &#8216;exotic&#8217; list function, group:</p>

<pre><code>group :: Eq a =&gt; [a] -&gt; [[a]]
    Splits the specified list into a list of lists of equal, adjacent elements.
</code></pre>

<p>My program is longer than Matt&#8217;s &#8212; roughly twice as long &#8212; but I think this version is easier to understand.</p>

<p>Matt&#8217;s Javascript for loop has some complicated state, contained in some loop variables which are modified in the body of the loop as well as in the for statement itself. I think that&#8217;s a recipe for confusion.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kablambda.org/blog/2008/07/09/take-two/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Dustin&#8217;s Programming Problem Take One</title>
		<link>http://www.kablambda.org/blog/2008/07/09/dustins-programming-problem-take-one-2/</link>
		<comments>http://www.kablambda.org/blog/2008/07/09/dustins-programming-problem-take-one-2/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 22:07:14 +0000</pubDate>
		<dc:creator>Tom Davies</dc:creator>
				<category><![CDATA[CAL and Open Quark]]></category>
		<category><![CDATA[Computer Science]]></category>

		<guid isPermaLink="false">http://diversions.nfshost.com/blog/2008/07/09/dustins-programming-problem-take-one-2/</guid>
		<description><![CDATA[My colleague Matt Ryall wrote about this simple algorithm for marking up a series of letters &#8212; which is complex enough to be interesting.

I wrote a version in CAL:

arr = ['a', 'b', 'c', 'c', 'd', 'e', 'e', 'e', 'e', 'e',
          'f', 'e', 'f', 'e', 'f', 'a', [...]]]></description>
			<content:encoded><![CDATA[<p>My colleague Matt Ryall <a href="http://mattryall.net/blog/2008/07/dustins-programming-problem">wrote about this simple algorithm</a> for marking up a series of letters &#8212; which is complex enough to be interesting.</p>

<p>I wrote a version in <a href="http://openquark.org">CAL</a>:</p>

<pre><code>arr = ['a', 'b', 'c', 'c', 'd', 'e', 'e', 'e', 'e', 'e',
          'f', 'e', 'f', 'e', 'f', 'a', 'a', 'a', 'f', 'f', 'f'];

data State = State string :: String current :: (Maybe Char) count :: Int;

out =
    let
        initial = State "" Nothing 0;
        f :: State -&gt; Char -&gt; State;
        f state char =
            let
                State s current count = state;
                charStr = fromChar char;
                appendSameChar = 
                    if count == 2 then
                        s ++ " &lt;span&gt;" ++ charStr
                    else
                        s ++ " " ++ charStr;
                appendDiffChar =
                    if count &gt; 2 then
                        s ++ "&lt;/span&gt; " ++ charStr
                    else
                        s ++ " " ++ charStr;
            in
                case current of
                    Nothing -&gt; State (fromChar char) (Just char) (1 :: Int);
                    Just c -&gt;
                        if c == char then
                            State appendSameChar (Just char) (count+1)
                        else
                            State appendDiffChar (Just char) 1;
            ;
        finalState = foldLeftStrict f initial arr;
    in
        finalState.State.string ++(if finalState.State.count &gt; 2 then
            "&lt;/span&gt;"
        else
            "");
</code></pre>

<p>Positive proof that you can write verbose, confusing code in any language &#8212; but at least this code had no bugs &#8212; once it compiled it worked correctly first time.</p>

<p>As a follow up to this I will try to do better!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kablambda.org/blog/2008/07/09/dustins-programming-problem-take-one-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A CAL webapp with persistent data using GWT, STM and BDB</title>
		<link>http://www.kablambda.org/blog/2008/03/27/a-cal-webapp-with-persistent-data-using-gwt-stm-and-bdb/</link>
		<comments>http://www.kablambda.org/blog/2008/03/27/a-cal-webapp-with-persistent-data-using-gwt-stm-and-bdb/#comments</comments>
		<pubDate>Thu, 27 Mar 2008 12:24:26 +0000</pubDate>
		<dc:creator>Tom Davies</dc:creator>
				<category><![CDATA[CAL and Open Quark]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://diversions.nfshost.com/blog/2008/03/27/a-cal-webapp-with-persistent-data-using-gwt-stm-and-bdb/</guid>
		<description><![CDATA[aka, attack of the TLAs.

This webapp&#8217;s architecture is depicted below:




The browser runs a Javascript thick client compiled from Java by GWT. Some of the classes have CAL annotations. These don&#8217;t affect the client, but allow the server side of the GWT RPC protocol to call CAL functions.
The CAL functions store persistent data using Software Transactional [...]]]></description>
			<content:encoded><![CDATA[<p>aka, attack of the TLAs.</p>

<p>This webapp&#8217;s architecture is depicted below:</p>

<p><a href='http://diversions.nfshost.com/blog/wp-content/uploads/calgwt2.png' title='Webapp Architecture'><img src='http://diversions.nfshost.com/blog/wp-content/uploads/calgwt2.png' alt='Webapp Architecture' /></a></p>

<ul>
<li>The browser runs a Javascript thick client compiled from Java by GWT. Some of the classes have <a href="http://diversions.nfshost.com/blog/2008/03/15/gwt-as-a-cal-client/">CAL annotations</a>. These don&#8217;t affect the client, but allow the server side of the GWT RPC protocol to call CAL functions.</li>
<li>The CAL functions store persistent data using <a href="http://en.wikipedia.org/wiki/Software_transactional_memory">Software Transactional Memory</a>. This is a simple Java implementation based on the description in <a href="http://research.microsoft.com/~simonpj/papers/stm/stm.pdf">Composable memory transactions</a>. It is given a CAL interface similar to a subset of <a href="http://haskell.org/ghc/docs/latest/html/libraries/stm/Control-Concurrent-STM.html">Haskell&#8217;s Control.Concurrent.STM</a>.</li>
<li>Each STM TVar stores its value as a key-value pair in a <a href="http://www.oracle.com/database/berkeley-db/je/index.html">Berkeley DB Java Edition</a> database.</li>
</ul>

<p>Any data structure can be built on top of TVars &#8212; and each TVar is a mutable reference, these are <em>not</em> functional data structures.</p>

<p>In this application a simple hashmap is used. Skiplists and relaxed balance btrees are other data structures which might allow reasonable concurrency too, while also providing features like in-order traversal.</p>

<p>This illustrates the relationship between the CAL objects in the <a href="http://openquark.org/Documents/javadoc/org/openquark/cal/runtime/ExecutionContext.html">CAL ExecutionContext</a> and key-value pairs in the BDB:</p>

<p><a href='http://diversions.nfshost.com/blog/wp-content/uploads/cal-gwt-stm-persistence.png' title='cal-gwt-stm-persistence.png'><img src='http://diversions.nfshost.com/blog/wp-content/uploads/cal-gwt-stm-persistence.png' alt='cal-gwt-stm-persistence.png' width=500 /></a></p>

<p>The root of the persistent data structure is a TVar with a &#8216;well-known&#8217; id &#8212; 1 in the example, which is created by a <a href="http://www.haskell.org/haskellwiki/Constant_applicative_form">constant applicative form function</a>. This TVar will retrieve its value from the BDB when it is created, or if no value exists for its id, it will be initialised with a default value, which in the case of a hashmap is an array of TVars, each containing an empty list of key-value pairs. A value stored in a TVar is persisted to the BDB by serialising it using CAL&#8217;s default <code>output</code> function and <a href="http://xstream.codehaus.org/">Xstream</a>, which can serialize and deserialize instances which are not serializable and do not have accessible constructors.</p>

<p>TVars themselves have <code>transient</code> values, so only the id is persisted &#8212; the value is lazily loaded when required, using the id. So even though a TVar may persist a complicated tree of CAL algebraic values, this stops at the first TVar. (The root TVar is never persisted itself &#8212; only its value is stored).</p>

<p>You can get a <a href="http://diversions.nfshost.com/cgi-bin/gitweb.cgi?p=calex;a=snapshot;h=62165fb0519d5a4bcf692c615500bcdae9be669f;sf=tgz">snapshot here</a> &#8212; just unpack it and run <code>ant run</code>, then point your browser at <code>http://localhost:8080/caltest.html</code>. Or <a href="http://diversions.nfshost.com/cgi-bin/gitweb.cgi?p=calex;a=summary">browse the source</a>.</p>

<p>The <code>ant</code> build script includes a target <code>run-tests</code> which runs some <a href="http://selenium.openqa.org/">Selenium</a> tests. Stop the server before running that target.</p>

<p>Note that the source code includes various bits of half-baked rubbish, in addition to that described above!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kablambda.org/blog/2008/03/27/a-cal-webapp-with-persistent-data-using-gwt-stm-and-bdb/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>GWT as a CAL client</title>
		<link>http://www.kablambda.org/blog/2008/03/15/gwt-as-a-cal-client/</link>
		<comments>http://www.kablambda.org/blog/2008/03/15/gwt-as-a-cal-client/#comments</comments>
		<pubDate>Sat, 15 Mar 2008 09:12:04 +0000</pubDate>
		<dc:creator>Tom Davies</dc:creator>
				<category><![CDATA[CAL and Open Quark]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[GWT]]></category>

		<guid isPermaLink="false">http://diversions.nfshost.com/blog/2008/03/15/gwt-as-a-cal-client/</guid>
		<description><![CDATA[I&#8217;ve been interested in GWT as a way of building rich Internet applications since it appeared, and I&#8217;m very pleased to see it getting better and better.

So it&#8217;s natural that I&#8217;d want to try using it with CAL, a functional language quite similar to Haskell which runs on the JVM.

I used a similar approach to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been interested in <a href="http://code.google.com/webtoolkit/">GWT</a> as a way of building rich Internet applications since it appeared, and I&#8217;m very pleased to see it getting <a href="http://timepedia.blogspot.com/2008/03/gwtthe-road-to-15-part-1_07.html">better</a> and <a href="http://timepedia.blogspot.com/2008/03/gwt-road-to-15-linkers.html">better</a>.</p>

<p>So it&#8217;s natural that I&#8217;d want to try using it with <a href="http://openquark.org">CAL</a>, a functional language quite similar to <a href="http://haskell.org">Haskell</a> which runs on the JVM.</p>

<p>I used a similar approach to marshalling Javabeans to CAL algebraic types as I <a href="http://diversions.nfshost.com/blog/2007/10/03/cal-and-tapestry-5-part-2-algebraic-types-and-forms/">used before</a>, but this time I haven&#8217;t used any bytecode manipulation &#8212; as the Java classes are needed at compile time for the GWT client there isn&#8217;t any point in generating them at runtime (although generating them as a separate build step might be useful). I&#8217;ve also extended the previous work to include mapping a Java 5 enum to a CAL algebraic type which has constructors with zero parameters.</p>

<p>So in our GWT client we can write:</p>

<pre><code>CaltestServiceAsync service = GWT.create(CaltestService.class);
((ServiceDefTarget) service).setServiceEntryPoint(
    GWT.getModuleBaseURL() + "CaltestService");
service.processPerson(
    new Person(Salutation.MR, "Jim", "Earl", "Jones"), new MyAsyncCallback(...));
</code></pre>

<p>and call the CAL function:</p>

<pre><code>public processPerson p =
    let Person s f m l = p; 
    in Person s (toUpperCase f) (lift toUpperCase m) (toUpperCase l);
</code></pre>

<p>where the types are:</p>

<pre><code>data Salutation = MR | MRS deriving Inputable, Outputable;
data Person =
    Person salutation :: Salutation 
              firstName :: String 
              middleName :: (Maybe String) 
              lastName :: String 
    deriving Inputable, Outputable;
</code></pre>

<p>All this is done via three different annotations, and a special subclass of the GWT <code>RemoteServiceServlet</code>.</p>

<p>The first annotation, <code>@Cal</code> is applied to the GWT service interface, and indicates the CAL module to map the functions on the interface to:</p>

<pre><code>@Cal(workspace = "myworkspace.cws", module = "TDavies.GwtTest")
public interface CaltestService extends RemoteService {
    @Cal
    Person processPerson(Person p);
...
</code></pre>

<p>The CAL types <code>Person</code> and <code>Salutation</code> need to be mapped to Java classes:</p>

<p>Person is a simple Javabean with getters and setters for each attribute:</p>

<pre><code>@CalBean(workspace = "myworkspace.cws", module = "TDavies.GwtTest",
    constructorName = "Person")
public class Person implements IsSerializable {
    private Salutation salutation;
    private String firstName;
    private String lastName;
    private String middleName;
...
</code></pre>

<p>Note that <code>middleName</code> has the type <code>Maybe String</code> in the CAL type. A value of <code>null</code> maps to <code>Nothing</code> while a value of <code>"x"</code> maps to <code>Just "x"</code>.</p>

<p>Salutation is an <code>enum</code>:</p>

<pre><code>@CalEnum(workspace = "myworkspace.cws", module = "TDavies.GwtTest",
    type = "Salutation")
public enum Salutation {
    MR, MRS
}
</code></pre>

<p>The names of the enum&#8217;s values must be identical to the names of the CAL constructors.</p>

<p>A subclass of <code>RemoteServiceServlet</code> checks for the annotations and transforms the values in both directions.</p>

<p>The source code for this experiment is available via anonymous svn from <code>http://tgdavies.beanstalkapp.com/eddy/browse/trunk/cal</code>. Please note that this repository contains various other half-baked and half-finished experiments! Look at the <code>build.xml</code> file to see how to set up an environment &#8212; you&#8217;ll need to supply OpenQuark, GWT and <a href="http://www.mortbay.org/">Jetty</a>.</p>

<p>In my next post I&#8217;ll describe how to persist information on the server.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kablambda.org/blog/2008/03/15/gwt-as-a-cal-client/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CAL and Tapestry 5, Part 2: Algebraic Types and Forms</title>
		<link>http://www.kablambda.org/blog/2007/10/03/cal-and-tapestry-5-part-2-algebraic-types-and-forms/</link>
		<comments>http://www.kablambda.org/blog/2007/10/03/cal-and-tapestry-5-part-2-algebraic-types-and-forms/#comments</comments>
		<pubDate>Wed, 03 Oct 2007 11:29:17 +0000</pubDate>
		<dc:creator>Tom Davies</dc:creator>
				<category><![CDATA[CAL and Open Quark]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://diversions.nfshost.com/blog/2007/10/03/cal-and-tapestry-5-part-2-algebraic-types-and-forms/</guid>
		<description><![CDATA[In my previous post I described how to use a CAL function as part of the implementation of a Java class.

This post looks at interfacing CAL to Tapestry 5 using the &#8216;Java Bean&#8217; conventions of getter and setter methods for the fields in an object.

Tapestry 5 provides a BeanEditForm component which simplifies providing CRUD operations [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous post I described how to use a <a href="http://labs.businessobjects.com/cal/">CAL</a> function as part of the implementation of a Java class.</p>

<p>This post looks at interfacing CAL to <a href="http://tapestry.apache.org/tapestry5/">Tapestry 5</a> using the &#8216;Java Bean&#8217; conventions of getter and setter methods for the fields in an object.</p>

<p>Tapestry 5 provides a <a href="http://tapestry.formos.com/nightly/tapestry5/tapestry-core/guide/beaneditform.html">BeanEditForm</a> component which simplifies providing CRUD operations for Beans. This is described in the <a href="http://tapestry.apache.org/tapestry5/tutorial1/forms.html">second part of the Tapestry 5 tutorial</a>.</p>

<p>By creating a Java class which provides a Bean with fields equivalent to the constructor parameters of a  CAL algebraic data type we can use CAL to provide the data model for a web UI created with Tapestry.
<span id="more-19"></span>
A Tapestry application doesn&#8217;t need to have a compile-time dependency on the fields in a Bean which will be edited in a <code>BeanEditForm</code>. This means that we can simply declare an abstract class, associate it with a CAL data constructor and have immediate web-based CRUD for that type.</p>

<p>On the Java side, we make the following changes to the code described in <a href="http://tapestry.apache.org/tapestry5/tutorial1/forms.html">the tutorial</a>.</p>

<p>The <code>Address</code> class becomes:</p>

<pre><code>@CalBean(workspace="myworkspace.cws", module="TDavies.Address", constructorName = "Address")
public abstract class Address implements CalBeanBase {
}
</code></pre>

<p>The type referred to by the annotation looks like this:</p>

<pre><code>data Address = Address
    honorific :: String
    firstName :: String
    lastName :: String
    street1 :: String
    street2 :: (Maybe String)
    city :: String
    state :: String
    zip :: (Maybe Int)
    email :: String
    phone :: (Maybe String)
    fax :: (Maybe String)
deriving Inputable, Outputable, Show;
</code></pre>

<p>The type must be an instance of <code>Inputable</code> and <code>Outputable</code>.</p>

<p>The <code>CalBeanBase</code> interface provides the information about the Bean needed for copying between an instance of <code>Address</code> (or any other Bean constructed from a CAL type) and an <a href="http://resources.businessobjects.com/labs/cal/open_quark_javadoc/index.html">AlgebraicValue</a>:</p>

<pre><code>/**
 * This interface describes the structure of a Bean derived from a CAL type.
 * The information allows values to be transferred between bean instances and
 * CAL AlgebraicValue instances, using the BeanConverter class.
 */
public interface CalBeanBase {
    public static class FieldSpec {
        public String name;
        public BeanValueConverter converter;

        public FieldSpec(String name, BeanValueConverter converter) {
            this.name = name;
            this.converter = converter;
        }
    }
    public List&lt;FieldSpec&gt; getFieldSpecs();
    String getDataConstructorName();
    int getDataConstructorOrdinal();
}
</code></pre>

<p><code>BeanValueConverter</code> implementations copy between a CAL value and a field. At present the only non-trivial implementation is the <code>MAYBE</code> converter, which maps <code>Nothing</code> to <code>null</code>.</p>

<p>The <code>BeanConverter</code> class has these methods:</p>

<pre><code>/**
 * Copy values between CalBeanBase subclasses and CAL AlgebraicValue instances.
 */
public class BeanConverter {
    /**
     * Create a new AlgebraicValue which has been constructed using
     * the field values from bean.
     */
    public static AlgebraicValue toCal(CalBeanBase bean) {
        ...
    }

    /**
     * Set the field values in bean from the constructor parameters
     * in v.
     */
    public static void fromCal(CalBeanBase bean, AlgebraicValue v) {
        ...
    }
}
</code></pre>

<p>At runtime Javassist implements the CalBeanBase interface and adds the fields, getters and setters needed to make a bean. It does this by looking up the CAL type given in the annotation and introspecting it.</p>

<p>In addition, setters for fields which are not of type <code>Maybe a</code> are given a <code>@Validate("required")</code> annotation. <code>@Order</code> annotations are used to keep the fields in the same order as they appear in the CAL type. (The tutorial is out of date in this respect, and doesn&#8217;t mention the <code>@Order</code> annotation).</p>

<p>To exercise this technique we can make the <code>CreateAddress</code> class less trivial:</p>

<pre><code>       // make _address persistent, so we can see the results of processing it on submit
  @Persist
  private Address _address;
       ... getter and setter unchanged ...
       // CAL function -- the body will be replaced with a call to TDavies.Address.sendAddress
  @Cal
  public AlgebraicValue sendAddress(Object address) {return null;}

  public void onSubmit()
  {
      BeanConverter.fromCal(_address, sendAddress(BeanConverter.toCal(_address)));
  }
</code></pre>

<p>When we submit the form, the bean&#8217;s field values are converted to an AlgebraicValue and passed to the CAL function <code>sendAddress</code>. The value returned by the function is used to set the fields of the bean, which is then displayed.</p>

<p>The <code>sendAddress</code> function just converts some of the data to upper case:</p>

<pre><code>sendAddress :: Address -&gt; Address;
public sendAddress o =
    let
        address = o;
    in
        Address
            address.Address.honorific
            (toUpperCase address.Address.firstName)
            (toUpperCase address.Address.lastName)
            (toUpperCase address.Address.street1)
            (case address.Address.street2 of Nothing -&gt; Nothing; Just s -&gt; Just $ toUpperCase s;)
            (toUpperCase address.Address.city)
            (toUpperCase address.Address.state)
             address.Address.zip
             address.Address.email
             address.Address.phone
             address.Address.fax;
</code></pre>

<p>There are a number of enhancements which could be made to this scheme:</p>

<ul>
<li>Unlike the example, Java Enums are not supported as field values.</li>
<li>Only <code>required</code> validation can be specified, not <code>regex</code> or other types.</li>
<li>There is a problem allowing optional field values for non-string values &#8212; this may be a Tapestry limitation.</li>
<li>The <code>BeanConverter</code> methods should be on the <code>CalBeanBase</code> interface. Not only would the <code>onSubmit</code> implementation above be simpler, but the existing methods on the <code>CalBeanBase</code> interface could be removed, and implemented as private methods called by the toCal/fromCal implementations.</li>
</ul>

<p>To really tell whether these techniques are worthwhile, I need to write a non-trivial web app using them!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kablambda.org/blog/2007/10/03/cal-and-tapestry-5-part-2-algebraic-types-and-forms/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
