Showing posts with label F#. Show all posts
Showing posts with label F#. Show all posts

Wednesday, January 14, 2009

Expert F# by Don Syme Review

(Sorry if this sounds like a commercial, but I liked the book)...

Can a 650+ page book from 2007 on an evolving language be any good? There are only two or three other F# books available, so saying it's the best reference isn't a big commitment. But two years after its release, Expert F# continues to be a great reference and overview of the language. It has a number of good things going for it.

  1. The book's not a 650 page reference manual. Expert F# is really two books in one. The first 250 pages deals solely with the language, functional and OO programming techniques, and available libraries. Seemingly in its entirety. I find F# an incredibly clean, simple, and easy language to program in (at least from my reference points). The fact that it can be fully described in 250 pages speaks to its straight-forward nature and lack of weird edge cases. Compare that to your JVM/CLR language du jour.

  2. The Appendix is a 7 page language guide to the F# syntax and language features. I printed this out from the eBook copy early on and it never left my side. This was a great aide in learning the language and all programming books should steal the idea.

  3. The functional programming chapter clearly explains the idioms of FP and does not use OO as a point of reference. I don't want an OO/FP hybrid and this is a good introduction to recursion, immutable data types, pattern matching, et al, yet it strictly avoids the common "here is how to use a functional syntax with the standard Java/C# mutable HashMap". In fact, I suggest you skip the OO chapter. Let's learn FP first, and then decide when it's required to resort to OO.

  4. The eBook has a searchable index. The book is 2 years old and it's still easiest for me to find answers in the pdf rather than searching Google and HubFS.

  5. The downloadable code samples are a valuable resource for exploring the concepts beyond code snippets. I have fond memories of using the PalmOS code samples to learn the platform, and these are of the same caliber. But seriously, isn't there a better build system for .NET than build.bat files? Ugh.

  6. An entire chapter on fslex and fsyacc? Actually, there are two chapters. Awesome, especially when coupled with the code samples. Langauge oriented programming gets a very good treatment here.

  7. The asynchronous workflow and concurrency chapter is worth reading just to see how elegant they made thread manipulation and wait/join actions. Yes there is a difference between let and let!, and it's cool. And who doesn't want yet another monad tutorial? Not me.
And the bad...

This is really two books in one: a language guide and a set of case studies on advanced topics. I'd have bought this book long ago if it were just the first 250 pages. Can anyone read a book that's too heavy to carry out of the house? My advice: buy the eBook and print out the chapters you want. Save a tree. Appreciate F# even if you don't plan on shipping code with it.

Sunday, September 14, 2008

Temporal Coupling in Java and Some Solutions

Temporal Coupling.

I first came across the term in Thomas and Hunt's The Pragmatic Programmer, where they encourage readers to consider "...the role of time as a design element of the software itself." Hmph. Most the chapter is about designing processes for parallelization, and not APIs, but the end of the chapter shows some code comparing C's strtok and Java's StringTokenizer. Reviewing this made me thankful that C++ is well behind me except for the odd bit of JNI code...

So StringTokenizer has a "hasNext" and "next" method on it, so callers can easily iterate over bits of a string. In the strtok days, there was only one method: strtok, and you passed it a string the first time you called it and null every other time to get the next token.

char input[] = "Hello World";
char* hello = strtok(input, " ");
char* world = strtok(NULL, " ");
I invite you to contemplate how the one, global strtok method works when accessed from multiple threads. So to the Prag guys, avoiding temporal coupling meant designing for concurrency. Strtok could never, ever work in a multi-threaded world because of the global state hidden behind method invocations. Whereas objects like StringTokenizer and Iterators work because their state is local to the object.

Bob Martin's Clean Code carries on the torch of avoiding Temporal Coupling, but with a new suggested fix. Consider an object with an execute() and getErrors() method (example from this comment). Which order should these method be called in? Well, the naming makes that fairly clear: first you execute and then you get the error messages. What happens if you call getErrors before execute? Should it perform the calculation or throw an exeception? There is no single answer. Bob's solution is the API equivalent of the bucket brigade:
final class Computation {
public Future<Computation> execute() {
// perform some computation, collecting errors, and returning a future
}

public static Collection<String> getErrors(Future<Computation> future) {
// get the error list out of the computation
}
}
execute() returns a Future of the result... this is a handle to the result of the computation, which may or may not be calculated yet. The getErrors method now requires one of these handles on it's parameter list. This example statically compiles the temporal coupling of the two methods: the getError method requires as input the output of the execute method. With this API it's very hard to invoke the methods out of order.

So what about Iterator?

It's certainly wasn't temporal coupling to the Prag Guys in 1999, seeing as they used an iterator-like API as a motivating and correct example. But clearly, calling iterator.next() repeatedly will result in an exception. There is state hidden behind it in the form of a cursor to the recordset. If an iterator is accessed by multiple threads then all callers of hasNext/next must have the same synchronization policy or risk having the iterator advanced after the hasNext check was performed but before next is called. This looks like temporal coupling to me, and it looks like a violation of the Design for Concurrency tip from the Prag programmer. So in 2008 we should probably start looking for ways to avoid this API.

Except that Effective Java's 2nd Edition (pub: 2008) recommends this API in some cases; disagree with Mssr. Bloch at your own peril. He spins the API as a way to avoid unnecessary use of checked exception. Checked exceptions just produce nasty code:
try {
obj.action(args);
} catch (SomeException e) {
//handle exception
}
The checking-API of providing a hasNext or isValid allows you to change a checked exception into a runtime exception because your callers have presumable validated that the correct preconditions hold before invoking the method:
if (obj.isActionAllowed(args) {
obj.action(args);
}
And Bloch is careful to point out that this API is not appropriate in multi-threaded scenarios where the state of the object may change between invocations of the guard check. So either you're single threaded or your object is immutable. Yet another reason to prefer immutability. Now, how would you implement an immutable iterator? You're probably better off using an immutable list. Anyway...

Assuming we need iterators and their ilk, what can we do instead?

Sentinel values are the common approach: return null, or "", or NaN. But in the end, undermining your type system just isn't smart. If you broadcast to the world that you return a String, then reserving one particular String as an error condition is just mean. Someone, somewhere is going to forget to perform the check. And it will be me and I'll do it about once a month. NullPointerExceptions are just another variation of this, but instead of using one type to represent two different conditions ("" is error, while all other strings are not), you're using two types without declaring it to your compiler (String method returns null or String). Ricky Clarkson's Optional Values in Java contains a good discussion of this (including the comments). Returning an empty list is a great way to signal that no results were found. Returning an empty list to indicate an error occurred is a bad use of sentinels.

And now is the time when we come to the Option type.

F# and OCaml don't have null* (simplification alert); They have an Option type. An Option can either have a value or not. So a function returning a String or null in Java would instead return Option of String, and you have to ask the Option object whether or not there it has a value before using it. The compiler doesn't allow null values to masquerade as Strings, and it won't allow you to reference an optional String until you check that it is available. The result is an end to NullPointerExceptions. That I can live with. Does the API become more complicated?
Option<String> option = iterator.next();
if (option.hasValue()) {
//do something with value
}
Iterator gets simpler because it loses the hasNext function. It's also no longer a concurrency issue to share iterators between threads. Each invocation of next() is atomic and there is no time window between hasNext and Next where the internal state can change. The calling code is really no different... you either make an unsafe check before grabbing an item or you grab an item and then make a safe check. The latter seems better.

The calling code could be cleaned up, of course. But that would require adding pattern matching to Java, which I suspect is unlikely. But the F# code to perform the checks and handle None vs. Some is concise and not alien once you get used to it:
let printName name =
match name with
| (fname, Some(lname)) -> printfn "Hello %A %A" fname lname
| (fname, None) -> printfn "Hello %A" fname

printName ("Sonny" , Some("Bono"))
printName ("Cher", None)
But even with an odd calling syntax from Java, concurrency issues facing the industry make the Option type a welcome addition to codebases. The implementation can be quite simple:
public final class Option<T> {

private final T value;

public Option(T value) {
this.value = value;
}

public boolean hasValue() {
return value != null;
}

public T get() {
if (value == null) throw new RuntimeException("Option not valued");
return value;
}

public static <T> Option<T> Some(T value) {
return new Option<T>(value);
}

public static <T> Option<T> None() {
return new Option<T>(null);
}
}
And here is a usage example:
final class StringUtils {
public static Option<String> stringToOption(String input) {
if (input == null) return Option.None();
else return Option.Some(input);
}
}
Functional Java
has an Option type, documentation here. And this is called Maybe in other languages (Haskell?). And I should credit Reinier Zwitserloot (best... name... ever...) with getting the ball rolling with his initial comment.

Sorry for the length!

Wednesday, August 6, 2008

Can Java.next include F#? Please?

Stuart Halloway coined the term "Essence vs. Ceremony" to describe the future of maintainable code in a post-Java world, and we're indebted to him for clearly and uniquely stating the problem with some of the most popular programming languages (historical note: it happened live at Code Freeze 2008 - hooray Minneapolis). Now he's back, this time describing the similarities in the new JVM languages gaining mindshare, a group of languages he's calling Java.next.

So I'll ask the question that is sure to be on the minds of JVM language users everywhere: "Is F# Java.next?" Let's consider it by comparing some Groovy and F# code...

Low-Ceremony Property Definitions - Java.next eases the burden of type, field, accessor, mutator, and constructor creation. F# Record Types fit the bill.

// F#
type Person = {
firstName: string
lastName: string }

let fred = { firstName="Fred"; lastName="Flinstone" }

// Groovy
class Person {
def firstName
def lastName
}

new Person(firstName:
"Fred", lastName: "Flinstone")
Expressive Collections - Java.next offers simple, easy, concise syntax for lists and maps. F# does too. The following code finds all natural number odd squares under 100:
// F#
[ 1 .. 10 ]
|> List.map (fun x -> x * x)
|> List.filter (fun x -> x % 2 = 1)

// Groovy
(1..10).collect{ it * it }.findAll { it % 2 == 1}

Functional programming - Java.next supports functional programming concepts like first class functions, closures, and higher order programming. F# is a functional language, it doesn't just support it. I'm not sure about Clojure, but I'd be willing to conjecture that F# has better FP support than Groovy or Ruby. This code creates a function that performs addition:

// F#
let sum a b = a + b

// Groovy
adder = { add -> { val -> val + add } }
Overriding Operators - F# and Java.next support operator overloading. Groovy supports a limited number of predefined operators. In F# you're just redefining what certain symbols mean, so the options in F# should not be so limited. The motivating example is to produce a custom Rational number type that can be used like this:
balance + (balance * interest)
The syntax for this isn't that pretty in either language, but is a bit more intuitive, in my opinion, in F# than Groovy because there is no special syntax. You define a member of the class just like any other, while Groovy requires a named method and even C++ required an operator keyword.
// F#
type Rational (num:int,denom:int) =
member x.num = num
member x.denom = denom
static member (+) (r1: Rational ,r2: Rational) =
Rational((r1.num*r2.denom) + (r1.denom*r2.num), r1.denom*r2.denom)
static member ( * ) (r1: Rational ,r2: Rational) =
Rational(r1.num*r2.num, r1.denom*r2.denom)

// Groovy

class Rational {
def num
def denom

Rational plus(Rational other) {
new Rational(
num: (this.num * other.denom) + (
this.denom * other.num),
denom:
this.denom * other.denom)
}

Rational multiply(Rational other) {
new Rational(
num:
this.num * other.num,
denom:
this.denom * other.denom)
}
}

Maintainable Exception Handling - I love anyone willing to call checked exceptions a failed experiment. C# doesn't have checked exceptions and it doesn't seem F# does either. So far F# has 5 out of the 8 commonalities with Java.next... could it just be part of this group?

Adding Methods to Existing Types - Working with Groovy's metaprogramming system has been a real joy, with only a few exceptions. Venkat's chapters on the subject in his book are great, and there is always Groovy.mn's presentation. Opening types to add members in F# is possible but I was told it was "bad form". It can be done, but the following is only valid within the "compilation unit" not globally... maybe that's a good thing though. This code adds an isPositive method to our previous Rational type:

// F#
type Rational with
member x.isPositive =
if x.num > 0 && x.denom > 0 then true
elif x.num < 0 && x.denom < 0 then true
else false

// Groovy
Rational.metaClass.isPositive = {
if (delegate.num > 0 && delegate.denom > 0) return true
if (delegate.num < 0 && delegate.denom < 0) return true
false
}

Roll-Your-Own Constructs - I'm not 100% clear on what this means. In Java.next you can "create new constructs that work like core language features". But the example in Clojure just seems to define a function called most that has a calling syntax like other language keywords. My knowledge of F# starts to break down here, but OCaml has a preprocessor that would allow you to do anything (cite: Robert Fischer), and there is purportedly an OCaml library that changes the language to use a Scheme prefix-operator-and-parenthesis syntax. Seems like F# should be up to par in this area. Here's an implementation of a generic most function like the one on Stuart's blog, just for fun (doesn't exactly scale well to larger tuples, though).

