Tuesday, January 18, 2011

Project Euler #1 - One Problem, Three Solutions, Seven Languages

I haven’t posted here in a long time, and I apologize for that. No particular reason, but all good: programming in F#, learning lots of new programming stuff, enjoying the fall and winter holiday season (including hand-making some Christmas gifts), etc.

As I mentioned, one of the things I’ve been doing is learning new programming skills. I ignored F# during its early history, and the past year has shown me that was a mistake. So I decided to take a look at some of the other things I’ve been ignoring. That led me into various spots, including: Lua, Python, Ruby, MongoDB, MySQL, PostgresQL, Silverlight 4, SVN, Haskell, NetBeans, revisiting Scheme, the world of Visual Studio extensions, etc.

There’s a popular programming book by Bruce Tate, titled “Seven Languages in Seven Weeks.” In that spirit, I’d like to present something similar here: three views of Project Euler, problem number one, in seven languages. Some of these languages I’ve worked in for a long time; some of them I’ve just learned, but here goes. (As always, the code and information here are presented "as-is" and without warranty or implied fitness of any kind; use at your own risk.)

First is F#. Of all the languages listed here, F# is my favorite. Not by a wide margin, perhaps, but my favorite nonetheless. I think this is because of the vision of its creators: to build a language based on thoughtful consideration of all that has come before, both academic and pragmatic. At this, it succeeds brilliantly. (And no, Don Syme did not pay me to say this, lol.)

// Naive Implementation,
// based on problem statement.
// Illustrates aggregate operators
// and pipes.
let euler_1_naive a b bound =
  seq {1..bound-1} 
  |> Seq.filter (fun i->((i%a=0)||(i%b=0)))
  |> Seq.sum
 
 
// Sums stepped ranges.
// Illustrates aggregate operators
// and pipes.
let euler_1_iteration a b bound =
  (seq {a..a..bound-1} |> Seq.sum)+
  (seq {b..b..bound-1} |> Seq.sum)-
  (seq {a*b..a*b..bound-1} |> Seq.sum)
 
 
// Numeric (one possible factoring).
// Illustrates the use of nested functions,
// closures and immutable parameters.
let euler_1_numeric a b bound =
  let b1 = bound-1
  let f n =
    let c = b1/n
    c*(c+1)/2*n
    (f a)+(f b)-(f (a*b))


Next is Python. Python is an interesting language; it embodies a lot of characteristics that make it fun and easy to program in: orthogonality, lack of syntactic fluff, etc. On the other hand, it is a very businesslike language with a lot of excellent libraries available. If I were Java and C#, I’d watch my back.

# Python 3.1.3 and NetBeans w/Python plug-in.

def euler_1_naive (a,b,bound):
"""Naive Implementation,
based on problem statement.
Illustrates comprehensions
and implicit booleans."""
return sum(
i for i in range(1,bound)
if (not ((i%a) and (i%b))))


def euler_1_iteration (a,b,bound):
"""Sums stepped ranges.
Illustrates aggregate operators."""
return sum(range(a,bound,a))+\
sum(range(b,bound,b))-\
sum(range(a*b,bound,a*b))


def euler_1_numeric (a,b,bound):
"""Numeric (one possible factoring).
Illustrates the use of nested functions
and closures."""
bound -= 1
def f (n):
"""Compute sum of n-divisible."""
c = int(bound/n)
return int(c*(c+1)/2)*n
return f(a)+f(b)-f(a*b)


And here is Ruby. What to say about Ruby? Superficially, it strikes one as incoherent and arbitrary. But a closer look shows this to be a mistake. What looked like incoherence and randomness is really richness and a wonderful idiosyncrasy. Ruby is a complex, Raku bowl of a language, which reflects the mind of its creator, Yukihiro Matsumoto, and records all the incidents and accidents of its history. Of all the languages here, it is the one that draws the most passion from the programmers who use it, and I can see why. There’s a lot to be said for a language in which you can do something five times by coding “5.times {…}”

# Ruby 1.9.2 and NetBeans w/Ruby plug-in.

# Naive Implementation,
# based on problem statement.
# Illustrates filtering.
def euler_1_naive (a,b,bound)
((0...bound).find_all{
|i|(i%a==0)||(i%b==0)}).reduce(:+)
end


# Sums stepped ranges.
# Illustrates aggregate operators.
def euler_1_iteration (a,b,bound)
(a...bound).step(a).reduce(:+)+
(b...bound).step(b).reduce(:+)-
(a*b...bound).step(a*b).reduce(:+)
end


# Numeric (one possible factoring).
# Illustrates the use of lambdas
# and closures."""
def euler_1_numeric (a,b,bound)
bound -= 1
#Compute sum of n-divisible.
f = lambda {|n|
c = bound/n
c*(c+1)/2*n
}
f.call(a)+f.call(b)-f.call(a*b)
end


Lua, like Ruby and F#, reflects the visions of its creators. Like Python, it is simple and orthogonal. So simple and orthogonal, in fact, that it has only one non-value type: an associative table. Everything else – objects, lists, arrays, stacks, etc. – must be built using those tables. Lua’s simplicity and speed, coupled with the fact that it is implemented in a highly portable subset of C, make Lua a great choice for new processors, small machines, embedded scripting and similar environments. Think of it as a FORTH for the new millennium. I wish GPU shader languages looked like Lua.

function euler1Naive (a,b,bound)
acc = 0
for i=0,bound-1 do
if (i%3==0) or (i%5==0) then
acc = acc+i
end
end
return acc
end


function euler1Iterative (a,b,bound)
bound = bound-1
function f(n)
acc = 0
for i=n,bound,n do
acc = acc+i
end
return acc
end
return f(a)+f(b)-f(a*b)
end


function euler1Numeric (a,b,bound)
bound = bound-1
function f(n)
c = math.floor(bound/n)
return math.floor(c*(c+1)/2)*n
end
return f(a)+f(b)-f(a*b)
end


Good old Java, C#, and C/C++; the three tireless workhorses of modern computing. When programmed procedurally, all three are so similar that I will show only a single example: the naïve implementation in Java. Of course, the reasons why a programmer might prefer one of these languages over the others are real and important, but are simply beyond the scope of a snippet. In most cases it has to do with platform, ecosystem, and considerations of speed vs. safety. (In this example, and in the C# case below, I have omitted the enclosing class definition for brevity.)

public static int euler_1_naive (
int a,
int b,
int bound)
{
int sum = 0;
for (int i=1;i<bound;i++)
if (((i%a)==0)||((i%b)==0))
sum += i;
return sum;
}


Many procedural languages are growing to become more functional. To illustrate that, here is an example in C#, which makes us of a locally defined delegate.

// C# 4.0 and Visual Studio 2010.
 
// Sums stepped ranges.
public static int Euler_1_iteration (
  int a,
  int b,
  int bound) 
{
  Func<int,int,int> f = 
    (sum,n) => {
      for (int i=n;i<bound;i+=n) 
        sum+=i;
      return sum; };
 
  return f(f(-f(0,a*b),b),a);
}


C++0X also adds functional features and other modern constructs to the C++ language. The example below shows the definition of a lambda and the use of the “auto” keyword (a great boon to readability). The lambda syntax appears a bit arcane and robotic, but then, everything about C and C++ is a bit arcane and robot. *Which is exactly what programmers like about it.* (And if you really, *really* like that kind of thing, you might want to try FORTH.)

// Numeric (one possible factoring).
// Illustrates the use of lambdas, auto
// and closures.
int euler_1_numeric (
  int a,
  int b,
  int bound)
{
  bound -= 1;
 
  auto f = [bound] (int n) -> int 
  { 
    int c = bound / n;
    return c*(c+1)/2*n;
  };
 
  return f(a)+f(b)-f(a*b);
}


Last, here are a couple of examples that use template-based metaprogramming in C++. In case you haven’t encountered that before, it’s basically a way of tricking the compiler into running a program at *compile time* that leaves a correct value or structure in the compiled code. In these examples, the correct Project Euler #1 value is left in the enumeration value RET. Template-based metaprogramming can be a bit hard to wrap your mind around at first, and the examples here are not especially reflective of how it might be useful in the real world. Suffice to say that it can be a powerful technique for creating complex data structures and increasing runtime efficiency (for example, by permitting constant folding and similar techniques in ways that go beyond even optimizing compilers).

// Template metaprogram 1.
// Sums stepped ranges.
// Illustrates partial template
// instantiation.
 
template<int i, int acc, int n>
struct SRSum
{
  enum { 
    RET=SRSum<i,acc+i,n-1>::RET+acc 
  };
};
 
