Friday, July 06, 2007
Well I've had a highly unproductive afternoon scrambling to rebuild my development PC after the RAID 5 decided to kill itself off... at first the pc reported one disk had fallen out of the raid... I brought it back in, rebooted, the machine started rebuilding the array then rebooted itself.. at which point it declared each disk was a member of different array... stuffed around with it for about an hour and contemplated throwing a 750gig drive in and doing a software-based recovery... but considering last time I did something like that it took a number of days to complete, I decided to just heave a large sigh, break the array up into individual disks and re-install (without RAID-5 this time...). 

Thankfully between svn, google apps (gmail for domains, google reader) and del.icio.us I don't think a lot has slipped through the gaps, barring the odd bit of skype history.

Guess I know what I'll be doing this weekend.  bleh!

posted @ Friday, July 06, 2007 3:07:22 AM (New Zealand Standard Time, UTC+12:00)    Comments [4] | Trackback |
 Thursday, July 05, 2007

So I see both Andrew, Nick and Alex J have some thoughts on languages, and of course Rowans post sparked it off... and people talk about beautiful languages, mentioning expressiveness in the same breath. 

Personally I love how expressive Ruby is - I think potentially because I got my first exposure to ruby after reading Why's poignant guide a while back (I see there are new chapters ...oooh) which was quite surreal compared to how I say learnt C++ (from reading the Borland Turbo C++ manual when I was 11, also my first exposure to OOP)...

When I code in ruby I feel like I'm telling stories... I dig that :)

So Alex J mentioned that extension methods let us achieve much of the syntactic sugar that ruby provides (though obviously in ruby's case this isn't so much syntactic sugar as core mechanisms in the language itself) - and of course Lambda expressions are helping too, but does expressive == good 100% of the time?   I don't think I'm qualified to say, but I can't help but feel that a language which is very expressive, isn't necessarily the easiest to manipulate and refactor, so I may not be as productive and it may not feel as fluent to me... I quite liked this resharper horizons post which suggests that tooling support should probably influence future language design - could that requirement possibly fight against an increased level of expressiveness in a language, will compromises need to made, or is nirvana just around the corner?

As for C# vs VB.Net - large clumsy keywords are only a probablem until something like Resharper steps in... when I'm developing I see a lot of unusued space on the right hand side of the editor with C#... if VB.Net fills it up, and I'm not typing any harder to get there, why should I care - hell it'll probably make a VB.Net Resharper Jedi look more impressive then the C# equivalent, he'll be producing more characters ;o)

OK, well I figured this post should at least have some code... I'd feel uneasy otherwise... so how about:

public static class CommonExtensions
{
    public static Action<Action<int>> LoopTo(this int start, int end)
    {
        return new Action<Action<int>>(action => To(start, end).ForEach(i => action(i)));
    }
 
    public static IEnumerable<int> To(this int start, int end)
    {
        if (end < start)
            for (int i = start; i > end - 1; i--)
                yield return i;
        else
            for (int i = start; i < end + 1; i++)
                yield return i;   
    }
 
    public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
    {
        foreach (T item in sequence) action(item);
    }
 
    public static void PrintLine(this object o)
    {
        Console.WriteLine(o);
    }
}


So now we could try and do this....

// ruby
(10..20).each { |i| puts i }

// C#
10.LoopTo(20) ( i => i.PrintLine() );


Alas I don't think C# will ever match ruby in this game, no matter how we try to nudge it there... and until the development community figures out where the healthy place is to draw the line in the attempt, we may be doing more harm then good by pushing for it, sacrificing discoverability/maintainability for expressiveness.   Maybe that's just dogma, and expressiveness makes code inherently easier to maintain in the first place, so we don't need to care.... time will tell.

Of course I could be wrong, I am a little sleepy ;o)
posted @ Wednesday, July 04, 2007 12:03:27 PM (New Zealand Standard Time, UTC+12:00)    Comments [0] | Trackback |
 Wednesday, July 04, 2007