// F#
let most (x, y, z) =
match (x, y, z) with
| Some(x), Some(y), Some(z) -> true
| None, Some(y), Some(z) -> true
| Some(x), None, Some(z) -> true
| Some(x), Some(y), None -> true
| _ -> false
Everything is an Object - Java.next languages don't have primitive types... everything is an object. This helps with DSL funness because you can write code like 5.days.from.now, producing a Date object representing 5 days in the future. Cool. But to quote a Yegge post: "Dude, not everything is an object."
F# seems focused on creating operations that work on types rather than adding operations to types. F# still has the .NET value types like int and float, which can't have operations added to them. Adding a method to System.Int32 seems out of the question... at least I can't figure out how, which is quite different from impossible! A preprocessor should make quick work of this, but on the surface it doesn't seem supported. More research on my part is needed here. Bummer, F# only got 7 out of 8 Java.next commonalities.

Conclusion - The only logical conclusion is that we should start work on a .NET implementation running on the JVM. Starting Google Code project in 3...2...1...
Seriously though, cool ideas aren't restricted to the JVM and I've had a great time playing with F# and putting this post together. It's always fun to compare languages, isn't it?
(and curses to blogger's mangling of escape characters and whitespace, I did my best)

Monday, August 4, 2008

F# Sieve of Eratosthenes

My neighbor obsesses over rare candies. He'll travel to small towns with 5 and Dimes to buy the the wax lips and Mallo Cups he remembers growing up with. White people famously obsess over accumulating pirated music. I think it represents modern man's search for identity in a post-industrial society where we now have the luxury to contemplate more than just feeding our families and surviving the winter. It's intrinsically a play activity normally abandoned in young adulthood, but the affluence of our society has afforded us to become a culture of overgrown man-childs still tinkering with childhood past-times. So what do you obsessively accumulate? Oh, you're above it all, I understand. You're content with adult, intellectual pursuits... like spending Summer plowing through an endless list of fiction and memoirs (an accumulation of vague insights and good party conversation?). Perhaps you have a spiritual escape from it, and have melded a Christian upbringing with Kabbalah/ Scientology/ Pastafarianism) into a compassionate and pious life. Just be careful to not fall into Spirtual Materialism, Chögyam Trungpa's phrase describing the accumulation of spiritual detritus that simply serves to build up the ego.

If this sounds negative then you've gotten the wrong idea... I LOVE accumulating crap. Coins, comics, and crummy implementations of toy algorithms. Collecting useless junk is my birthright as a child of the modern age. My favorite: The Sieve of Eratosthenes. There's so much joy in retreading a useless relic from the past. Without further ado, here goes!

Maybe you remember Eratosthenes, the 3rd Century Greek who gave us the first accurate estimate of the Earth's circumference in the 3rd century bc. Perhaps not. He also gave us a method for finding prime numbers which, up until the 1970s, was the best way to find them. The algorithm from Wikipedia is a good starting point. They have you start with a finite list of numbers from 2 (2..100, say). The first element of the list is always prime, so 2 is prime. Now remove all multiples of 2 from the list, leaving only odd numbers. Again, the first element of the remaining list is always prime, so 3 is prime. Now remove all multiples of 3 from the list. First element (5) is prime, remove multiples of 5 from list, etc. etc. Implementing this algorithm will leave you with a list where the is always a prime number and the list is filtered each time the head is taken.

This method certainly works, and is the basis for Chris Smith's F# Sieve of Eratosthenes. Personally, I like mine better because all the data is immutable, there is no state, and it uses only built-in F# types (but kudos to Chris for getting the ball rolling):
#light

let primes max =
let rec next potentialPrimes =
match potentialPrimes with
| [] -> []
| n :: tail -> n :: next (List.filter (fun x -> x % n <> 0) tail)

next [ 2 .. max]

printfn "%A" (primes 1000000)
Reading through this quickly: "primes" is a function that returns all the prime numbers under the specified maximum. It is implemented as an inner, recursive function called "next", which is initailized with a list of all natural numbers from 2 to the maximum. "next" takes the list it is given as a parameter and a) returns an empty list when given an empty list, or b) concatenates the head of the list (remember, the head is always prime) with the result of a recursive call to next passing in the tail of the list with multiples of the head value filtered out. Writing this was every bit as satisfying as wax lips on a summer day. Mmm.

