Notes on Structured Design

A while ago I finished my first reading of Structured Design. Here are some notes and random thoughts about it.

Why did I read it?

My first encounter with the book was when reading Kent Beck’s Responsive Design article:

In 2005 I was invited to sit on a panel celebrating the 25th anniversary of the publication of Ed Yourdon and Larry Constantine’s Structured Design, the book that introduced the terms coupling and cohesion. I’d had a copy in my library since I’d used it as a college textbook, but, since I had used it as a college textbook, I hadn’t really read it. As I studied it in preparation for the panel, I realized that many of the questions I had about software design had been answered two decades before. This motivated me to make my informal study of design more structured and rigorous, and to communicate the results to a new generation of programmers. This was the official genesis of the Responsive Design Project.

Beck also mentions this book in his post on Coupling and Cohesion. Then Aslam Khan showed me a physical copy of the book.

In general

I like the book. I like the subject. The book has lots of content. Some of the content is timeless, some is a bit dated (first print 1979).

Some nice quotes

“…the cost of implementing a computer system will be minimized when the parts of the problem are 1) manageably small 2) solved separately” (p18)

Note that this means that the division of problem parts is too fine-grained (i.e. the parts are too small), then they can’t be be solved separately. However, it’s better if the parts are too small than too large, since it’s often easier to “join” parts than to separate one part into smaller ones.

“[…] what can be seen is more easily understood that what cannot be seen.” (p100).

Implicit < explicit.

A paragraph on page 106 says (my summarization)

Focus on cohesion, since cohesion => coupling

However, the two concepts are not in a perfect correlation, but on average your coupling will decrease if your cohesion increases.

“In general, the use of pathological connections reduces the ability of the programmer to treat modulues as black boxes.” (p263)

Somewhat related to implicit < explicit.

Some nice pictures

5_3

6_7

In closing

Structured Design is a recommended read. I especially liked chapters 1-9, 19.0-2, 20-21. Regarding the other chapters; they didn’t really ring a bell in me, perhaps I misunderstood the contents or I haven’t experienced the problem (due to my inexperience or that the problem is nowadays “solved”), or a combination of the above…

Posted in Uncategorized | Tagged , | 1 Comment

Zen and the Art of Motorcycle Maintenance

I recently finished reading “Zen and the Art of Motorcycle Maintenence” (ZAMM) by Robert Pirsig and I would like to say a few words about that book.

First, I think it’s a good book and would recommend it to anyone who has an (perhaps small) interest in philosophy. It contains some important parts of the history of philosophy, told in a pretty approachable way.

I don’t want to summarize or give a full review of the book. Instead, read the reviews on Amazon for that: http://www.amazon.com/Zen-Art-Motorcycle-Maintenance-Inquiry/dp/0553277472

Beware, because there are some traps in the book. ZAMM is a book about philosophy and metaphysics, so there’s going to be a few ideas in there that challenge your view of the world. At least, it challenged me. Here’s an important tip: Don’t get stuck! For example, Pirsig tells us about David Hume’s version of empiricism and its implications, which for me was very hard to accept at the time. So, I thought about it for quite a while. Instead, I could have read on and discovered that Pirsig introduces us to Kant, who (according to Pirsig) wrote “Critique of Pure Reason” as an answer to Hume.

I mean that you should absolutely think about the problems introduced in the book, but try not to get stuck.

Actually, one of the most practical parts of the book is when Pirsig talks about “not getting stuck” and you find some of his ideas here and here. As a software developer, I really found this part of the book useful.

What does Pirsig mean with the word Quality? There’s so much that word could mean. There’s a part in the book which talks about if quality is objective, subjective, or outside that dichotomy. Pirsig says that quality can’t be objective (I agree) and gives some arguments. He then also says at the same time that quality can’t be subjective, but the argument is pretty much like “when you sense quality, you feel something that is outside of yourself”. I don’t get that argument. (If I missed something, please comment below or tweet me).

[I think that quality (for humans) is subjective. More specifically, I think that it is very close to that which Lacan calls “objet petit a” – the unattainable object of desire, or perhaps “the the object cause of desire” (but don’t take my word for it). Then, of course, some of us desire similar things, but I think at least that it is more of a cultural phenomena, rather than something universal in nature.]

A lot of the book is travelogue, Pirsig tells us what he sees and experiences on the road with his eleven years old son, Chris. I don’t like the amount of travelogue text in ZAMM, it’s just too much. Sure, it lightens up the philosophical material in the book, but there’s just such a big amount of travelogue text and as far as I can tell it doesn’t add much to the book.

There is a good podcast episode about ZAMM from The Partially Examined Life podcast. There, you also find some good blog posts which discusses the ideas in the book, and they do not have a consensus on Pirsig’s ideas in the group. More specifically, they seem to disagree on the value of his ideas and also on the novelty of them. For example, some say that there are some Heidigger, Hegel, and pragmatism in his text. Perhaps I could personally stretch it to say that Pirsig takes a pragmatic process philosophy stance, but I’m not too sure about that one..

In summary, ZAMM is a good book which introduces some important part of the history of philosophy in a quite easy manner. Recommended reading.

Posted in books | Tagged , | 2 Comments

Complexity is Subjective

I recently read the book “Systems Thinking for Curious Managers” [1] and found this good quote:

“Complexity is not a property of problems but of those looking at problems.”

After I finished reading the book, I decided to explore this idea further and found the research paper “A Subjective Measurement of Complexity” [2]. It contains a lot of good ideas. The most important of them is that complexity is subjective and that there is a distinction between the notion of a complex system, a complicated system and a simple system.

Note that Ackoff talks about problems and Fioretti talk about systems. My gut feeling is that there is not much difference between a problem and a system: A problem is a question about a system that we want an answer to, possibly because we want to get more value out of the system or that we want to understand the system better (which gives us value personally). It is also likely that the question and the system will be better defined as we learn about the system along the way.

The paper begins with:

“Complexity is often thought as a property of the system under observation, much in the same way as its mass or its volume.”

And then he states a similar idea as Ackoff:

“An alternative approach […] is that of viewing complexity as a property of the relationship between a system and its observer: the person who is observing a system says that ‘this system is complex’ when she is not satisfied with the mental model she has of it.”

In the end of the introduction, Fioretti makes the distinction between complex, complicated and simple systems:

“If the observer knows that he did not identify all the relevant elementary particles, or if he knows that he did not identify all the causal relationships that link the events these particles generate to the actions he undertakes upon the system, or both, then he says that the system is complex.

If the observer did identify all the relevant elementary particles, as well as the causal relationships that link the events that these particles generate to the actions he undertakes upon the system, but he is not able to express all these relationships by means of a universal law, then he says that the system is complicated.

If the observer identified all the relevant elementary particles as well as the causal relationships that link the events these particles generate to the actions he undertakes upon the system, and if he is able to express these relationships by means of a universal law, then he says that the system is simple.”

I interpret the statements as:

  • Complex: We get surprised of the behavior of the system
  • Complicated: We understand the system and can predict the behavior of the system, but cannot express it in one or more laws
  • Simple: We can express the system in one or more laws

When building software, I think that the “complexity is subjective” idea could be useful. For example:

  • “Staff turnover” – getting new members in a team would most likely increase the mean complexity of the software.
  • “Code rot” – when code is forgotten by the team, changing the code could lead to unpleasant surprises
  • “Size matters” – our brains have a limited working memory, it is difficult to predict how a large system will react to change

There are probably more examples in software. And in other systems too.

[1] Systems Thinking for Curious Managers, by Russell Ackoff. It contains a good introduction to Systems Thinking.
[2] A Subjective Measurement of Complexity (pdf), by Guido Fioretti

(Note: I plan to write more about surprise in the future and how surprise relates to quality. I also plan to write about system boundaries in the future.)

Posted in Uncategorized | 1 Comment

How Bridges Fall

During the last six months I have watched “The Ister” twice. It’s a remarkable documentary based on Martin Heidegger’s wartime Hölderlin lectures.

In one part of the documentary, Nemanja Calic talks about the NATO bombings of the bridges in Novi Sad during the Yugoslav war. The mentioned bridges are the Sloboda bridge (sloboda is the slavic word for freedom) and the Zezelj bridge:

Sloboda bridge in Novi Sad

Zezelj Bridge in Novi Sad

Here is some of what Nemanja Calic says in the documentary:

See what is impressive, for example, is that this [The Sloboda bridge] is kind of a sophisticated structure. With stay cables, with high pylons and everything. Although it’s a little bit old-fashioned now, for that time (the early 1980) it was really an accomplishment.

And the other bridge, the big concrete bridge, Zezelj Bridge […], was built a decade earlier in a classic style, an old-fashioned arc bridge. And having a look at the way they were destructed, the sophisticated structure gave up instantly, and the old one had suffered, let’s say, seven attacks, with more than thirty missiles, bombs, whatever was launched on it, whilst the Sloboda Bridge collapsed after only two Tomahawk missiles, very precise in the base of the pylons. And it was down in a minute.

But Zezelj Bridge, concrete arc structure, retained, although very heavily damaged, perforated by various hits… And finally they could not put it down. And they concentrated their attacks on the middle pier, in the river. They gave up targeting the beams, the arcs, and then they concentrated their fire on the middle pier, and then they just destructed it. It was just blown away, and without the pier, both arcs collapsed in the river.

I just wanted to point out the difference between modern, sophisticated technologies, even in the construction business. The more sophisticated they are, the more sensitive they are. I don’t say that the other one is safer than this one, but it’s more sophisticated. Vulnerable. If you touch it at the proper point it will yield, it will give up.

So that’s how it went…

Here is another image of the Zezelj bridge. Notice the size of the middle pier.

I think it’s an important story, from many perspectives and it leaves some room for thoughts for the listener. For example, why did NATO bomb the bridges? Was it a correct decision? Was the design of the “modern bridge” too brittle? Is Nemanja’s suggestion correct that sophistication leads to sensitive systems? What happened to the people in the city during and after the war? Or why was there a war in Yugoslavia in the first place?