template<int i, int acc>
struct SRSum<i,acc,0>
{
  enum { RET=acc };
};
 
template<int a, int b, int bound> 
struct Euler1Iterate
{
  enum { 
    RET=(SRSum<a,0,(bound-1)/a>::RET)+ 
        (SRSum<b,0,(bound-1)/b>::RET)-
        (SRSum<(a*b),0,(bound-1)/(a*b)>::RET)
  };
};
 
 
// Template metaprogram 2.
// Numeric.
 
template<int n, int bound>
struct NSum 
{
private: enum { C=(bound-1)/n };
public: enum { RET=C*(C+1)/2*n };
};
 
template<int a, int b, int bound> 
struct Euler1Numeric
{
  enum { 
    RET=NSum<a,bound>::RET+ 
        NSum<b,bound>::RET-
        NSum<(a*b),bound>::RET 
  };
};
 
 
// Test both.
int _tmain(int argc, _TCHAR* argv[])
{
  return (Euler1Iterate<3,5,1000>::RET+
          Euler1Numeric<3,5,1000>::RET)/2;
}


Finally, a short word about benchmarks. The compiled versions (C/C++/C#/Java/F#) all ran a lot faster than the scripting language versions (Lua/Python/Ruby). That was no surprise. What was surprising, however, was just how fast the scripted versions were – even given the startup time. Plenty fast enough for almost anything other than data or numeric intensive programs, and certainly fast enough to handle most user tasks. Of the three scripting languages, Lua lived up to its reputation as the fastest, but Ruby and Python weren’t far behind (Ruby was slightly faster than Python).

And that’s it: one problem, three solutions, seven languages.

-Neil

p.s. I apologize for not syntax highlighting several of the samples. I have a VS2008 add-in that will do it, but I don’t know how to do it in NetBeans.

Monday, January 17, 2011

If Programming Languages Were Television Shows

I’m working on a more substantial post that compares several programming languages on a single problem. In the meantime, I give you something frivolous; my take on…

If Programming Languages Were Television Shows

F#Mythbusters. We don't just explain the functional programming myths, we put them to the test. (Am I missing an eyebrow?)

Haskell – The Saturday-afternoon calculus course from the local community college on the public access channel.

Fortran – An old movie, a perennial favorite with classic actors, and the credits arranged in a matrix.

Java – Something on a business channel with a scrolling stock ticker and announcers who wear kakis and blue button-downs.

C# – Just like Java, but with fancier graphics on the stock ticker and announcers who wear power ties.

Python – Financial advice for the small investor. It seems sound, but which way will the market trend?

C/C++ – Some PBS hippie show about growing and canning your own vegetables. Who needs garbage collection when you can compost?

Lua – A late-night foreign art film in black and white by a visionary director. Deep, but will it find enough sponsors to go prime time?

RubyStar Trek. Geeky, gadgety, and tough on newcomers, but a fiercely loyal fan base will keep this series in syndication for a while. Beam me up, Matz!

FORTHThe Woodwright’s Shop. Watch a guy make handmade furniture using handmade tools. Be careful of splinters.

Assembly Language - A test pattern.

COBOL – Something on the radio your parents or grandparents used to listen to.

(Sorry, COBOL geeks, I couldn't resist that last one, lol. We love you anyway.)

-Neil

Sunday, October 3, 2010

F# Computation Expressions: Basic Data Retrieval Mechanics

One of the uses often mentioned for F# computation expressions is that of simplifying the syntax of database retrieval. To investigate how the mechanics of this could work, I decided to implement a simple relational retrieval system. I tried to pare it down to the utmost basics, and I’m happy to say I got further than I expected; the sample problem has far more lines of code than does the computation expression itself!

The test database itself consists of two record types. The first is a simple key/value pair. The second is a linking record type which consists of two keys. This keeps things simple for the test, but the method would remain the same even for more complex record structures.

The computation expression doesn’t really do much other than see that work is properly partitioned into the classic collection and decision phases. Even less work is done by the operators (from, where, and select), which don’t have any function other than documentation. My test code uses a simple database of flags and colors, where the tables are implemented as lists.

Disclaimer: this oversimplified code is designed to illustrate the basic mechanics of this type of workflow. It is *not* to be considered ideal, practical or canonical! To solve this type of problem in production code, please use the F# Linq extensions; they are consistent, composable, and standard. (And as always, the code and information here are presented "as-is" and without warranty or implied fitness of any kind; use at your own risk.)

Credit: I think I first saw this idea from a web video, but I can’t recall where (possibly Channel9?). If anyone knows and can point me to it, I’ll be happy to revise this post to give credit to the source.

// Micro relational database.
 
/// ID,Value table.
type Rec = 
  {
    Key : int;
    Value : string
  }
  static member Make (k,v) =
    { Key=k; Value=v }
 
/// ID to ID relational link table.
type Link = 
  {
    KeyFrom : int;
    KeyTo : int;
  }
  static member Make (kf,kt) =
    { KeyFrom=kf; KeyTo=kt }
 
 
/// Micro query workflow.
/// Note the austere quality of the functions.
/// The real work is done by the collect in
/// the first bind and the decision in the second.
/// The workflow just sees to it that things 
/// get routed properly.
type MicroQuery () =
 
  // This de-sugars the "from" operator.
  member this.Bind (s,f) =
    Seq.collect f s 
 
  // This de-sugars the "where" operator.
  member this.Bind (b,f) =
    if b then f() else Seq.empty 
 
  // This de-sugars the "select" operator.
  member this.Return v =
    Seq.singleton v
 
 
// Since all the logic is contained
// in the workflow, these are not really
// necessary except as a form of
// self-documentation.
let inline from s = s
let inline where b = b
let inline select v = v
 
 
// For test data, I define some countries and
// the colors of their flags.  
// For consistency, I used the names 
// and spellings used in the USA.)
// If I left out your country, consider it 
// an exercise to the reader to add it!
 
let countries =
  [(0,"Australia");   (1,"Brazil");(2,"Germany");    
   (3,"Italy");       (4,"Mexico");(5,"Netherlands");
   (6,"South Africa");(7,"Spain"); (8,"USA")]
  |> List.map Rec.Make  
 
let colors = 
  [(0,"Black");(1,"Blue");(2,"Gold");
   (3,"Green");(4,"Red"); (5,"White")]
 |> List.map Rec.Make 
 
let flags =
  [(0,1);(0,4);(0,5);
   (1,1);(1,2);(1,3);
   (2,0);(2,2);(2,4);
   (3,3);(3,4);(3,5);
   (4,3);(4,4);(4,5);
   (5,1);(5,4);(5,5);
   (6,0);(6,1);(6,2);
     (6,3);(6,4);(6,5);
   (7,2);(5,4);
   (8,1);(8,4);(8,5)]
  |> List.map Link.Make 
 
 
/// This query will return the colors of
/// a country's flag.
let flagColors countryIn = MicroQuery () {
  let! country = from countries
  do! where country.Value=countryIn
  let! flag = from flags
  do! where country.Key=flag.KeyFrom
  let! color = from colors
  do! where color.Key=flag.KeyTo
  return select color.Value }
 
 
/// Test it:
let flagColorsBrazil = 
  flagColors "Brazil" 
  |> Seq.toList 
 
 
printfn "Your breakpoint here."
 

Friday, October 1, 2010

More Novice F# Computation Expression Bind/Return Mechanics

Today’s post is more F# “beginner” stuff I’m doing to help myself learn to think about workflows (or computation expressions as they are also called). As I’ve said before, I’ve gotten to the stage where I can usually puzzle out how to make a workflow do what I need it to do. However, my goal is to internalize the mechanics of workflows to the point where I can proactively recognize situations where they might be useful.

Paradoxically then, here is a particularly useless example. It does little more than simply perform a set of serial conversions. But it does illustrate the Bind/Return calling chain in a way that makes plain the “de-sugaring” mechanics. So I thought I would post it here. (As always, the code and information here are presented "as-is" and without warranty or implied fitness of any kind; use at your own risk.)

type Binder () =
 
  // Bind:0
  member this.Bind (v:int,f:string->float) =
    // v From Caller
    let down = v.ToString()
    let func = f down // Calls Bind:1
    let up = (float) func
    up // To Caller:
 
  // Bind:1
  member this.Bind (v:string,f:float->string) =
    // v From Bind:0
    let down = (float) v
    let func = f down // Calls Bind:2
    let up = (float) func
    up // To Bind:0
 
  // Bind:2
  member this.Bind (v:float,f:byte->double) =
    // v From Bind:1
    let down = (byte) v
    let func = f down // Calls Bind:3
    let up = func.ToString()
    up // To Bind:1
 
  // Bind:3
  member this.Bind (v:byte,f:byte list->int) =
    // v From Bind:2
    let down = [v;v]
    let func = f down // Calls Return
    let up = (double) func
    up // To Bind:2
 
  // Return
  member this.Return (v:byte list) = 
    // v From Bind:3
    let up = (int) (List.sum v)
    up // To Bind:3
 
 
let f = Binder () {
  let! x = 32 // Bind:0
  let! x =// Bind:1
  let! x =// Bind:2
  let! x =// Bind:3
  return x    // Return
  }
 
 
printfn "Your breakpoint here."
 
 
 
 

Monday, September 27, 2010

F# Computation Expressions, Yield/For Mechanics

Today’s episode of the ongoing computation expression saga features Yield/YieldFrom and For. One encounters fewer examples of these than of Bind/Return, though in most respects their operation is every bit as fundamental.

The code accompanying this post shows the use of these computation expression members in creating a rudimentary list comprehension builder. Of course, in real life you’ll want to use F#’s far superior built-in list comprehensions. But playing “how would I implement built-in construct X” is an old tradition in functional languages, so here it is. (As always, the code and information here are presented "as-is" and without warranty or implied fitness of any kind; use at your own risk.)

First, although the desired output is a list, the ongoing concatenation is maintained internally as a sequence. The Run operator does the work of converting the final sequence into a list. This makes the computation expression class more general, because the internal sequence could easily be converted to an array, .NET generic collection, etc., with a single change or override.

  member this.Run a = 
    a |> Seq.toList 


Most of the work for the yield operations in the example is done by the Combine operators. The Yield, YieldFrom, Delay, and Zero members are really just defaults (in fact, Yield and YieldFrom are identical in form). Three Combine operators cover most cases:

1) Prepending a yielded item to an ongoing sequence. This is the basic yield operation.

2) Combining a two sequences. This is the yield! operation.