So why not end it here?

The problem with all this is that the Wikipedia algorithm starts with a finite list of numbers. What if you wanted to calculate all the prime numbers until you ran out of resource? What would you initialize the "next" function with? Long.MAX_VALUE? That isn't high enough if you have dedicated, purpose built hardware (which they had in the 1970s in order to run this exact algorithm). Infinity? The first step of this algorithm is to create an in-memory list of all numbers from 2 to max... if you set max to infinity then you'd run out of resources building the initial list before the first prime was even pulled. Ouch. Hopefully that bug is caught before it makes it to production.

A much cooler approach is to use infinite streams. And F# provides the perfect starting point: Seq. An infinite stream is a data structure that looks and behaves like a List type, but produces elements on demand using a function. The Seq.init_sequence function creates a seq instance that produces elements from the offset requests. So all natural numbers can be expressed lazily and infinitely using an identity function like so:

#light

// creates a Sequence of all numbers
let allNumbers = Seq.init_infinite (fun i -> i)
So what we need is a sieve based on lazy evaluation, bigint and Seq types. I humbly submit the following:
#light

let sieve max =

// creates a Sequence based on a "multiple of" function
let multiplesOf n = Seq.init_infinite (fun i ->
bigint.FromInt32(i) * n)

// checks if a given infinite bigint
// sequence contains a given bigint
let seqContains x seq =
let rec innerSeqContains count =
match x with
| _ when Seq.nth count seq = x -> true
| _ when Seq.nth count seq > x -> false
| _ -> innerSeqContains (count+1)
innerSeqContains 0

