Archive for the 'Programming' Category

Project Euler Problem 2 Functional Java

Friday, October 3rd, 2008

Project Euler Problem 2 using Functional Java:

import fj.data.Stream;
import fj.P1;
import fj.F2;
import static fj.function.Integers.even;
import static fj.pre.Ord.intOrd;
import static fj.pre.Monoid.intAdditionMonoid;
import static fj.data.Stream.cons;
import static fj.Function.curry;
 
...
 
Stream<Integer> fibs = new F2<Integer, Integer, Stream<Integer>>() {
  public Stream<Integer> f(final Integer a, final Integer b) {
    return cons(a, P1.curry(curry(this).f(b)).f(a + b));
  }
}.f(1, 2);
 
final int problem2 = intAdditionMonoid.sumLeft(fibs.takeWhile(intOrd.isLessThan(1000001)).filter(even).toList());

Project Euler Problem 1 Functional Java

Friday, October 3rd, 2008

Project Euler Problem 1 using Functional Java:

import static fj.pre.Monoid.intAdditionMonoid;
import static fj.data.List.range;
import fj.F;
 
...
 
final int problem1 = intAdditionMonoid.sumLeft(range(0, 1000).filter(new F<Integer, Boolean>() {
  public Boolean f(final Integer a) {
    return a % 3 == 0 || a % 5 == 0;
  }
}));

Scala: Gotchya!

Wednesday, October 1st, 2008

I have been caught out by type-checking code that fails at runtime. It should have failed at compile-time due to a language limitation in structural types — not a logical absurdity in the code itself. Thankfully I have a workaround, but it does provoke persistent hesitance — giving that disgusting feeling as if I were using something as degenerate as, for example, Ruby or even worse (can it get worse?), Groovy. I’ll have to counsel myself on that one.

Nevertheless, I give warning. Here is the bug report. Here is the fun. Observe:

scala> def left[B] = new { def apply[A](a: A): Either[A, B] = Left(a) }
left: [B]java.lang.Object{def apply[A](A): Either[A,B]}
 
scala> left[String](7)
res6: Either[Int,String] = Left(7)
 
scala> def left[B] = new { def apply[A](a: A, b: B): Either[A, B] = Left(a) }
left: [B]java.lang.Object{def apply[A](A,B): Either[A,B]}
 
scala> left(7, "")
res8: Either[Int,java.lang.String] = Left(7)
 
scala> left[String](7, "")
java.lang.NoSuchMethodException: $anon$1.apply(java.lang.Object, java.lang.String)
        at java.lang.Class.getMethod(Class.java:1605)
        at .reflMethod$Method1(<console>:6)
        at .<init>(<console>:6)
        at .<clinit>(<console>)
        at RequestResult$.<init>(<console>:3)
        at RequestResult$.<clinit>(<console>)
        at RequestResult$result(<console>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native ...

IntelliJ IDEA whinge

Friday, September 26th, 2008

An update on IntelliJ IDEA + Scala utterly unusable

  1. Delete ~/.IntelliJIdea80 (oh well, I’m so used to specifying my settings over and over anyway).
  2. Start IntelliJ IDEA. Do not open a project
  3. Install the Scala plugin
  4. Open your project
  5. Observe not-useless usability
    1. There are still issues of not being able to open certain source folders (try it and see for yourself scalaz.control in Scalaz trunk)
    2. Other minor annoyances that needn’t be mentioned

I have repeated this twice on different machines (8823). Swapping steps 3 and 4 result in a rapid degeneration of usefulness to the point of absolute uselessness.

Thanks again for listening. I hope the usability trend reverses.

IntelliJ IDEA + Scala utterly unusable

Wednesday, September 24th, 2008

It seems that IntelliJ IDEA 8.0 EAP and its Scala plugin have reached the point of being completely unusable. This is such a shame given that there are no existing viable alternatives (don’t say Eclipse and expect me to keep a straight face). I guess it will be emacs or Kate in the future.

The last few EAP releases crash the IDE when you expand some source trees resulting in a perpetual wait icon. I receive a dialog about submitting the bug and I have done, three times. The last two EAP releases (8823 and 8810) don’t allow me to install the Scala plugin at all. Upon restart, the IDE is unaware that the Scala plugin has even been installed. As a result, I have to use 8664, which my trial is due to expire any time soon.

The IDE constantly gives me false errors (surely it is not difficult to download the Scalaz source and observe the IDE complaining about errors that do not exist?). The IDE causes a segmentation fault if I use the Sun JDK 1.6.0_07 and I receive an UnspportedClassVersionError if I use version 1.5, so I am forced to use 1.6.0_10. The IDE is barely responsive on a 3.2GHz machine with 1.5GB memory and it doesn’t even align scaladoc comments properly as you write them. I am constantly manually fixing up indentation in the source code.

With so many elementary failures, I think any reasonable person would concede that IntelliJ IDEA is as unusable as Eclipse. That ends my whinge; thanks for listening.

Did you to have be so blunt?

Tuesday, September 23rd, 2008

http://realtimecollisiondetection.net/blog/?p=81

My favourites:

In contrast, design patterns are purported “master programmer advice” strongly suggesting to young or otherwise impressionable programmers that the design patterns convey important concepts, practices, or principles that have been “prethought.” However, design patterns are not “master programmer advice!”

Far from “master programmers,” design patterns are the work of people who do conferences, talks, and books for a living, to further their own cause

And the clincher:

Design patterns are spoonfeed material for brainless programmers incapable of independent thought, who will be resolved to producing code as mediocre as the design patterns they use to create it.

I’m sure you knew you’d be standing on toes, despite the the overwhelmingly defensible truth value of your statements. Don’t adjust your sight Christer, it’s dead on target ;)