3) Appending a yielded item with an ongoing sequence. This makes it possible to avoid calling the Zero operation using a “().” (Although Zero is supplied in case it is desired.)

  member this.Combine (a,b) = 
    Seq.append (Seq.singleton a) b
 
  member this.Combine (a,b) = 
    Seq.append a b 
 
  member this.Combine (a,b) = 
    Seq.append a (Seq.singleton b) 


The For operator just maps the body of the loop onto each item in the “for” sequence. This is essentially a default behavior for comprehensions. (An iteration across the “for” sequence might be a more appropriate default for some situations.)

  member this.For (s,f) =
    s |> Seq.map f 


At last, here is the full code plus an example. I named the computation expression builder class “SlightComprehension” both in order to reflect its rudimentary nature and to indicate my slight (but improving!) understanding of computation expressions, lol.

/// Rudimentary list comprehension builder.
type SlightComprehension () =
 
  /// Combine an item and a list.
  member this.Combine (a,b) = 
    Seq.append (Seq.singleton a) b
 
  member this.Combine (a,b) = 
    Seq.append a b 
 
  member this.Combine (a,b) = 
    Seq.append a (Seq.singleton b) 
 
  /// Map the function and convert
  /// the result to a list.
  member this.For (s,f) =
    s |> Seq.map f 
 
  // The following members are basically defaults.
 
  member this.Delay f = f()
 
  /// The concatenations are maintained
  /// internally as a sequence.
  /// This call converts them to a list
  /// on output.
  member this.Run a = 
    a |> Seq.toList 
 
  // The Combine overload makes 
  // Yield and YieldFrom identical
  // in form.
 
  member this.Yield a = a
 
  member this.YieldFrom a = a
 
  member this.Zero() = Seq.empty 
 
 