// checks if a list of infinite bigint
// sequences contains a given bigint
let rec seqsContain(x, seqs:seq<bigint> list) =
List.exists (
fun s -> seqContains x s) seqs

// generates a list of prime numbers, accumulating all
// non-prime numbers as a list of infinite sequences
let rec innerSieve (count : bigint) nonPrimes =
match count with
| _ when count = max -> []
| _ when count = 1I -> 1I :: innerSieve (count+1I) nonPrimes
| _ when seqsContain (count, nonPrimes) ->
innerSieve (count+1I) nonPrimes
| _ ->
let nextSeq = multiplesOf count
let newNonPrimeList = nextSeq :: nonPrimes
count :: innerSieve (count+1I) newNonPrimeList
innerSieve 2I []

printfn "%A" (sieve 500I)
Some details:

...multiplesOf is a helper function to create a Seq representing all multiples of a given bigint.
...seqContains determines if a given seq contains said bigint. The builtin contains can't be used without an infinite loop.
...seqsContain determines if any element of a seq of seq of bigint contains said bigint
...innerSieve simply produces the integers (this could in itself be expressed as a seq)

So what's up the initializing this thing to 500? Hey, I don't have specialized hardware, how do you expect me to test this thing? Anything over a couple thousand primes and my machine starts to crawl.

The sieve is a cool trick, but since the 70s it has been superseded by replaced as a prime finder by probabilistic techniques.