Partially Applying Scala type variables

Monday, September 22nd, 2008

Below is a neat trick that others may find useful when designing APIs using the Scala programming language.

Scala’s type inferencer is not as clever as some. As a result, we often find ourselves explicitly annotating type variables in certain contexts. This can become a little annoying, but what is worse, is if you have a type variable list and only one of those requires explicit specification, the others must also be explicitly specified even though they would have otherwise been inferred.

Let me demonstrate. I will use Scala’s higher-kinds, which are never inferred (this is quite acceptable given the problems associated with inferring higher-kinds — consider Java and C# where they do not even exist, thus leading to an enormous repetitive chore) though other examples may be applicable. However, it can be annoying if you were to write say, the Monad join function:

def join[M[_], A](m: M[M[A]]): M[A] = error("todo")

A caller invocation might look like:

val x = join[List, Int](List(List(1, 2, 3), List(4, 5, 6)))

Notice the explicit annotation with the List type constructor, however, the second type variable (Int) must also be explicitly specified, even though it could have otherwise been inferred. This is a bit annoying.

We can do away with it like so:

def join[M[_]] = new {
  def apply[A](m: M[M[A]]): M[A] = error("todo")
}

And now the caller code no longer has that clumsy type annotation:

val x = join[List](List(List(1, 2, 3), List(4, 5, 6)))

Yay! Have a nice day :)

20 Intermediate Haskell Exercises

Thursday, September 18th, 2008
class Fluffy f where
  furry :: (a -> b) -> f a -> f b
 
-- Exercise 1
-- Relative Difficulty: 1
instance Fluffy [] where
  furry = error "todo"
 
-- Exercise 2
-- Relative Difficulty: 1
instance Fluffy Maybe where
  furry = error "todo"
 
-- Exercise 3
-- Relative Difficulty: 5
instance Fluffy ((->) t) where
  furry = error "todo"
 
newtype EitherLeft b a = EitherLeft (Either a b)
newtype EitherRight a b = EitherRight (Either a b)
 
-- Exercise 4
-- Relative Difficulty: 5
instance Fluffy (EitherLeft t) where
  furry = error "todo"
 
-- Exercise 5
-- Relative Difficulty: 5
instance Fluffy (EitherRight t) where
  furry = error "todo"
 
class Misty m where
  banana :: (a -> m b) -> m a -> m b
  unicorn :: a -> m a
  -- Exercise 6
  -- Relative Difficulty: 3
  -- (use banana and/or unicorn)
  furry' :: (a -> b) -> m a -> m b
  furry' = error "todo"
 
-- Exercise 7
-- Relative Difficulty: 2
instance Misty [] where
  banana = error "todo"
  unicorn = error "todo"
 
-- Exercise 8
-- Relative Difficulty: 2
instance Misty Maybe where
  banana = error "todo"
  unicorn = error "todo"
 
-- Exercise 9
-- Relative Difficulty: 6
instance Misty ((->) t) where
  banana = error "todo"
  unicorn = error "todo"
 
