Phillip Trelford's Array

POKE 36879,255

Software Architect 2009 Conference

For the last 2 days I’ve been attending the Software Architect 2009 conference located at the iconic Royal College of Physicians building opposite Regent's Park in central London. Overall the events have been interesting, that said, the content has not in general been particularly new or ground breaking, but that is probably the nature of the discipline. It has however been good to be reminded of key principles, to listen to the views of others, and as always I’ve found it quite thought provoking. For each talk I attended I’ve created an entry on Twitter @ptrelford:

Tim Ewald on Saving Software Architecture: "When you go too far up, abstraction-wise, you run out of oxygen" Joel on Architecture Astronauts

Kevin Seal on MorganDirect's client-side architecture: Swing app with Eclipse IDE look, blackboard pattern, detailed logs & takes screenshots

Kevlin Henney on Slicing design over time: take time estimate & half it, coding is performance art so practice, test cases are propositions.

Dave Wheeler on Coding a solid UI: "WPF is great", dependency properties are cool, do MVVM pattern, get an HCI expert & use Expression Blend

Richard Blewett on What's New in WF 4.0: Everything. Complete API rewrite. 3.5 favoured code based workflow. 4.0 declarative XAML is king.

Dino Esposito asks "How good are you at .NET software design?" Separation of concerns, OOD principles - prefer composition to inheritance etc

Kevlin Henney on Modelling in the age of agility: Most important aspect of modelling is the -ing, i.e. the social and collaborative aspects.

Simon Brown on "Documenting your software architecture - why and how?" Start with a context and set the scene. Put yourself in others shoes.

Most popular analogy: Construction (Tim Ewald & Kevlin Henney)

Favourite example: Fast-Track Construction of the Empire State Building (Kevlin Henney)

Best term usage: idempotent (Simon Brown)

Best vocabularly usage: pontificate (Kevlin Henney)

Only search term suggestion: Death by UML Fever (Kevlin Henney again)

C# Scripting

The .Net Framework ships with a C# code compiler that lets you generate in-memory assemblies. This can be used to run C# scripts without the need for the installation of a large application like PowerShell. The following code, which targets .Net 2.0, builds into a 7K executable, and is all that is needed to run C# source files from the command line:

using System;
using System.CodeDom.Compiler;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.CSharp;
using System.Collections.Generic;

static class Program
{
    /// <summary>
    /// Executes specified C# script file
    /// </summary>
    /// <param name="args">Path of C# script file</param>
    static void Main(string[] args)
    {
        // Check parameters
        if (args.Length == 0)
        {
            Console.WriteLine("Please specify a C# script file");
            Environment.Exit(-1);
        }
        // First parameter is source file path
        string path = args[0];
        // Check file exists 
        if (!File.Exists(path))
        {            
            Console.WriteLine("Specified file does not exist");            
            Environment.Exit(-1); 
        }
        // Read source from file
        string source = ReadFile(path);
        // Initialize compiler options
        CompilerParameters compilerParameters = 
            new CompilerParameters();      
        compilerParameters.GenerateExecutable = true;
        compilerParameters.GenerateInMemory = true;
        compilerParameters.TreatWarningsAsErrors = true;
        compilerParameters.CompilerOptions = "/nowarn:1633"; // unrecognized pragmas
        // Prepass source for #pragma reference statements        
        StringReader reader = new StringReader(source);       
        while (true)
        {
            string line = reader.ReadLine();
            if (line == null) break;            
            string pattern = 
                "\\s*#pragma\\s+reference\\s+\"(?<path>[^\"]*)\"\\s*";
            Match match = Regex.Match(line, pattern);                   
            if (match.Success)            
                compilerParameters.ReferencedAssemblies.Add
                    (match.Groups["path"].Value);            
        }
        // Specify .NET version
        Dictionary<string, string> providerOptions =
            new Dictionary<string, string>();
        providerOptions.Add("CompilerVersion", "v3.5");
        CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions); 
        // Compile source           
        CompilerResults results =
                provider.CompileAssemblyFromSource(
                    compilerParameters,
                    new string[] { source });
        // Show errors
        if (results.Errors.HasErrors)
        {
            Console.WriteLine("Errors Building " + path);
            foreach (var err in results.Errors)
                Console.WriteLine(err);
            Environment.Exit(-1);
        }
        // Extract argument tail
        string[] parameters = new string[args.Length - 1];
        Array.Copy(args, 1, parameters, 0, args.Length-1);
        // Invoke compiled assembly's entry point
        results.CompiledAssembly.EntryPoint.Invoke
            (null, new object[1] { parameters });        
    }
    
    private static string ReadFile(string path)
    {
        using (StreamReader reader = File.OpenText(path))
            return reader.ReadToEnd();
    }
}

 

Script files look just like Console applications:

using System;

public class Class1
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World");
    }
}

 

Finally additional assemblies can be referenced using #pragma directives:

#pragma warning disable 1633 // disable unrecognized pragma directive warning
#pragma reference "System.Windows.Forms.dll"

using System.Windows.Forms;

public class Class1
{
    static void Main(string[] args)
    {
        MessageBox.Show("Hello World");
    }
}

F# Units of Measure talk at Open Source eXchange III

The Open Source eXchange III was a mini-conference where members of the ALT.NET community talked about their favourite alternative .NET tools that increase programmer productivity. Units of Measure is a cool language feature in F#, developed by Andrew Kennedy, that lets you easily annotate values with units like metres, kilograms or seconds. Then F# type inference kicks in to give you automatic checking of your unit types at design and compile time, but cost you nothing at run time, e.g.

  let gravityOnEarth = 9.8f<m/s^2> // Acceleration

Following a bit of a Apollo 40th Anniversary theme, I presented 3 code samples (attached):

  • Statistics
  • Orbital Mechanics
  • Lunar Lander

Resources:

Further reading: