Monday, June 29, 2009

Sieve of Eratosthenes

This is my response to the Scala slide in the "JavaOne Talk: Performance Comparisons of Dynamic Languages on the Java Virtual Machine" presentation. In particular, the Scala example seemed quite verbose and "unscalalike", so I thought I would see what I could quickly knock up. It's the Sieve of Eratosthenes (sort of - it's recursive and it doesn't bother with Step 5 of the algorithm on the Wikipedia page, so it does more work than is needed).

It's quick and dirty and could stand to be improved - my main motivation was to show that it could be done quickly and in a lot fewer lines in Scala than was shown on the presentation slide so it's not the greatest example of code ever written. I've put it up here because blogger's commenting system nukes source code layout.


def primes(n: Int): List[Int] = {
def nomults(s: Int, xs: Seq[Int]): List[Int] = (for (x <- xs if x % s != 0) yield x).toList
def sieve(xs: List[Int]): List[Int] = {
if (xs.isEmpty) xs
else {
val p = xs.first
val nxs = nomults(p, xs drop 1)
p :: sieve(nxs)
}
}

val odds = nomults(2, 2 to n)
2 :: sieve(odds)
}

println( primes(100) )

Monday, April 20, 2009

Oracle To Buy Sun

Article at the NY Times

Sun's Press Release

My first impression is that this should be good for Java, less good for MySQL.

Wednesday, April 8, 2009

Scala on the Google AppEngine

Good News - It was fairly trivial to use Scala with the new Java support in AppEngine.


I used a text editor and ant instead of mucking about with Eclipse. It was pretty much a case of following the docs for Java, just using Scala instead of Java for writing the servlet. The main difference between using Java and Scala is that you need to merge some Scala specific items into the build.xml file. Here's my build.xml




<project>
<property name="scala.home" location="../scala-2.7.3.final" />
<property name="sdk.dir" location="../appengine-java-sdk-1.2.0" />
<property name="sources.dir" value="${base.dir}/src" />
<property name="build.dir" value="${base.dir}/build"/>

<import file="${sdk.dir}/config/user/ant-macros.xml" />

<path id="project.classpath">
<pathelement path="war/WEB-INF/classes" />
<fileset dir="war/WEB-INF/lib">
<include name="**/*.jar" />
</fileset>
<fileset dir="${sdk.dir}/lib">
<include name="shared/**/*.jar" />
</fileset>
</path>

<target name="init">
<property
name="scala-library.jar"
value="${scala.home}/lib/scala-library.jar"
/>
<path id="build.classpath">
<pathelement location="${scala-library.jar}" />

<pathelement location="${build.dir}" />
</path>
<taskdef resource="scala/tools/ant/antlib.xml">
<classpath>
<pathelement location="${scala.home}/lib/scala-compiler.jar" />
<pathelement location="${scala-library.jar}" />
</classpath>
</taskdef>
</target>


<target name="copyscala"
description="Copies the App Engine JARs to the WAR.">
<copy
todir="war/WEB-INF/lib"
flatten="true">
<fileset dir="${scala.home}/lib">
<include name="**/scala-library.jar" />
</fileset>
</copy>
</target>

<target name="copyjars"
description="Copies the Scala JARs to the WAR.">
<copy
todir="war/WEB-INF/lib"
flatten="true">
<fileset dir="${sdk.dir}/lib/user">
<include name="**/*.jar" />
</fileset>
</copy>
</target>

<target name="compile" depends="copyscala, copyjars, init"
description="Compiles Scala source and copies other source files to the WAR.">
<mkdir dir="war/WEB-INF/classes" />
<copy todir="war/WEB-INF/classes">
<fileset dir="src">
<exclude name="**/*.scala" />
</fileset>
</copy>
<scalac
srcdir="src"
destdir="war/WEB-INF/classes"
classpathref="project.classpath"
/>
</target>


<target name="runserver" depends="compile"
description="Starts the development server.">
<dev_appserver war="war" />
</target>

</project>

Java Coming To Google AppEngine

The docs are up on Google's AppEngine site!

I've been playing with the python version (though I haven't released anything) - now it's time to look at using Java (and hopefully Scala and Groovy).

Tuesday, March 3, 2009

Starbucks (UK) Vs Linux

I can't believe how braindead Starbucks' UK website is. If you're running Linux and trying to register your Starbucks card you'll get this message:



Browser error

We're sorry, your browser doesn't support the Starbucks Card registration pages of this website.

Please update your browser to Internet Explorer version 5.0 or above, or Netscape Navigator version 6.0 or above.

Thank you.


Here I was thinking Firefox 3 was above Netscape 6.


Of course, if you switch the User Agent to say that you're running Windows, all works well. 1999 called - they want thier browser detection back.


Maybe it has something to do with having headquaters in Seattle.

Thursday, July 31, 2008

Stupid Scala Trick: Injecting Methods With Spring

I'm not sure why I came up with this idea, but it occurred to me that since functions are first class objects in Scala then I should be able to inject them as dependencies using the Spring framework. So I decided to give it a try (using constructor injection to make life simple).

First, I need a class that will have a method injected -


class User(val f: String => String) {

def b() = {f("hello")}

}

So, this class will have a method named f (which takes a String and returns a String) injected into it. It also has a method called b, which will use f.

Next up, a function that will be injected.

object func1 extends Function1[String, String] {
def apply(s: String): String = {s.toUpperCase()}
}

This is essentially the same as

def func1(s: String): String = {s.toUpperCase()}

Now, the Spring bean definition xml (which I'll save in a file called app.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">


<bean id="user" class="User">
<constructor-arg>
<bean class="func1$"/>
</constructor-arg>
</bean>
</beans>


Finally, a small application to fire up spring and test that injection worked


import org.springframework.context.support._

object SpringTest {

def main(args: Array[String]) = {

val context = new ClassPathXmlApplicationContext(Array[String]("app.xml"));
val user = context.getBean("user").asInstanceOf[User]
println(user.b())
println(user.f("world"))
}
}



And here's the output (minus some log4j warnings)


HELLO
WORLD

Friday, July 18, 2008

maven & build-helper

I ran into a little issue with maven and the build-helper plugin today.

The background is as follows - I was part-mavenizing a project (long, boring work related story) and I needed to generate some source code using JAXB (which was a trial in and of itself - we're compiling on Java 1.4 and JAXB hates Java 1.4 - in the end I needed to use antrun to run the 1.0.0 version of xjc) and then have it compile as part of the main compile process. So build-helper to the rescue. The documentation states that you just add the plugin to the build-


...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>some directory</source>
...
</sources>
</configuration>
</execution>
</executions>
</plugin>
...



Note the "some directory" for the source. I was trying to place the generated code into /target/generated-code/java, seeing as the generated code was output and output ends up in /target. It wouldn't work. I tried several variations on a theme, but as long as I kept trying to compile source that lived in target, maven would not see it. In the end, I placed the code in {$basedir}/src/generated/java (ie, in src, not target), pointed build-helper to it and it started to work.

While it works, it does mean I have more work ahead in order to get clean to work as expected.