// Test.
 
let result0 = SlightComprehension () {
   yield 1
   for i in 2..3 do
     yield i 
   yield 4 
   // The following calls Zero.
   () }  
 
let result1 = SlightComprehension () {
   yield 0
   yield! result0
   yield seq { for i in 5..7 -> i }
   yield 8 }
 
// result1 = [0;1;2;3;4;5;6;7;8]
printfn "%A" result1
 
printfn "Your breakpoint here."
 
 
 

Sunday, September 26, 2010

F# Computation Expression Bind/Return Mechanics Continued.

Isn’t it always the way? Almost as soon as I posted the previous entry, I came up with an example I like better. Rather than replace that example, I’ll just post the new one here.

This one adds overloads to Bind, which show how both multiple types of let! bindings as well as do! bindings can be produced. It prints a trace of the calls and returns to the console, illustrating the descend an return behavior.

Below are the output and the code. As always, it is presented "as-is" and without warranty or implied fitness of any kind; use at your own risk.



 
/// Sample do!,let!,return! binder.
type Binder () =
 
  /// For indent to list level.
  let rec spaces spc = function
    | [] -> spc
    | h::t -> spaces ("  "+spc) t
 
  /// let! binding (first use).
  member this.Bind (s:string,
                    f:string list->string list) =
    printfn "Entering let! %s,[]" s
    let rtn = List.tail (f [s])
    printfn "%sLeaving let! %s,%A" (spaces "" rtn) s rtn
    rtn
 
  /// let! binding (nth use).
  member this.Bind ((s,sl):string*(string list),
                    f:string list->string list) =
    printfn "%sEntering let! %s,%A" (spaces "" sl) s sl
    let rtn = List.tail (f (s::sl))
    printfn "%sLeaving let! %s,%A" (spaces "" rtn) s rtn
    rtn
 
  /// do! binding.
  member this.Bind ((s,sl):string*(string list),
                    f:unit->string list) =
    printfn "%sEntering do! %s,%A" (spaces "" sl) s sl
    let rtn = f()
    printfn "%sLeaving do! %s,%A" (spaces "" rtn) s rtn
    rtn
 
  /// return.
  member this.Return (a:string list) =
    printfn "%sReturn %A" (spaces "" a) a
    a
 
 
// Test.
let result = Binder () {
   let! x = "A"
   let! x = "B",x
   do! "B0",x
   let! x = "C",x
   return x }  
 
printfn "Your breakpoint here."
 


p.s. For the spaces function you could also use something like:
new string(' ',sl.Length*2)

F# Computation Expressions, a Simple Bind/Return Mnemonic

I’ve gotten to the point where I can usually puzzle out what I need in a computation expression while I’m sitting at the computer. However, I can still have some trouble visualizing the process when I’m thinking “offline” (e.g. while in line at the grocery store, cleaning the rabbit’s litter pan, etc.). So I’m trying to come up with some useful patterns that I can keep in my head for such occasions.

Below is one I’ve come up with for basic Bind/Return operation. It’s just a simple computation expression that increments a different column of a base ten number depending on the operation. What are important to me are the names I came up with for the variables. I don’t claim that they are either academically correct or that they are the best possible names, but they are ones that make sense to me.

At the bottom of this post is my pattern. (As always, it is presented "as-is" and without warranty or implied fitness of any kind; use at your own risk.)

The Bind operation takes two parameters: “rhs” and “theRest.” “rhs” is the result from evaluating the right hand side of the let! assignment. In the example below, that’s the return from calling “add1.” “theRest” represents the remainder of the computation. As you can see, “rhs” (or in this case “rhs” after having 10 added to it), get passed down the line as an “assignedDownX” to “theRest.” When that call returns, the result gets “returnedUp.”

The Return operation takes a single parameter, “assignedDown.” For example purposes, this has 100 added to it. The result is then “returnedUp.”

The computation expression example shows the whole thing put together.

As I said, the names may not be ideal; they represent a particularly mechanical way of thinking about what is happening. In a context where more sophisticated computation is taking place, conceptual labels will be more meaningful. But I generally find it easier to remember the mechanical and work towards the conceptual, rather than vice versa. Perhaps I’m peculiar in that respect; I couldn’t really say for certain, lol.

Still, it's amazing how simple Bind/Return looks when sticking to the mechanics in light of the power that can be leveraged by augmenting those basic mechanics.

 
/// Add 1.
let add1 i = i+1
 
 
/// Adds a 10 on Bind, 
/// or a 100 on Return.
type BindAdd10ReturnAdd100 () =
 
  /// Add 10.
  member this.Bind (rhs,theRest) =
    let assignedDown = rhs+10
    let returnedUp = theRest assignedDown
    returnedUp
 
  /// Add 100.
  member this.Return assignedDown =
    let returnedUp = assignedDown+100
    returnedUp
 
 