Wednesday, July 30, 2008

Morphisms for the Masses

No, not polymorphism. That's one we might consider unlearning. What I'm calling the “morphisms” refers to several types of recursive functions working with lists. Yeah, it's a neologism; that's the type of artistic license that comes with self publishing. But seriously, the morphisms aren't that hard, they just aren't often presented in a learnable way. And learning them gives you a more general way to talk about types of recursive functions, which can help you better explain your abstractions and designs. Let's get started.

Catamorphism
The coolest part of this is that you get to use Greek letters. κατα means “downwards”, as in “catastrophe”, and μορφή means “form” or “shape”. Put them together and you have catamorphism. Apply them to computer science and you have a recursive function that starts with a broad shape (a big old list) and funnels it into a single output (like an integer). The size() or length() method on a list can be a catamorphism. These functions are sometimes called “fold”. They take a type signature of List <Type A> into <Type B>. Or in Java:

int length(List list);
Which might be an implementation of the more general:
T length(List<?> list);
In F# (and I believe OCaml), the type signature for a catamorphism is:
'a list -> 'b
Read these type signatures by looking at the far right element first ('b). That is the return type. Everything else is a parameter. So “tick a” means a generic argument and “tick b” means a generic return type. The type signature of the List.length function in the F# core library is:
('a list -> int)
Phew. We're done with the types. Let's look at one more common example of a catamorphism: the sum function. Take a guess as to the type signature of sum(List)...
int list -> int
Yup, take a list of integers and fold it into a single integer result. And here is a naïve implementation:
let rec sum list =
match list with
| [] -> 0
| head :: tail -> head + (sum tail)
sum takes a list and returns 0 if the list is empty. Otherwise, it splits the list into a head and a tail, and adds the head onto the sum of the tail. Easy Peasy.

Anamorphism
This is the opposite of catamorphism. Some people like to say ”category dual” instead of opposite; you'll sound smarter if you do too. The Greek involved here is ανα, meaning “upward”, and μορφή meaning “shape”. Take a single input and expand it upwards into a wide list. This one is frequently called “unfold”, and a typical Java signature for an anamorphism might be:
List<Integer> first(Integer);
Which would presumably be a function to return a list of the first n numbers between 1 and the parameter. The same type signature in F# is:
int -> int list
That is, a function that takes in integer and produces a list of integers. In general, anamorphisms have the type signature:
'a -> 'b list
A single value is used to generate a list of other values, possibly of a different type. Let's take a look at an anamorphism that generates a list of the first n integers greater than 0, that is, a function with the signature int -> int list:
let rec first max =
match max with
| 1 -> [1]
| x -> x :: first (x-1)
First off, this isn't tail recursive! No bother... the point is to see that a list of integers is generated by building a cons list using the supplied value “max”.

Hylomorphism
Hey, we're done with the basics! If you understand the previous two types then you'll understand this one: a hylomorphism is the composition of an anamorphism and a catamorphism. The fun Greek part is ὑλο (hylo) meaning “wood”, which won't help you remember the term one bit. So putting an anamorphism ( 'a -> 'b list) together with a catamorphism ('b list -> 'c) results in a type signature of 'a -> 'b. Combine an unfold with a fold and you'll have a function that takes a value and returns a value, and hidden in the middle is a recursive function that builds then reduces cons lists. Using our previous examples of first and sum, we can put them together into a simple hylomorphism that sums the first n elements of the natural number scale:
let sumFirst max =
sum (first max)
This example explains the “composition” part of composing the anamorphism and the catamorphism, but it doesn't quite explain the recursive nature of a hylomorphism. See, a hylomorphism is going to build up a list and then perform an operation on each element of the list. Factorial is the archetypal hylomorphism:
let rec factorial x =
if x = 1 then 1
else x * (factorial (x-1))
You'll notice this is not tail recursive. At runtime, the recursive factorial calls build up a list of all the factorial results before applying the * multiplication. You might visualize the processing steps like this:
factorial 4 =
4 * (factorial 3) =
4 * 3 * (factorial 2) =
4 * 3 * 2 * (factorial 1) =
4 * 3 * 2 * 1 =
4 * 3 * 2 =
4 * 6 =
24
This uses a lot of memory and a lot of stack frames! But it doesn't have to be so. Some language compilers will recognize a hylomorphism and short cut it into a less resource intensive and tail-call like structure, applying the multiplication as it becomes available, not waiting until a large list is built up:
factorial 4 =
4 * (factorial 3) =
12 * (factorial 2) =
24 * (factorial 1) =
24 * 1 =
24
Visually, this method of executing the hylomorphism takes less steps, but the point is to eliminate the intermediate list and the resources associated with building it. This shortcut has a name: deforestation. And the compiler that does it is the Glasgow Haskell Compiler. Cool.

And now there's just one last morphism to cover...

Metamorphism
A metamorphism is the categorical dual of a hylomorphism: a catamorphism followed by an anamorphism. There's not a lot to say on this one... it doesn't help you understand deforestation and I don't even have the Greek translation for it. Nonetheless, I'm obligated to cover it for completeness.
A metamorphism is going to compose a catamorphism ('a list -> 'b) with an anamorphism ('b -> 'c list) to create a function of type ('a list -> 'c list). The previous examples can't be composed into a good metamorphism, so consider the function which turns a list of strings into a list of characters...
wordlist_to_chars ["The";"quick";"brown";"fox"]
producing...
['T';'h';'e';'q';'u';'i';'c';'k';'b';'r';'o';'w';'n';'f';'o';'x']
Would be defined as a function composition:
let wordlist_to_chars list =
chars (concat list)
where the concat function has the signature “string list -> string”, chars has the signature “string -> char list”, leaving wordlist_to_chars to have the composed signature “string list -> char list”. Implementing concat and chars as recursive functions is left as an exercise to the reader.

That it... you've seen some morphisms, some deforestation, and some cool Greek letters. Are you ready for paramorphisms, apomorphisms, and "Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire”? I'm not, but let me know how it goes.

Saturday, July 19, 2008

Awesome new Groovy Mixin Syntax (and F#'s alternative)

Groovy's MetaClass recently acquired some new features...

Check out how easy it is to add multiple new methods to an existing class:

class ListUtils {
static foo(List list) { "foo called" }
static bar(List list) { "bar called" }
}
List.metaClass.mixin ListUtils

assert "foo called" == [1, 2, 3].foo()
assert "bar called" == [1, 2, 3].bar()
From the DefaultGroovyMethods source, it looks like you can currently call .mixin on any Class or MetaClass object, passing a new Class (here ListUtils) or list of classes. Awesome.

Paulk made a few comments regarding the Maximum Segment Sum implementation in Groovy from my last post. Looking at both the F# and Groovy original implementations, it was easy to see the value that F# brought for functional programming. But the new versions can be seen here, and the results are not so different.

Open classes are still available in F#, despite it being a statically typed, compiled language. I still find the F# open classes syntax simple and appealing:
open List

type List with
member x.foo = "foo called"
member x.bar = "bar called"

if "foo called" <> [1;2;3].foo then failwith "error"
if "bar called" <> [1;2;3].bar then failwith "error"
I especially like how the 'this' reference can be named anything at all (here 'x').

Let the golf begin.

Thursday, July 17, 2008

Groovy vs. F# Showdown - Side by Side Comparison

Ah, our old friend Maximum Segment Sum. Given a list of integers, find the highest sum of any set of adjacent integers. The list [ 1, 2, 3, -4] has an MSS of 6 (1 + 2 + 3). The solution is deceptively simple:

mss = max º sum* º (flatten º tails* º inits)

Briefly explained…

inits() returns all the initial segments of a list in order of increasing length. So the inits of [1, 2, 3] is [ [1], [1,2], [1,2,3] ]

tails() returns all the trailing segments of a list in order of decreasing length. So the tails of [1, 2, 3] is [ [1,2,3], [2,3], [3] ]

Calculating the MSS is as simple as taking the inits of a list, taking the tails of the result, find the sum of each element in that result, and return the maximum entry. Simple, right?

Solving this is a great way to practice functional programming, which I did using Groovy in Function Calisthenics a few months ago, and again last night using F#.

The F# and Groovy results can be seen side by side here: http://www.hamletdarcy.com/files/2008/FsharpVsGroovy.html (I suggest opening it up in a new window big enough so that the lines don’t wrap).

Which begs the question, “Why would you ever want to compare F# (or OCaml) to Groovy?”

Because it explores the answers to a few other questions:

Are dynamically typed languages more concise than statically typed ones? Maybe the comparison between Java and Groovy isn’t a fair comparison, because the results here show F#/OCaml being more concise.

How awful is the F#/OCaml syntax? You can make your own conclusion, but it might be worth spending a few hours with the language before pronouncing a victor. I personally have found the freedom from curly braces and good recursion support a Good Thing.

Do I want to give F#/OCaml a try? That’s kinda the point of writing a post about the language, isn’t it?

So here goes…

Conciseness – The F# version is shorter, there’s no denying that. You also don’t need to add any type information despite the fact that the language is statically typed and the IDE shows you compiler errors as they happen. Also, the F# libraries offer much better support for functional constructs. For instance, the map_concat function doesn’t exist in Groovy, so much of the Groovy code is simply reducing a List of Lists of Lists to a List of Lists. Groovy support for closures and collections is good, but check out the F# documentation and see all functions you wish you had. There is certainly a learning curve to understanding the map*, fold*, and reduce* functions, but I contend that it’s worth the time to learn the fundamentals of Computer Science, which these concepts can rightly be categorized as.

Also, concise List and Map (and Sequence!) creation using the [ a, b, c ] notation is a wonderful thing. But this is an issue with Java, not statically typed languages in general.

The Awful Syntax – Come on, is it really that bad? Sure there is a new set of libraries to learn… but you’re not exactly investing in learning the .NET libraries, just the F# ones. I don’t know a thing about .NET and this was fairly simple. It doesn’t even really rely on the .NET libraries in this example (under the covers it does because it’s implemented in a .NET language and provides interoperability, but that’s another matter). Ricky Clarkson explores having to learn a new syntax in his post “In Defence of (0/:l)(_+_) in Scala”, which includes a quote from David MacIver: "Optimising your notation to not confuse people in the first 10 minutes of seeing it but to hinder readability ever after is a really bad mistake." Exactly. Maybe its time we ditch the C++/Java syntax. It’s not that hard.

Giving F#/OCaml a shot – Let me be clear: Learning F# is not the same as learning .NET. There are plenty of directions online for running it under Mono in Mac/Linux, and the F# install comes with an install-mono.sh shell script. I got it to run on an EEE PC with Xandros Linux without much effort. And there have been plenty of “wow” moments learning F# including wondering how the heck the compiler knows about my types and the satisfaction of finally understanding what “('a -> 'b) -> 'a list -> 'b list” means (Hint: it is a type signature that takes a function and a list and returns another list).

And why would you not want to make this comparison? Groovy is not a functional language and doesn’t advertise itself to be. Closure/lambda support in Groovy is good, and enables a functional style, but it’s not quite a level playing field. A comparison of the languages in an Object Oriented style might well yield different results.

Anyway, give it a shot, my friends, give it a shot. Perhaps the sweet F# handout can shed some light: http://hamletdarcy.blogspot.com/2008/07/f-handout-available.html

Monday, July 7, 2008

The F# Handout Available

I made a fancy handout for those interested in learning the F# language. This is a beginner's guide through the syntax and features of the language in an easily digestible two page format. Suitable for lamination!

Most the content is drawn from the Visual Studio examples and Chris Smith's excellent F# in 20 Minutes blog series.

There is a PDF version: http://www.hamletdarcy.com/files/2008/TheFSharpHandout.pdf
and a Word version (should you want to edit it).

Intro to F# at Groovy Users of Minnesota

I'm presenting an introduction to F# at the Groovy Users of Minnesota group this Tuesday night, July 8th, at 6:00 PM, Refactr World Headquarters.

Robert Fischer will present an "OCaml for Groovyists" and I'll present a fancy, full-color, laminated handout called "The F# Handout" that is certain to steal the show. (and will be posted here later).

Expect chaos.

Directions available here.