-- Exercise 10
-- Relative Difficulty: 6
instance Misty (EitherLeft t) where
  banana = error "todo"
  unicorn = error "todo"
 
-- Exercise 11
-- Relative Difficulty: 6
instance Misty (EitherRight t) where
  banana = error "todo"
  unicorn = error "todo"
 
-- Exercise 12
-- Relative Difficulty: 3
jellybean :: (Misty m) => m (m a) -> m a
jellybean = error "todo"
 
-- Exercise 13
-- Relative Difficulty: 6
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple = error "todo"
 
-- Exercise 14
-- Relative Difficulty: 6
moppy :: (Misty m) => [a] -> (a -> m b) -> m [b]
moppy = error "todo"
 
-- Exercise 15
-- Relative Difficulty: 6
-- (bonus: use moppy)
sausage :: (Misty m) => [m a] -> m [a]
sausage = error "todo"
 
-- Exercise 16
-- Relative Difficulty: 6
-- (bonus: use apple + furry')
banana2 :: (Misty m) => (a -> b -> c) -> m a -> m b -> m c
banana2 = error "todo"
 
-- Exercise 17
-- Relative Difficulty: 6
-- (bonus: use apple + banana2)
banana3 :: (Misty m) => (a -> b -> c -> d) -> m a -> m b -> m c -> m d
banana3 = error "todo"
 
-- Exercise 18
-- Relative Difficulty: 6
-- (bonus: use apple + banana3)
banana4 :: (Misty m) => (a -> b -> c -> d -> e) -> m a -> m b -> m c -> m d -> m e
banana4 = error "todo"
 
newtype State s a = State {
  state :: (s -> (s, a))
}
 
-- Exercise 19
-- Relative Difficulty: 9
instance Fluffy (State s) where
  furry = error "todo"
 
-- Exercise 20
-- Relative Difficulty: 10
instance Misty (State s) where
  banana = error "todo"
  unicorn = error "todo"

20 Intermediate Scala Exercises

Wednesday, September 10th, 2008

I will be publishing answers to these exercises as well as the Revised Scala Exercises in the near future. In the meantime, see if you can tackle the exercises below. In almost all cases, the type signature is enough to derive what the implementation should be. In all other cases, the solution is as difficult to derive anyway, so consider it an equivalent achievement.

The source file below compiles, but is missing certain function implementations (where you see error("todo")). Enjoy and if you have questions, please feel free to post them :)

trait PartialType[T[_, _], A] {
  type Apply[B] = T[A, B]
  type Flip[B] = T[B, A]
}
 
trait Fluffy[F[_]] {
  def furry[A, B](f: A => B, fa: F[A]): F[B]
}
 
object Fluffy {
  // Exercise 1
  // Relative Difficulty: 1
  def ListFluffy: Fluffy[List] = error("todo")
 
  // Exercise 2
  // Relative Difficulty: 1
  def OptionFluffy: Fluffy[Option] = error("todo")
 
  // Exercise 3
  // Relative Difficulty: 1
  def StreamFluffy: Fluffy[Stream] = error("todo")
 
  // Exercise 4
  // Relative Difficulty: 1
  def ArrayFluffy: Fluffy[Array] = error("todo")
 