// Test it out.
let result = BindAdd10ReturnAdd100() {
  let! assignedDownA = add1 0
  let! assignedDownB = add1 assignedDownA
  let! assignedDownC = add1 assignedDownB
  return assignedDownC
}
 
 
printfn "Your breakpoint here."

Friday, September 17, 2010

F# Workflow for Building Immutable Trees from Delimited Strings

Here is an update on an earlier post: Computation Expressions with .NET Data Types. In that case, I showed how to use computation expressions to build a tree from a character-delimited string. However, there were two things about it I wanted to correct. First, my understanding of idiomatic F# has improved; it’s still a long way from perfect, but it has improved. Second, and more important, I really wanted to create an immutable version, but I lacked the skill with computation expressions at the time of the earlier post.

This post corrects those flaws and presents an interesting workflow design pattern which I think I’m going to find useful in a number of contexts. (For example, it can be adapted to trees based on data structures other than lists; even .NET data structures as in the original post.)

(As always, presented "as-is" and without warranty or implied fitness of any kind; use at your own risk.)

/// Splits a string into a list, 
/// using char.
let splitter (c:char) =
  let ca = [|c|]
  (fun (s:string) ->
    s.Split(ca) |> Array.toList)
 
 
/// Canonical discriminated union tree.
type Tree = 
  | Branch of string*Tree list
  | Leaf of string
 
 
/// Computation expression class to
/// split a string into a tree.
type TreeSplitter () =
 
  member this.Bind (sa,f) =
    List.map (fun s->Branch(s,f s)) sa
 
  member this.Return sa = 
    List.map (fun s->Leaf(s)) sa
 
 
// Test.
 
/// Split by bar, colon, then dot.
let barColonDot s = 
  Branch(
    s, 
    TreeSplitter() {
      let! x = splitter '|' s
      let! x = splitter ':' x
      return splitter '.' x
    })
 
// Test print a tree.
let printo =
  let rec f (spc:string) = function
    | Branch(s,c) ->
      printfn "%s%s" spc s
      List.iter (f (spc+"  ")) c
    | Leaf(s) ->
      printfn "%s%s" spc s
  f ""
 
// Run a test.
 
printo 
  (barColonDot "a0.a1:b0.b1|c0.c1:d0.d1")
 
printfn "Your breakpoint here."

Thursday, September 16, 2010

F# Async Computation Expressions: A Tiny Model System

Continuing my quest to learn computation expressions, I decided to explore from scratch the implementation of basic asynchronous behavior. This post is the result. It’s not too fancy, and lacks basic safety, resource management, etc., SO DON’T SIMPLY COPY AND USE IT IN REAL LIFE, but it gets the basic idea across. For real-world use, browse the Microsoft-supplied F# async classes (Microsoft.FSharp.Control.Async, etc.); you’ll find better stuff there than I could come up with. My goal here was to temporarily strip away most of the complexity, however necessary it is in real life, to investigate an underlying model.

My computation class below is just a simple thread spinner. It starts a thread process and then continues with the computation. As each bit completes, its caller waits for its own process to join, until the initial call joins and control continues at the module level. A test function in the form of a simple string printer is supplied. The screenshot below records a typical run.



As always: this code and other information is presented "as-is" and without warranty or implied fitness of any kind; use at your own risk. This is especially true in this case! Multi-threading can be a tricky business, and again I recommend you treat my code here as an oversimplified example, and use the Microsoft.FSharp.Control libraries for real-world use.

open System.Threading
 
 
/// A simple thread-runner.
/// Note: don't use this in real life!
/// Write something with better safety,
/// resource management, etc., or better yet,
/// use the F# supplied Async libraries!
type OverlySimpleAsync () = 
 
  /// Starts a thread and moves on,
  /// then waits for a join.
  member this.Bind (tp,f) =
    let t = Thread(ThreadStart(tp))
    t.Start()
    f()
    t.Join()
 
  /// Does nothing.
  member this.Return a = a
 
 
// Simple test.
 
/// This simple test prints a string
/// parameter a random number of times
/// with a random sleep between.
let r = System.Random()
 
let testThreadProc a =
  (fun () ->
    let count = r.Next(10,20)
    let sleep = r.Next(10,500)
    for i=0 to count do
      printf "%s" a
      Thread.Sleep(sleep))
 