So Catch Ltd (one of DevDefined's partners) turned 3 today, and there was a few birthday celebrations  this evening.  Not only was it an opportunity for me to establish my supremacy in the role of worst ten pin bowler, but it was I think one of the first times the entire Catch team actually got to the meet each other - considering the type of work Catch does (providing QA, BA & PM resources primarily, generally on-site) it's actually pretty rare for everyone to be in one place at the same time!

It's been great to watch a company that started off effectively with just the Managing Director Bryce Day 3 years ago reach a size where you can't even fit all the employees into a meeting room any more, with new roles being created on an almost weekly basis, exciting times ahead for Catch I would say!

Great work Bryce, and all the Catch Staff - keep up the great work!

And for anyone looking for a company which can provide highly skilled and talented PM, BA or QA resources or end-to-end software development leveraging the skill sets in both Catch Limited and DevDefined then why not drop Catch an email?

posted @ Wednesday, July 04, 2007 10:52:23 AM (New Zealand Standard Time, UTC+12:00)    Comments [0] | Trackback |
 Tuesday, July 03, 2007

So I've tidied up the source for the DSL from my last post a little... though my "test" was to represent a DSL similar to the one Ayende displayed in Brail - I haven't implemented any monorail view engine integration, there's little point I feel, I was more interested in being able to display a nested DSL-like syntax, and parse the necessary information out of it as required. 

You can grab it from SVN repository here (edit: I've now fix the PROPFIND proxy issue, so the link should work)

At any rate, probably the most interesting example is the one that takes this code:

var people = new List<Person>()
{
    new Person() { FirstName = "Alex", LastName = "Henderson"},
    new Person() { FirstName = "Joe", LastName = "Bloggs"}
};
 
var compDsl = new ComponentDsl();
 
compDsl.Add
(
    GridComponent => compDsl.Component
    (
        compDsl.Parameters
        (
            source => people
        ),
        header => compDsl.Section
        (
            tr => compDsl.As
            (
                th => compDsl.As
                (
                    compDsl.Text("Names")
                )
            )
        ),
        item => compDsl.Section
        (
            tr => compDsl.As
            (
                td => compDsl.As
                (
                    compDsl.Item<Person>(p => p.FirstName + " " + p.LastName)
                )
            )
        )
    )
);
 
var dsl = new StandardDsl();
 
dsl.Add
(
    html => dsl.As
    (
        body => compDsl
    )
);

And converts it to this xhtml...

<html>
  <body>
    <table>
      <tr>
        <th>Names</th>
      </tr>
      <tr>
        <td>Alex Henderson</td>
      </tr>
      <tr>
        <td>Joe Bloggs</td>
      </tr>
    </table>
  </body>
</html>

You can pretty quickly figure out what's going on by placing a breakpoint on the Execute() method of the StandardDsl class and tracing through all the calls - in essence all the nodes are emitted by calling the top-level Batch delegate which causes a recursive call down the "tree", with the information being emitted as a side-effect to an evaluation scope.

Though I used nodes - effectively creating a structure that's easier to parse, there's no reason why you couldn't make immediate calls to some kind of object, avoiding the need for a second round of parsing - the only trick is that you'd still need to use some kind of scoped stack to push/pop the names of the components because in a statement like this:

dsl.As
(
    GridComponent => dsl.Component
    (
      // etc. etc.
    )  
)


the call to dsl.Component needs some way to inspect the stack of names and pull "GridComponent" off the top.

I'd love to hear from anyone who could see a use for this kind of thing... it'd be nice to get a more realistic example... I'm struggling to think of anything practical myself.

[Edit: I Noticed the code formatting was pretty awful, so I've tidied it up a little... anyone got a good solution for copy/pasting code out of orcas (CopyAsHtml2005 doesn't appear to install under Orcas)]
 |  | 
posted @ Tuesday, July 03, 2007 11:01:26 AM (New Zealand Standard Time, UTC+12:00)    Comments [2] | Trackback |
 Friday, June 29, 2007

Following on from my posts on creating hashes (dictionaries) using lambdas (here, and here) and the little annotations "framework" I produced (here and here) which leverage the idea for annotating classes via extension methods... I've decided to turn my hand to creating a DSL using lambdas, on my continuing theme of C# 3.0 lambda abuse.

So first off... go have a look at Ayende's post DSL Support for brail ... that'll give you an idea of kinda what I'm trying to achieve.... so, here's an example of a simple DSL for building say a html table.

var dsl = new StandardDsl();

dsl.Add(
table => dsl.As(
  tr => dsl.As(
    td => dsl.Text(
"header1"
),
    td => dsl.Text(
"header2"
))));

Console
.WriteLine(DslToXml.ToXml(dsl));

which gives an output of:

<table><tr><td>header1</td><td>header2</td></tr></table>

Depending on taste you could lay it out differently, avoiding the mess of closing parentheses at the end of the Add call, say like:

var dsl = new StandardDsl();

dsl.Add
(
  table => dsl.As
  (
    tr => dsl.As
    (
      td => dsl.Text(
"header1"
),
      td => dsl.Text(
"header2"
)
    )
  )
);

Which is pretty easy on the eyes... now what about something a little more domain specific like the view component example Ayende gave for monorail... well here's my take on that, so say we have some people:

var people = new List<Person>()
{
 
new Person() { FirstName = "Alex", LastName = "Henderson"
},
 
new Person() { FirstName = "Joe", LastName = "Bloggs"
}
};

And we have a DSL specific to components...

var compDsl = new ComponentDsl();

compDsl.Add
(
  GridComponent => compDsl.As
  (
    compDsl.Component(source => people),
    header => compDsl.Section
    (
      tr => compDsl.As
      (
        th => compDsl.As
        (
          compDsl.Text(
"Names")
        )
      )
   
),
    item => compDsl.Section
    (
      tr => compDsl.As
      (
        td => compDsl.As
        (
          compDsl.Item<
Person>(p => p.FirstName + " "
+ p.LastName)
        )
      )
    )
  )
);

And now we could do this in-line with a bigger DSL for say a whole view, but we can also just reference them so I could do something like this to create the overall view:

var dsl = new StandardDsl();

dsl.Add
(
  html => dsl.As
  (
    body => compDsl
  )
);

Now once I've tidied the code up a bit I'll probably put it up for people to have a play with - I don't necessarily consider a "good idea" - but it's cute.  However for now let's have a quick look at how I'm doing it...

So to start with we have a delegate called "Batch" with the signature below - batch probably isn't the right name for this, I'm not really sure it matters all that much.

public delegate Batch[] Batch(Batch batch);

Batch takes a Batch and returns an array of Batch ;o) and to match that we then have say the "As" method on the DSL:

public Batch[] As(params Batch[] batches)
{
  Batch asBatch = new Batch(delegate(Batch
ignore)
  {
    ExecuteBatches(batches);
   
return null
;
  });
 
  IgnoreBatch(asBatch);

  return new Batch[] { asBatch };
}

Notice it takes one or more Batch instances, and returns a delegate which executes the batches, ignores the batch we just generated and returning the one Batch as an array... conforming to the expected return type of the Batch delegate.  Clear as mud? ;o)

Ignoring the batches actually just uses the annotation framework, so IgnoreBatch looks like this:

public void IgnoreBatch(Batch batch)
{
  batch.Annotate(Ignore =>
true
);
}

And then we check if a batch is ignored before processing it down the line by calling this method.

public bool IsBatchIgnored(Batch batch)
{
 
return batch.HasAnnotation("Ignore"
);
}

Last of all to actually "render" the DSL into some useful format we execute it (no Expression<>'s required, so it's very fast) ... which just call the top with null, which in turn calls the arguments, and those arguments arguments etc.  While doing that we write nodes (much like an Xml writer) against an "evaluation" scope, which associates a NodeWriter with the current thread.... basically the DSL ends up as a bunch of calls like:

NodeWriter writer = new NodeWriter();
writer.WriteStartNode(
new NamedNode("table"
))
  .WriteStartNode(
new NamedNode("tr"
))
    .WriteStartNode(
new NamedNode("td"
))
      .WriteNode(
new TextNode("column1"
))
    .WriteEndNode()
  .WriteEndNode()
.WriteEndNode();

where the nodes conform to this interface:

public interface INode
{
 
INode Parent { get; set
; }
 
List<INode> Nodes { get
; }
}


At which point it's trivial to walk the tree of INode's and do whatever you like with the information stored within it, and we can encapsulate new concepts by creating new types of node, which have payloads of additional information.

At any rate, next time I'll post a little more about how I'm doing it, and attach the code for people to have a play with.

 |  | 
posted @ Friday, June 29, 2007 10:12:23 AM (New Zealand Standard Time, UTC+12:00)    Comments [2] | Trackback |
No so much for my future reference, but to refer people too should the topic of how generic types are represented by name ever crops up again.

Type FullName
typeof (List<>).FullName System.Collections.Generic.List`1
typeof(List<int>).FullName System.Collections.Generic.List`1[[System.Int32]]
typeof(Dictionary<,>).FullName System.Collections.Generic.Dictionary`2
typeof(Dictionary<string,int>).FullName System.Collections.Generic.Dictionary`2[[System.String],[System.Int32]]
typeof(Dictionary<string,List<int>>).FullName System.Collections.Generic.Dictionary`2[[System.String],[System.Collections.Generic.List`1[[System.Int32]]]]
posted @ Friday, June 29, 2007 4:47:25 AM (New Zealand Standard Time, UTC+12:00)    Comments [2] | Trackback |
 Monday, June 18, 2007

mushrooms.jpg