  // Exercise 5
  // Relative Difficulty: 5
  def Function1Fluffy[X]: Fluffy[PartialType[Function1, X]#Apply] =
    error("todo")
 
  // Exercise 6
  // Relative Difficulty: 6
  def EitherLeftFluffy[X]: Fluffy[PartialType[Either.LeftProjection, X]#Flip] =
    error("todo")
 
  // Exercise 7
  // Relative Difficulty: 4
  def EitherRightFluffy[X]: Fluffy[PartialType[Either.RightProjection, X]#Apply] =
    error("todo")
}
 
trait Misty[M[_]] extends Fluffy[M] {
  def banana[A, B](f: A => M[B], ma: M[A]): M[B]
 
  def unicorn[A](a: A): M[A]
 
  // Exercise 8
  // Relative Difficulty: 3
  // (use banana and/or unicorn)
  def furry[A, B](f: A => B, ma: M[A]) = error("todo")
}
 
object Misty {
  // Exercise 9
  // Relative Difficulty: 2
  def ListMisty: Misty[List] = error("todo")
 
  // Exercise 10
  // Relative Difficulty: 2
  def OptionMisty: Misty[Option] = error("todo")
 
  // Exercise 11
  // Relative Difficulty: 2
  def StreamMisty: Misty[Stream] = error("todo")
 
  // Exercise 12
  // Relative Difficulty: 2
  def ArrayMisty: Misty[Array] = error("todo")
 
  // Exercise 13
  // Relative Difficulty: 6
  def Function1Misty[X]: Misty[PartialType[Function1, X]#Apply] =
    error("todo")
 
  // Exercise 14
  // Relative Difficulty: 7
  def EitherLeftMisty[X]: Misty[PartialType[Either.LeftProjection, X]#Flip] =
    error("todo")
 
  // Exercise 15
  // Relative Difficulty: 5
  def EitherRightMisty[X]: Misty[PartialType[Either.RightProjection, X]#Apply] =
    error("todo")
 
  // Exercise 16
  // Relative Difficulty: 3
  def jellybean[M[_], A](ma: M[M[A]], m: Misty[M]): M[A] = error("todo")
 
  // Exercise 17
  // Relative Difficulty: 6
  def apple[M[_], A, B](ma: M[A], mf: M[A => B], m: Misty[M]): M[B] =
    error("todo")
 
  // Exercise 18
  // Relative Difficulty: 6
  def moppy[M[_], A, B](as: List[A], f: A => M[B], m: Misty[M]): M[List[B]] =
    error("todo")
}
 
object AdvancedFun {
  case class State[S, A](f: S => (S, A))
 
  // Exercise 19
  // Relative Difficulty: 9
  def StateFluffy[S]: Fluffy[PartialType[State, S]#Apply] = error("todo")
 
  // Exercise 20
  // Relative Difficulty: 10
  def StateMisty[S]: Misty[PartialType[State, S]#Apply] = error("todo")
}

Haskell > Scala > (Java 7 <=> Functional Java) > Java

Friday, September 5th, 2008

Write a parser that accepts command line arguments.
For each command line argument, print out true or false,
depending on whether or not that value parses.

For a value to parse, it must consist entirely of these
characters: '(', ')', '[', ']‘. Any other character renders
the parse invalid and so prints “false”.

The value must also be “balanced”. That is, for each opening
parenthesis or bracket, it is matched by a closing parenthesis
or bracket accordingly. The different bracket types must not
intersperse.

Here are some examples of successfully parsing values that
result in printing “true”:

""
"()"
"[]"
"([])"
"[()]"
"[]()"
"[][[([])]]"

Here are some examples of values that fail the parsing and
result in printing “false”:

"("
")"
"["
"]"
"]["
")("
"( )"
"([)"
"[)]"
"([)]"
"({})"
"[())]"

Using Haskell (without Parsec):

import Prelude hiding (foldr, any)
import Control.Monad
import Data.Foldable
import System
 
tokens = [('(', ')'), ('[', ']')]
 
parse x = any null (foldr (\c f -> (\s -> (const (c:s)) `fmap`
            flip lookup ((uncurry (flip (,))) `fmap` tokens)  c `mplus`
              (flip lookup tokens c >>= (\v ->
                do h:t <- return s
                   guard (v == h)
                   return t))) =<< f) (return []) x)
 
main = getArgs >>= print . (parse `fmap`)

Using Scala (without scala.util.parsing):

object Parser {
  val tokens = List(('(', ')'), ('[', ']'))
 
  def parse(s: String) =
    s.foldRight[Option[String]](Some(""))((a, b) => b flatMap
      (ss => {
        val s = ss.toList
        (lookup(tokens map { case (x, y) => (y, x) }, a)
          map (t => (a::s)) orElse
        (lookup(tokens, a) flatMap (v => s match {
          case Nil => None
          case h :: t => if(v == h) Some(t) else None
        }))) map (_.mkString)
      })) exists (_.isEmpty)
 
  def main(args: Array[String]) {
    args foreach (parse _ andThen println)
  }
 
  // The Scala API needs hand-holding
  def lookup[A, B](x: List[(A, B)], a: A) =
    x.find { case (aa, _) => a == aa } map (_._2)
}

Using Java 1.5 and Functional Java:

import fj.F;
import fj.F2;
import fj.Function;
import static fj.P.p;
import fj.P1;
import fj.P2;
import fj.data.List;
import static fj.data.List.asString;
import static fj.data.List.fromString;
import static fj.data.List.list;
import static fj.data.List.lookup;
import fj.data.Option;
import static fj.data.Option.some;
import static fj.function.Strings.isEmpty;
import static fj.pre.Equal.charEqual;
import static fj.pre.Show.booleanShow;
 
final class Parser {
  @SuppressWarnings("unchecked")
  static final List<P2<Character, Character>> tokens =
    list(p('(', ')'), p('[', ']'));
 
  static boolean parse(final String s) {
    return fromString(s).foldRight(
      new F2<Character, Option<String>, Option<String>>() {
      public Option<String> f(final Character c, final Option<String> b) {
        return b.bind(new F<String, Option<String>>() {
          public Option<String> f(String s) {
            final List<Character> ss = fromString(s);
            return lookup(charEqual,
              tokens.map(P2.<Character, Character>swap_()), c)
                .map(Function.<Character,
                  List<Character>>constant(ss.cons(c)))
                .orElse(lookup(charEqual, tokens, c)
                .bind(new F<Character, Option<List<Character>>>() {
                  public Option<List<Character>> f(final Character v) {
                    return ss.isEmpty() || v != ss.head() ?
                        Option.<List<Character>>none() :
                        some(ss.tail());
                  }
                })).map(asString());
          }
        });
      }
    }, some("")).exists(isEmpty);
  }
 
  public static void main(final String[] args) {
    for(final String s : args) {
      booleanShow.println(parse(s));
    }
  }
}

Using Java BGGA and Functional Java:

import fj.Function;
import static fj.P.p;
import fj.P1;
import fj.P2;
import fj.data.List;
import static fj.data.List.asString;
import static fj.data.List.fromString;
import static fj.data.List.list;
import static fj.data.List.lookup;
import fj.data.Option;
import static fj.data.Option.some;
import static fj.function.Strings.isEmpty;
import static fj.pre.Equal.charEqual;
import static fj.pre.Show.booleanShow;
 
final class ParserBGGA {
  @SuppressWarnings("unchecked")
  static final List<P2<Character, Character>> tokens =
    list(p('(', ')'), p('[', ']'));
 
  static boolean parse(final String s) {
    return fromString(s).foldRight({ char c, Option<String> b =>
      b.bind({ String ss =>
        final List<Character> s = fromString(ss);
          lookup(charEqual,
            tokens.map(P2.<Character, Character>swap_()), c)
          .map(Function.<Character, List<Character>>constant(s.cons(c)))
          .orElse(lookup(charEqual, tokens, c)
          .bind({ char v =>
            s.isEmpty() || v != s.head() ?
              Option.<List<Character>>none() :
              some(s.tail())})).map(asString())})}
      , some("")).exists(isEmpty);
  }
 
  public static void main(final String[] args) {
    for(final String s : args) {
      booleanShow.println(parse(s));
    }
  }
}

A submission by a Java programmer who volunteered:

import java.util.ArrayList;
 
public class IsBalanced {
 
  private Stack stack = new Stack();
 
  public boolean isBalanced(String expression) {
 
    boolean isBalanced = true;
 
    for (int i = 0; i < expression.length(); i++) {
      char nextChar = expression.charAt(i);
 
      if (nextChar == '(') {
        stack.push('(');
      }
      else if (nextChar == '[') {
        stack.push('[');
      } else {
        if (!stack.isEmpty()) {
          char stackChar = (Character) stack.peek();
          if (nextChar == ')') {
            if (stackChar == '(') {
              stack.pop();
            } else {
              return false;
            }
 
          } else if (nextChar == ']') {
            if (stackChar == '[') {
              stack.pop();
            } else {
               return false;
            }
          }
        } else {
          return false;
        }
      }
    }
 
    if (!stack.isEmpty()) {
      isBalanced = false;
    }
    return isBalanced;
 
 
  }
 
  public static void main(String[] args) {
    System.out.println(args[0]);
    System.out.println((new IsBalanced()).isBalanced(args[0]));
  }
 
  private class Stack {
 
    private ArrayList stack = new ArrayList();
 
    public void push(char c) {
      stack.add(c);
 
    }
 
    public void pop() {
      stack.remove(stack.size()-1);
    }
 
 
    public Object peek() {
      return stack.get(stack.size()-1);
    }
 
    public boolean isEmpty() {
      return stack.size() == 0;
    }
  }
}

Forget the syntax for a moment and consider the compositional properties of each of these programs. For example, what if I were to add another pair of brackets such as '{' and '}'? Are there sub-programs that exist independently and can be extracted from the larger program? How does that affect my ability to reason (and therefore, read) the code?

What properties about the code make it easy to read?