Thursday, December 31, 2009

The importance of API design

Reflecting on the exercise leading up to yesterday's post, one of the things that struck me in the comparison of the .net Framework used from F# and the Java APIs available to Scala/JVM was how much the former got little details right to facilitate working in the web-page embedded context. Take the simple task of getting at the URL query parameters for the page in which the applet is embedded

In Silverlight, in the main UserControl class:

let (success, stringValueLat) = System.Windows.Browser.HtmlPage.Document.QueryString.TryGetValue("lat")

In an applet, where peer is the Applet instance:

      // navigate methods returning type Object to get to the raw string URL
      val win = JSObject.getWindow(peer)
      val doc = win.asInstanceOf[JSObject].getMember("document")
      val loc = doc.asInstanceOf[JSObject].getMember("location")
      val url = loc.asInstanceOf[JSObject].getMember("href").asInstanceOf[String];

      // get minimal parsing assistance from the APIs, where java.net.URI is
      // woefully underfunctional compared with System.Windows.Browser.HtmlDocument
      val params = (new URI(url)).getQuery()

      // Now split up the query string manually
      // or could use parser APIs
      var tmap = new Map[String, String]()
      if (params ne null)
      {
        val parts = params.split("&")
        tmap = (tmap /: parts) ( (m:Map[String,String], pair:String) =>
          {
            val bits = pair.split("=")
            val tuple : (String, String) = (bits(0), bits(1))
            m + tuple
          })
      }
      val stringValueLat = tmap.getOrElse("lat", "")

Perhaps this just shows how the old-style Java applet has withered on the vine, while Silverlight as a competitor to Flash has taken on a more aggressive stance for developer acceptance -- but with the decade-plus that Java has under its belt compared with Silverlight's barely more than a year (1.0 not really counting), the comparison is rather disappointing.

I shall have to investigate whether the continued work on scala-msil has led to any material improvements in its robustness since I looked at it last, six months ago.

A few minutes later

Well, my six month old port of the Scala actors package to pure Scala calling the .Net APIs still blows the compiler up in a Scala 2.8 nightly that's just a few days old. The explosion is in pure Scala code taken directly from the 2.7.5 actors package, and not the Scala-calling-.net replacements I coded of the Java parts of that package:

object Eval$2
  symbol = final case  object Eval$2
  owner  = final  object Futures
with methods = List(scala.actors.Futures.Eval$2., scala.actors.Futures.Eva
l$2.readResolve, scala.actors.Futures.Eval$2.canEqual, scala.actors.Futures.Eval
$2.productElement, scala.actors.Futures.Eval$2.productArity, scala.actors.Future
s.Eval$2.productPrefix, scala.actors.Futures.Eval$2.toString, scala.actors.Futur
es.Eval$2.productElements, scala.actors.Futures.Eval$2.productIterator)
Exception in thread "main" java.lang.RuntimeException: ILGenerator.emit(): Stack
 underflow in method: public static System.Void scala.actors.Futures$+scala.acto
rs.Futures.Eval$2$::.cctor()
        at ch.epfl.lamp.compiler.msil.emit.ILGenerator.emit(ILGenerator.scala:48
7)

So, still not ready for prime-time.

Wednesday, December 30, 2009

Anime — Aoi Hana (Sweet Blue Flowers)

A quiet little story of school-girl romance, very sweetly done; and with a delicate and restrained art style, presumably heavily post-processed photographs in the main. The story follows childhood friends Fumi and Akira though Fumi's first romance with an older and generally very popular pupil from her school, and the messy break-up that follows. But even through that, all the characters involved are just all-around nice -- no real catty or bitchy episodes (unlike the superficially similar schoolgirl story in Marimite, with the insufferable Touko-chan).

Based on an on-going manga, it ends like a chapter ending rather than the tale being all told, but for all that it comes to a satisfying conclusion. Alas, poor DVD sales means a second series is unlikely -- which is disappointing as it's one of the better shows in what has been a dreadfully thin year for new anime.

Presumably there aren't enough trainspotters to buy it on the strength of the many railway scenes during Fumi and A-chan's commute to their adjoining schools (if Aria can be considered scenery porn, this verges of the train porn at times).


Sample frames and a YouTube link removed following DMCA complaint. If the buggers can't understand fair use quotation for purposes of review, then my recommendation would be to not reward them with any of your hard earned.

A little toy in Scala

Proving that with a little help from tools like JarJar and Pack200, an applet written in Scala will come in somewhere between and IronPython and an F# Silverlight equivalent, considering the weight of infrastructure code that gets dragged along to support the language, though my using Scala 2.8 makes the applet a bit bulkier than using a 2.7.x basis would.

The applet GUI isn't quite as slick as Silverlight gives you for free, and the UI code could be tidied a fair bit.