My aging dasBlog install got hacked last night some time... by the turks ;o) all back up and running again now, upgraded to dasBlog 1.9 as well... might migrate to a different blog platform at some point (either Subtext, or I might give nBlogr a whirl because I know the technology stack it sits on reasonably well.

posted @ Monday, June 18, 2007 3:09:21 AM (New Zealand Standard Time, UTC+12:00)    Comments [2] | Trackback |
 Thursday, June 14, 2007
Here's the code for my last post on Annotations - I tidied up a few things up (it's still very basic but it does work) there's a single test fixture to give you a guide for usage... so things like:

[Test]
public void QueryStoreForClassAnnotationsWithCertainKey()
{
   
ClassA target1 = new ClassA();
    ClassA target2 = new ClassA();
    ClassA target3 = new ClassA();

    target1.Annotate(Description =>
"class number 1");
    target2.Annotate(Description => "class number 2");
    target3.Annotate(Parsed =>
true);

    var results = AnnotationStore.Classes
      .Where(a => a.HasKey(
"Description"))
      .ToList();

    Assert
.AreEqual(2, results.Count);
}

And also the equivalent thing is possible for members... though I suspect annotating members isn't all that useful in most cases...

[Test]
public void QueryStoreForMemberAnnotations()
{
    ClassA target1 = new ClassA();
    ClassA target2 = new ClassA();
    ClassA target3 = new ClassA();

    target1.Annotate(() => target1.FirstName, CamelCase => true); // annotating a property
    target1.Annotate(() => target1.Field, Ignored => true); // annotating a field
    target2.Annotate(() => target2.Execute(), Parsed => true); // annotating a method

    target3.Annotate(Parsed =>
true);

    var results = AnnotationStore.Members
      .Where(p => p.HasKey(
"CamelCase"))
      .ToList();

    Assert.AreEqual(1, results.Count);
}


 |  | 
posted @ Thursday, June 14, 2007 4:06:12 AM (New Zealand Standard Time, UTC+12:00)    Comments [1] | Trackback |
I've been under whelmed with GoogleGears & GoogleReader as a combination (though it has enabled search capabilities for the last 2000 posts to GoogleReader which is a god send)...

But what I was thinking of that would be particularly useful in offline mode, a wiki... I wonder if it'll ever happen?

posted @ Thursday, June 14, 2007 2:30:58 AM (New Zealand Standard Time, UTC+12:00)    Comments [0] | Trackback |

So I've been mulling some ideas over after the whole abusing lambdas for Hash table construction (here and here) ... and after reading a post on Jb Evain's blog I decided to create a little bit of code for doing annotations... so given a class say:

public class ClassA
{
    public int Id { get; set; }
    public string Name { get; set; }
}

You can then do this kind of thing (assuming you've added the apropriate namespace where the Annotations static class resides in)

[Test]
public void AnnotateClass()
{
    ClassA classA = new ClassA();
    classA.Annotate(IsValid =>
false);
    classA.Annotate(MapsToTable =>
"TblClassA", Key => "Id");
    classA.Annotate(Roles =>
new [] {"Administrator", "User"});

    Assert.IsFalse(classA.Annotation<bool>("IsValid"));
    Assert.AreEqual("TblClassA", classA.Annotation<string>("MapsToTable"));
    Assert.AreEqual("Id", classA.Annotation<string>("Key"));
}

Or, perhaps you want to attach some annotations to a specific property... no problem!

[Test]
public void AnnotateProperty()
{
    ClassA classA = new ClassA();
    classA.Annotate(() => classA.Name, CanBeNull =>
true);
    bool canBeNull = classA.Annotation<bool>(() => classA.Name, "CanBeNull");
    Assert.AreEqual(true, canBeNull);
}

Under the hood the values are stored against a dictionary where the keys (in this case the instance of classA) are weak referenced... so once classA is garbage collected the entries in the dictionary will also dissapear in time (next time any method touches the dictionary).

The nice thing is obviously you can directly interogate the Annotations static class itself with a query expression to say find all objects with a certain annotation.

 |  | 
posted @ Wednesday, June 13, 2007 10:32:16 PM (New Zealand Standard Time, UTC+12:00)    Comments [2] | Trackback |
Search
FeedCount

Tags...
Who am I?
Alex Henderson
Alex Henderson
Auckland, New Zealand
Managing Director at Dev|Defined Limited

"Self Confessed Coding Junky for 15 years"
View Alex Henderson's profile on LinkedIn
 
Mobile: +64-21-402-969
Email: bittercoder 'at' gmail 'dot' com
MSN: bittercoder_nz@hotmail
Skype: alex.devdefined
Navigation