// Spin some threads.
 
do OverlySimpleAsync() {
  do! testThreadProc "A"
  do! testThreadProc "B"
  do! testThreadProc "C"
  do! testThreadProc "D" 
}
 
printfn ""
printfn "Your breakpoint here."

Monday, September 13, 2010

Basic F# Computation Expressions Using Yield and Combine

I decided to learn a little bit about computation expressions beyond the basic Bind/Return operations. So I made a goal of learning something about the Yield/Combine operations.

To demonstrate these operations, I decided to leave behind the world of tomato pricing and return to the simple animal expert system. The code below implements a typical “toy” guess-the-animal expert system. It uses computation expressions and lazy evaluation to implement the query and inference logic. It’s perhaps a bit of a misuse of the “yield” idiom, but it does demonstrate the basic mechanics in a way that can be compared to examples in earlier posts.

The operation is simple: Yield, Return, and Delay really don’t do much except propagate values; the real logic is in the Combine function. It uses the short-circuit feature of the && and || logic operators to minimize the number of queries when establishing a hypothesis. Lazy evaluation insures that queries are not repeated. A couple of utility functions query and conclude, take care of gathering the data and reporting the result. (Note that pressing the ‘y’ or ‘Y’ key indicates an answer of “yes,” while pressing any other key indicates “no.”)

I’m not sure I’d want to make this the basis of a “Fifth-Generation” A.I. project, lol, but is does show how a neat little DSL can be built with only a few lines of F# code. The basic “engine,” the computation expression, takes up only 17 lines of code, including comments and whitespace! Now that’s a tiny expert system shell if there ever was one…

Here is the output from a typical session:



And below is the code. (As always: this code and other information is presented "as-is" and without warranty or implied fitness of any kind; use at your own risk.)

// Joins values asserted by Yield, using a 
// supplied combining function.
type Join (fCombine) =
  member this.Combine (a:Lazy<bool>,b:unit->Lazy<bool>) = 
    fCombine a b
  member this.Delay (f:unit->Lazy<bool>) =
    f
  member this.Return (a:Lazy<bool>) = 
    a
  member this.Yield (a:Lazy<bool>) = 
    a
  member this.Yield (a:unit->Lazy<bool>) = 
    a()
 
// Define conjunction and disjunction with short-circuiting.
let conjoin = Join(fun a b->Lazy(fun()->a.Value&&b().Value))
let disjoin = Join(fun a b->Lazy(fun()->a.Value||b().Value))
 
 
// Syntax helper to query for a boolean.
let query s =
  (fun () ->
    printf "%s " s
    let q =
      ("yY").IndexOf(
        System.Console.ReadKey().KeyChar)
          <>(-1)
    printfn ""
    q)
 
// Syntax helper to assert a lazy boolean.
let conclude s b =
  printfn "%s" s
  Lazy(fun()->b)
 
 
// Basic facts.
 
let black = 
  Lazy<bool>(query "Is the animal all or partly black?")
let orange = 
  Lazy<bool>(query "Is the animal all or partly orange?")
let white = 
  Lazy<bool>(query "Is the animal all or partly white?")
 
let spotted = 
  Lazy<bool>(query "Is the animal spotted?")
let striped = 
  Lazy<bool>(query "Is the animal striped?")
 
// Intermediate hypotheses.
 
let blackAndWhite = conjoin {
  yield black
  return white
}
 
let blackAndOrange = conjoin {
  yield black
  return orange
}
 
// Output hypotheses (i.e. animals).
 
let tiger = conjoin {
  yield blackAndOrange
  yield striped
  return conclude "It's a tiger." true
} 
 
let zebra = conjoin {
  yield blackAndWhite
  yield striped
  return conclude "It's a zebra." true
} 
 
let leopard = conjoin {
  yield blackAndOrange
  yield spotted
  return conclude "It's a leopard." true
} 
 
let dalmation = conjoin {
  yield blackAndWhite
  yield spotted
  return conclude "It's a dalmation." true
} 
 
// Root hypothesis.
let animal = disjoin {
  yield tiger
  yield zebra
  yield leopard
  yield dalmation 
  return conclude "It must be a sasquatch!" false
}
 
 
// Run the engine.
let isKnownAnimal = animal().Value 
 
printfn "Your breakpoint here."