Monday, December 28, 2009

A quick Scala gotcha

Wouldn't it be nice, I thought, to be able to put UI decoration as a mixin to any sort of component, like

trait HasImage {
  def image : java.awt.Image
}

trait Tiled {
  self : scala.swing.Component with HasImage =>
  peer.setOpaque(false)

  override def paintComponent(g :Graphics2D) {
    for(x <- 0.until(peer.getWidth(), image.getWidth(peer));
        y <- 0.until(peer.getHeight(), image.getHeight(peer)))
    {
      g.drawImage(image, x, y, peer);
    }
    self.paintComponent(g)
  }
}

class TiledContainer(tiledBackgroundImage : Image, constraints :Seq[String]) extends Form(constraints) with Tiled with HasImage {
  val image = tiledBackgroundImage
}

In Scala 2.8 recent nightlies, this compiles happily -- but when you run it, the self.paintComponent(g) call just stack overflows, flipping between TiledContainer.paintComponent and Tiled.paintComponent as it goes.

At 2.7.x, it doesn't compile -- which at least prevents you getting the run-time error

error: overriding method paintComponent in class Component of type
(g: scala.swing.package.Graphics2D)Unit; method paintComponent in trait Tiled of type
(g: java.awt.Graphics2D)Unit cannot override a concrete member without a third member 
that's overridden by both (this rule is designed to prevent ``accidental overrides'')
class TiledContainer(tiledBackgroundImage : Image, constraints :Seq[String]) extends 
Form(constraints) with Tiled with HasImage {

Friday, December 25, 2009

Winter Wonderland

Thursday evening last, it started to snow -- blizzarding enough that Karen's evening call carers got lost on the way back, took the wrong turn and ended up stuck in the snow on a farm road, and had to be towed out by tractor.

Friday, the snow was drifted deep against the front door, and going out to the village shop, it was calf-deep in places where it had drifted. A definite work from home day.

Saturday, pulled my boots on, and yomped the footpaths across the fields into town to do some shopping, on an exhilarating crisp winter's morning, where the long grass was sticking through the snow like through blown sand on a beach. Traffic was horrid in town, and for the return journey, when I went part of the way along the main road, the snow had clearly turned to slush and been refrozen, horrible going. So on the last, off-road, leg, when I was getting tired and footsore, when confronted by a pitbull thing, I just kept on going. This unsetled it, and when I got within about six feet, in pronked off and started circling, despite being yelled at by its human. I eventually had just to grab the thing by the harness and wait for the lead to be clipped back on.

Deep and crisp and even

Deep and crisp and even

Sunday, I thought it would be a good idea to clear the drive -- but under what looked like nigh virgin snow there was a thick layer of ice. Monday, worked from home again, did some clearing -- though the main bus-route through the village was still thick with ice (no gritting done whatsoever). Tuesday, discover that the other road through the village was clear, so very gingerly make the short drive onto the clear road and the long main-road detour to work. Head home after lunch, expecting the other end of the village to be as clear as the way I went in the morning -- to find a horrible scary drive.

Worked from home the rest of the week, probably getting more done than had I gone in. Yesterday afternoon wheeled the bike out to the main road, then cycled to the nearest supermarket for some last minute food shopping. The main roads were clear, but some of the side roads near the supermarket were sheet ice (one gentle slide to my knees while wheeling over that on the way back).

Today, the thaw was setting in, but there was still snow lying morning and evening -- the first white Christmas I can remember, certainly in the 20+ years living here. the main road was clear, and in the close, the ice was soft and breaking into slush where cars were driving -- but some of the pavements (especially uncleared driveways) were solid slippery sheet ice. One old gent visiting the family for the day managed to get stuck for lack of traction, until I helped him.

Monday, December 14, 2009

Using a different mscorlib for F# in Visual Studio (Silverlight and probably XNA too)

It turns out that I was lucky last year when building an F# Silverlight 2 application by hand in Visual Studio -- I didn't make an explicit reference to mscorlib.

If you explicitly browse to the Silverlight mscorlib assembly to make an explicit reference, the .fsproj file still only gets the basic

    <Reference Include="mscorlib"/>

which falls back to the full framework version of the assembly when you compile. This behaviour has caused some people to abandon the exercise of getting F# to build against something non-default in Visual Studio.

However, the way forward is very simple indeed -- simply edit the .fsproj to give an explicit hint path pointing at the mscorlib you really mean:

    <Reference Include="mscorlib">
      <HintPath>C:\Program Files\Reference Assemblies\Microsoft\Framework\Silverlight\v3.0\mscorlib.dll</HintPath>
    </Reference>

and get the confirmation that this sticks in the command line that echoes to the Output window

C:\Program Files\FSharp-1.9.7.8\\bin\fsc.exe -o:obj\Debug\Library3.dll -g --debug:full --noframework --define:DEBUG --define:TRACE --optimize- --tailcalls- -r:"C:\Program Files\FSharp-1.9.7.8\Silverlight\2.0\bin\FSharp.Core.dll" -r:"C:\Program Files\Reference Assemblies\Microsoft\Framework\Silverlight\v3.0\mscorlib.dll" --target:library --warn:3 --warnaserror:76 --vserrors --utf8output --fullpaths --flaterrors Module1.fs

Problem sorted.

(Generalise as required to any other assemblies which refuse to stay pointed at the platform you want.)

Save the version number in the output, this advice is unchanged by the February 2010 CTP.

Sunday, December 13, 2009

Packaging Scala applets into one jar in NetBeans with JarJar [Updated]

Pretty much a note to self; using NetBeans that started off as 6.7.1, but has the bleeding-edge depot, and using a Scala 2.8 nightly, FWIW.

Get the jarjar tool; put it and a copy of scala-library.jar and scala-swing.jar in a lib directory under the project. Create a build.xml post-jar target to read

    <target name="-post-jar">
      <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask"
               classpath="lib/jarjar-1.0.jar"/>
      <jarjar jarfile="${dist.jar}">
        <fileset dir="${build.classes.dir}"/>
        <zipgroupfileset dir="lib" includes="scala-*.jar" />
        <keep pattern="[your.root.package].*"/>
      </jarjar>
    </target>

Clean and build, get a lot of Scala classes in your output jar file. For which there is then pack200 support to crunch further.

There is an Ant task for that, which we can add to the post-jar target in build.xml thus

    <target name="-post-jar">
      <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask"
               classpath="lib/jarjar-1.0.jar"/>
      <taskdef name="pack200"
               classname="com.sun.tools.apache.ant.pack200.Pack200Task"
               classpath="lib/Pack200Task.jar"/>
      <jarjar jarfile="${dist.jar}">
        <fileset dir="${build.classes.dir}"/>
        <zipgroupfileset dir="lib" includes="scala-*.jar" />
        <keep pattern="[your.root.package].*"/>
      </jarjar>
      <pack200 src="${dist.jar}"
               destfile="${dist.jar}.pack.gz"
               GZIPOutput="yes"
               verbose="0"
               />
    </target>

which brings in my first test case, a 2.5Mb jar down to just under 900kb.

Saturday, December 05, 2009

F# and Silverlight 3 addendum

You can make a permanent fix for the hint path needed to find FSharp.Core.dll by editing the template in C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ProjectTemplatesCache\FSharp\Silverlight\SilverlightLibrary3.zip\SilverlightLibrary.fsproj (and probably the version of the file in C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ProjectTemplates\FSharp\Silverlight\SilverlightLibrary3.zip just to be certain).

Proof of concept -- my orrery-clock upgraded to Silverlight 3.0 (with all the source bundled into the .xap file) here.

F# October CTP and Silverlight 3.0

With the February 2010 CTP, obviously change the version number to 1.9.9.9 instead!

Following on from last year's compendium for Silverlight 2 --

There's an official Silverlight 3.0 project template for Visual Studio 2008; while targetted at the May CTP, these can be used with the October CTP by opening up the .fsproj file and amending the file path for the FSharp.Core assembly -- unload project, edit, and change the version in the hint path for the reference to be 1.9.7.8 like

    <Reference Include="FSharp.Core.dll">
      <HintPath>$(ProgramFiles)\fsharp-1.9.7.8\Silverlight\2.0\bin\FSharp.Core.dll</HintPath>
    </Reference>

and then reload.

The template is still useful as it automatically picks up all the other Silverlight platform assemblies from their location in the Silverlight reference assemblies folder, saving you having to do that manually from C:\Program Files\Microsoft SDKs\Silverlight\v3.0\Reference Assemblies and seems to provide some other integration in conjunction with the Silverlight tools.

Unfortunately, none of the samples provided are pure F# -- they all use a C# bootstrap for XAML and the AppManifest packaging. However we can still use last year's recipe with only minimal changes -- just update the RuntimeVersion in AppManifest.xaml to "3.0.40818.0", and the FSharp.Core.dll which you wrap in the .xap file is, of course, the one from the October CTP at C:\Program Files\FSharp-1.9.7.8\Silverlight\2.0\bin\FSharp.Core.dll (not the one from last year!)

Friday, December 04, 2009

The Moon in Winter

This morning at 07:13, about 35 minutes before sunrise, the sky was pale in the east with the approaching dawn -- and when I went downstairs, the just-past-full moon was casting shadows in the dining room.

The cats all agreed that this was good for their crepuscular activites.