(Nemanja Calic text copied from http://www.rouge.com.au/3/ister.html)
Photos from VIVISECTfest.

Posted in Uncategorized | Tagged | 1 Comment

My impressions from Øredev 2009

Yesterday I wrote a post called “My impressions from Øredev” on Dotway‘s blog. In summary, I had a great time there and I’m still very inspired from the experience.

Hope to see you there next year! 🙂

Posted in Uncategorized | Leave a comment

FizzBuzz in LINQ

Earlier this week I realized that you are able to define functions in LINQ queries. So I made myself a sweet little FizzBuzz in LINQ.

It’s not pretty code, but I had fun writing it. Though, the code would be a somewhat nicer without all the type declarations everywhere. Hehe, I guess that if your code reminds you of The Obfuscated Code Contest, it’s a pretty good sign that your code stinks. Clearly muda!


[TestMethod]
public void FizzBuzz()
{
var lines = from x in Enumerable.Range(1, 100)
let divides = new Func<int, int, bool>((denominator, nom) => nom % denominator == 0)
let fizz = new Func<int, Tuple<int, string>>(
n => new Tuple<int, string>(n, divides(3, n) ? "Fizz" : ""))
let buzz = new Func<Tuple<int, string>, Tuple<int, string>>(
tuple => new Tuple<int, string>(tuple.Item1, tuple.Item2 +
(divides(5, tuple.Item1) ? "Buzz" : "")))
let returnNumberIfEmptyString = new Func<Tuple<int, string>, string>(
tuple => tuple.Item2 == "" ? tuple.Item1.ToString() : tuple.Item2)
select returnNumberIfEmptyString(buzz(fizz(x)));

foreach (var line in lines)
{
Debug.WriteLine(line);
}
}

(Oh, forgot to say that I use the .NET 4.0 tuples for this post)

Posted in Uncategorized | 1 Comment

From for loop to anamorphism

Introduction

Sometimes you want to generate a sequence of objects. This is often done using a for loop:
[Test]
public void CreateListOfFoos()
{
var xs = new List<Foo>();
for (int i = 0; i < 10; i++)
{
xs.Add(new Foo());
}

Assert.AreEqual(10, xs.Count());
}
In this post, I will show you how this code can be made more general, ultimately turning it into an anamorphism over lists.

Generalizing constructed type

First, what we want to do is to be able to create something other than a Foo. We apply ExtractVariable once and we also extract the constructor call to a lambda:
[Test]
public void ExtractMethod()
{
var times = 10;
Func<Foo>newFoo = () => new Foo();

var xs = CreateFooNumberOfTimes(times, newFoo);

Assert.AreEqual(10, xs.Count());
}

private IEnumerable<Foo> CreateFooNumberOfTimes(int times, Func<Foo> newFoo)
{
var xs = new List<Foo>();
for (int i = 0; i < times; i++)
{
xs.Add(newFoo.Invoke());
}
return xs;
}
From the above code, it’s easy to generalize on the type created. Note that we could have skipped the “constructor lambda” and instead used the “where T : new()” constraint.
[Test]
public void GeneralizeTypeForFunc()
{

var times = 10;
Func<Foo> newFoo = () => new Foo();

var xs = CreateTNumberOfTimes(times, newFoo);

Assert.AreEqual(10, xs.Count());
}

private IEnumerable<T> CreateTNumberOfTimes<T>(int times, Func<T> newFoo)
{
var xs = new List<T>();
for (int i = 0; i < times; i++)
{
xs.Add(newFoo.Invoke());
}
return xs;
}

Generalizing type for accumulator

We have now parametrized Foo to T, but wouldn’t it be possible to parametrize from “int” to A, as well? Let’s begin with breaking out the int-specific code from the for loop:
[Test]
public void ExtractForLoopLogic()
{
Func<Foo> newFoo = () => new Foo();

int i = 0; // Will be modified lots of times
Func<bool> expr = () => i < 10;
Action inc = () => i++;

var xs = CreateTUntil(newFoo, expr, inc);

Assert.AreEqual(10, xs.Count());
}

private IEnumerable<T>CreateTUntil<T>(Func<T> newT, Func<bool> expr, Action inc)
{
var xs = new List<T>();
for (; expr.Invoke(); inc.Invoke())
{
xs.Add(newT.Invoke());
}
return xs;
}
As indicated in the code, the variable “i” will be modified the closure called in CreateTUntil. Bart de Smet calls this a cruel lambda. Except that it’s quite hard to understand a lambda that mutate its outer scope, refactoring code that’s using cruel lambdas can make your code go totally bananas!
Let’s rewrite the code to use a pure lambdas instead. To do this, we need to refactor the for loop to a while loop, since the first and third “parameters” to a for loop are statements (not pure). We also parametrize from “int” to type parameter “A” instead.

Going pure and a more general constructor

[Test]
public void ForLoopToWhileLoop()
{
Func<Foo> newFoo = () => new Foo();
Func<int,bool> expr = a => a < 10;
Func<int,int> inc = i => i + 1;

var xs = CreateTUntilUsingWhile(newFoo, 0, expr, inc);

Assert.AreEqual(10, xs.Count());
}

// Now a pure method
private IEnumerable<T> CreateTUntilUsingWhile<T>
(Func<T> newT, int init, Func<int,bool> expr, Func<int,int> inc)
{

var xs = new List<T>();

int i = init;

while (expr.Invoke(i))
{
xs.Add(newT.Invoke());
i = inc.Invoke(i);
}
return xs;
}
Now we don’t have any concrete types in the method signature, except bool, which I think is ok to have there at this point. But, as the observant reader might have noticed, the constructor can’t be called with a variable argument, i.e. the accumulated value. What we need to do is to “connect” the lambdas that generates values, like this:
[Test]
public void ArgumentForConstructor()
{
Func<int,Result<Foo,int>> gen = n => new Result<Foo,int>(new Foo(), n + 1);
Func<int,bool> expr = a => a < 10;

var xs = GeneralizedCreateTWithArgsUntilUsingWhile(gen, 0, expr);

Assert.AreEqual(10, xs.Count());
}

private IEnumerable<T> GeneralizedCreateTWithArgsUntilUsingWhile<T,A>
(Func<a,Result><T,A>> gen, A init, Func<A,bool> expr)
{
var xs = new List<T>();

var i = init;

while (expr.Invoke(i))
{
var result = gen.Invoke(i);

xs.Add(result.Value);
i = result.Accumulator;
}

return xs;
}

Going recursive

Now it’s up to the generating lambda to pass an argument to the constructor or not. What’s funny with this is that if we replace the while loop to a recursive call, we come pretty close to the definition of an anamorphism over lists in the introduction of Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire by Erik Meijer et. al (link to postscript version).
[Test]
public void WhileLoopToRec()
{

Func<int, Result<Foo, int>> gen = n => new Result<Foo, int>(new Foo(), n + 1);
Func<int, bool> expr = a => a < 10;

var xs = CreateTUntilUsingRec(gen, 0, expr);

Assert.AreEqual(10, xs.Count());
}

private IEnumerable<T> CreateTUntilUsingRec<T,A>
(Func<A, Result<T, A>> gen, A init, Func<A, bool> expr)
{

if (!expr.Invoke(init))
return new List<T>();

var result = gen.Invoke(init);

return (new List<T> {result.Value})
.Concat(CreateTUntilUsingRec(gen, result.Accumulator, expr));

}

Abstracting away from bool

It seems that the only thing left to do is to abstract away the dependency on “bool” in CreateTUsingRec, but then we bump into a small problem,as you will see. What we do is to join the two lambdas into one and performing a null check inside the recursive function.
[Test]
public void MergeOnceMore()
{
int? i = 0;
Func<int, Result<int?, int>> gen = n => new Result<int?, int>(n < 10 ? i : null, n + 1);

var xs = CreateTUntilUsingRecNullCheck(gen, 0);

Assert.AreEqual(10, xs.Count());
}

private IEnumerable<T> CreateTUntilUsingRecNullCheck<T, A>
(Func<A, Result<T, A>> gen, A init)
{

var result = gen.Invoke(init);
if (result.Value == null)
return new List<T>();

return (new List<T> { result.Value })
.Concat(CreateTUntilUsingRecNullCheck(gen, result.Accumulator));

}

Writing it in F# instead

The problem with this solution is that we have lost the ability to generate ordinary non-nullable structs and that’s bad! We could easily solve the problem with writing our own MyNullable<T> which would  allow both classes and structs as instantiators of the type variable, but instead of doing that, I’ll show you something similar: the option type in F#.
let rec anamorphism n f = 
match f n with
| option.None -> []
| option.Some (e,next) -> e::(anamorphism next f)

> anamorphism 0 (fun a -> if a < 5 then option.Some("Bar" + a.ToString(), a + 1) else option.None);;
val it : string list = ["Bar0"; "Bar1"; "Bar2"; "Bar3"; "Bar4"]
Here, we removed the Result class and used a pair instead, together with the Option type, which is essentially the same as Nullable<T>, but without the restriction on type.

Conclusion

Functional programming is perhaps more abstract than imperative programming, but it is also seems to be more general, at least in this case. This post has only showed an anamorphism over lists, which is the simple case. Look here if you want to see a more advanced example.
Posted in Uncategorized | 1 Comment

Fluent language in FsStory

A nice feature for a story runner is to be able to provide arguments in a story sentence, like this:

ATableWithNumberOfLegs 4

This example is not hard to understand, but there’s some mental translation going on, since the order of the words is all screwed up. Let’s try another one:

TheNumberOfLegsOfATableIs 4

Better, but still not good. First, it’s longer than the previous example. Second, even if the grammar is correct, the word order is, well, unusual.. 😉

What about this?

ATableWith 4 Legs

Now we’re talking!

Here’s a bigger and more complete example:

[<Fact>]
let tableLegsScenario =
given (ATableWith 4 Legs)
|> whens (ICutOf 1 Leg)
|> thens (ItHasOnly 3 LegsLeft)

Note: As far as I know, RSpec/Cucumber is the only story runner(s) that is able to use variables inside a story sentence.

The nice thing about this is that I didn’t have to change FsStory itself to make it work. Not a single line. So, what’s the trick?

If you split up a story sentence like this, you have to prepare the step definition code (the behind-the-scenes code) in a certain way:

let ATableWith = fun n _ -> … do something here …

..or if you prefer, without a lambda:

let ATableWith n _ = … do something here …

Then you have to define Legs:

let Legs = id

As you see, in this case, it was just a matter of discovering the usage, rather than implementing it in the language. Honestly, I had no idea of this usage when I started to write on FsStory. This is clearly one of the reasons why I like internal DSLs!

Exercise: How would you implement the step definition for the following story sentence?

given (ATableWith 4 LegsAnd 2 Chairs)

Cheers!

Posted in bdd, F#, FsStory | Leave a comment

ImpossibleEstimation and Pomodoro Technique

Sometimes when using Pomodoro Technique I find it real difficult to estimate how long a particular activity will take, i.e., when locating a bug or find out why the webserver won’t read my files.

In Pomodoro Technique, every activity should have a time estimate – how many Pomodori I think it will take. Though, this is sometimes impossible! “The problem is solved when I find the bug and since I don’t know what the bug is related to, it’s impossible to say how much time it will take to find it.”

The solution: instead of just writing a number besides the activity, I use the less-than sign (<) before the number, indicating that I have a time-box for the activity, but that it might take less time. If I'm not done when the time-box is over, I have to ask a colleague to help me or ask my boss for extra resources – thus, escalating my problem. Then, I'm forced to have collected some data of the problem to help them to help me. The nice thing is that I still can have most of the benefits Pomodoro Technique gives me, i.e., increased focus when in a Pomodoro and possibility to get "the whole picture" during my breaks. The latter have proved to be an extra nice thing to have during hard problem-solving.

And, if a colleague comes to the rescue, we can construct another time-box, to know when to escalate it further, or at least to notify the team or the boss that we have some nasty problems at hand.

Yet, if I’m collecting metrics of my estimation skills, it is not a very good idea to track data for these bug-fixing Pomodori estimates. Put a “N/A” or a “-” in your records sheet and think for yourself: “Today was an exception, tomorrow will be a bug-free day.” And don’t forget to do your daily mind-map before you leave for home.

Posted in Uncategorized | 1 Comment

[Announce] FsStory, executable stories in F#

Since Claudio Perrone’s talk on Øredev, I have been thinking about what his MisBehave would look like in F#. In his talk, Claudio also mentioned Cucumber, a story runner written in Ruby. My plan was to make a lightweight DSL for writing stories in F# code, with the story parts separated from the implementation parts.

Currently, FsStory enables the developer to write user story scenarios (in Given/When/Then form) in F# code, like this:

#light

open FsStoryRunner
open MutatedTurtleMovesImpl
open Xunit

(*
In order to impress my friends
As a .NET programmer
I want to draw funny fractal pictures
*)

[<fact>]
let MoveTurtleToPosition() =
given ATurtle
|> andGiven IsRotated90DegreesToTheRight
|> whens (TurtleWalksSteps 9)
|> thens (TurtleIsLocatedAt (0,9))
|> endStory

Did you notice [<fact>] attribute just before the function definition? It is a xUnit.net specific attribute, telling xUnit.net that the function is a runnable test. So, why xUnit.net? Answer: xUnit.net is the currently the only test framework that runs static test methods, which is what F# functions compiles to.

Note: If you think that the story above is too low level to be a “good” user story, you’re right, but it’s just an example..

The “ATurtle”, “IsRotated90DegreesToTheRight”, “TurtleWalksSteps”, etc, are functions that you have to implement yourself. What these functions do is not FsStory’s business, except that they have the same type. It’s a good thing to think about this in advance.

If you’re testing something object oriented, i.e. a C# project, then you’re probably have to let the functions have the type () -> (). That is, they take no argument and return void, in C# lingo. You’d also need a mutable variable to accomplish this.

#light

open Turtle
open FsxUnit.Syntax

let mutable turtle = new Turtle() // turtle must have type Turtle

let ATurtle () = turtle <- new Turtle() // For reuse in same story let MovesOneStepForward () = turtle.Go() let IsMovedOneStepForward () = turtle.Position.X |> should equal 1 let RotationIs angle () = turtle.Direction |> should equal 0.0

It’s up to the developer what library she wants to use for her assertions. In this example, FsTest was used, but she could go for NUnit or NBehave or something else. I hadn’t actually tried this and do not longer think this will work. Either use xUnit.net or FsTest (which is based on xUnit.net).

Another style is to work with immutable objects. One example of immutable objects are value objects, in DDD. Immutable objects correspond well to functional programming principles. Here is an example of an implementation of a scenario when an immutable object is used in the SUT (System Under Test).

let ATurtle () = new TurtleImmutable()
let IsRotated90DegreesToTheRight = fun (turtle : TurtleImmutable) -> turtle.Left()
let TurtleWalksSteps steps = fun (turtle : TurtleImmutable) -> turtle.GoSteps(steps)
let TurtleIsLocatedAt (x,y) = fun (turtle : TurtleImmutable) -> turtle.Position |>
should equal (new Position(x,y)) ; turtle

To clarify, all methods on the (immutable) turtle return a new turtle and that turtle is returned and then passed in as an argument to the next test function (by FsStory). As you might have spotted, the example uses a lambda, an anonymous functions (the “fun”) instead of specifying an argument explicitly. It’s a good thing to get a running story before actually implementing the logic and assertions. Using the function “id” (just returning the argument) on the right-hand side is very helpful for getting everything to run.

You can find FsStory at http://www.codeplex.com/fsstory.

Posted in bdd, F#, FsStory | Leave a comment