C# as seen by languages with Type Inference…

via @HamletDRC

tumblr_kvdv7l891W1qz9bgeo1_400[1]

 

Ever since I started playing around with Boo this is exactly how I feel about declaring types for my variables…

C#

IFoo foo = (IFoo)Fetch(arg);

 

Boo

foo = Fetch(arg) as IFoo

 

IFoo only ever needs to be written once on any given line. And if Fetch returned IFoo it wouldn’t need to be written at all. Being explicit is great and all, but being redundant is absolutely not.

DSLs in Boo – Tech Review

The book DSLs in Boo: Domain-Specific Languages in .NET written by Oren Eini writing as Ayende Rahien has finally shipped. The final version is available online at Manning Press and I highly recommend it.

I was one of the technical reviewers so I have already read this book and I can tell you first hand it’s definitely one for your book shelf. The first few chapters describe the generalities of DSLs and Boo then the subsequent chapters describe all of the details you might need to know to implement an internal DSL in your application.

If you’ve been wondering about the whole DSL thing, this book would be a good gateway to the world. It’ll stretch your brain and certainly expose you to some new ideas. In addition the author makes a good case for some practical business applications and introduces a new addition to the open source scene: Rhino DSL.

I also got an honorable mention in the acknowledgments section of the book and a special quote on the Manning Press web site that’s pretty cool! Check out it out!

The Illusion of Strongly Typed XML with C#

This is essentially a redo of an earlier blog post of mine on how to create the illusion of a strongly typed xml in Boo using Duck Typing, except this time we’re using the dynamic keyword in C#.

http://cid-dfcd2d88d3fe101c.skydrive.live.com/embedrowdetail.aspx/blog/justnbusiness/XmlBuilder.cs

Here is an example of how it might look to use such a thing.

dynamic builder = new XmlBuilder();
builder.Main.One = "Hello";
builder.Main.Two = "World";

Console.WriteLine(builder.ToString());

Console.WriteLine(
    "{0} {1}!",
    builder.Main.One,
    builder.Main.Two);

builder = new XmlBuilder();
builder.Main["One"] = "Hello";
builder.Main["Two"] = "World";

Console.WriteLine(builder.ToString());

Console.WriteLine(
    "{0} {1}!",
    builder.Main["One"],
    builder.Main["Two"]);

XmlBuilder is a class I created myself, it inherits from DynamicObject and it intercepts TryGetMember, TrySetMember, TryGetIndex and TrySetIndex in order to allow you to navigate an internal XmlDocument object. Here is the output when the above is run.

<Main><One>Hello</One><Two>World</Two></Main>
Hello World!
<Main One=”Hello” Two=”World” />
Hello World!

Notice the use of properties corresponds to drilling into elements and the use of indexers corresponds to drilling into Attributes. This is just a proof of concept but you could see how this sort of thing would be useful.

Here is the complete XmlBuilder class that makes it all happen.

public class XmlBuilder : DynamicObject
{
    private Func<string, XmlElement> createElement;
    private Func<string, XmlAttribute> createAttribute;
    private XmlNode node;

    public XmlBuilder()
    {
        this.node = new XmlDocument();
        this.createElement = s => ((XmlDocument)this.node).CreateElement(s);
        this.createAttribute = s => ((XmlDocument)this.node).CreateAttribute(s);
    }

    private XmlBuilder(
        XmlNode node, 
        Func<string, XmlElement> createElement, 
        Func<string, XmlAttribute> createAttribute)
    {
        this.node = node;
        this.createElement = createElement;
        this.createAttribute = createAttribute;
    }

    public override bool  TryGetMember(GetMemberBinder binder, out object result)
    {
        XmlNode found = this.node[binder.Name];
        if (found == null)
        {
            found = this.createElement(binder.Name);
            this.node.AppendChild(found);
        }

        result = new XmlBuilder(found, this.createElement, this.createAttribute);
        return true;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        XmlNode found = this.node[binder.Name];
        if (found == null)
        {
            found = this.createElement(binder.Name);
            this.node.AppendChild(found);
        }

        found.InnerText = value.ToString();
        return true;
    }

    public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
    {
        if (indexes.Length != 1)
        {
            throw new InvalidOperationException("You may only specify a single index.");
        }

        XmlNode found = null;
        if (indexes[0] is string)
        {
            string name = (string)indexes[0];
            found = this.node.Attributes[name];
            if (found == null)
            {
                found = this.createElement(name);
                this.node.AppendChild(found);
            }
        }
        else if (indexes[0] is int)
        {
            int index = (int)indexes[0];
            found = this.node.Attributes[index];
        }

        if (found != null)
        {
            result = new XmlBuilder(found, this.createElement, this.createAttribute);
            return true;
        }
        else
        {
            result = null;
            return false;
        }
    }

    public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
    {
        if (indexes.Length != 1)
        {
            throw new InvalidOperationException("You may only specify a single index.");
        }

        XmlAttribute found = null;
        if (indexes[0] is string)
        {
            string name = (string)indexes[0];
            found = this.node.Attributes[name];
            if (found == null)
            {
                found = this.createAttribute(name);
                this.node.Attributes.Append(found);
            }
        }
        else if (indexes[0] is int)
        {
            int index = (int)indexes[0];
            found = this.node.Attributes[index];
        }

        if (found != null)
        {
            found.InnerText = value.ToString();
            return true;
        }
        else
        {
            return false;
        }
    }

    public override string ToString()
    {
        return this.node.InnerXml;
    }
}

Featured on techcareertips.com

Tavis Hudson is a Tech Headhunter who first recruited me in 2005 to work for Magenic. Over the years we have kept in contact and run into each other at a few events here and there. Recently, Tavis contacted me about doing an over the phone interview (as in journalism not recruiting) for his blog.

In the first of a series of blog posts he is authoring called “Prodigy Developers” he did a write up based on the conversation we had. I’ll try not to let that title go to my head but thanks for the vote of confidence Tavis.

One of the things he touches on in his post is something that I’d like to elaborate on a little more. This is something I consciously say to myself from time to time:

One thing that I have learned in college and in my career so far is that there are lots of people who are smarter than me. I mean downright geniuses. I am not a genius. I am constantly awed by these people and their mathematical abilities or their ability to grasp incredibly complex topics or the speed with which they are able to get to conclusions. This is not my strong point even though I am not an idiot by any means. Yet somehow, in a field generally regarded as primarily mathematical, I seem to thrive. It’s not to say that intelligence is overrated but I think that passion and dedication are, perhaps, underrated.

Sometimes I like to say that I’m an artist who can’t paint. I know that sounds corny but what I’m trying to say is just that I have to rely more on my creative side than my intellectual side when programming. I’m more of a right brainer than a left brainer, if that makes sense. Maybe more people than I realize would be able to associate with this notion but I feel like this is what has helped me more than anything, not that it’s more important but maybe that it’s rare.

Sorry, enough self congratulation and introspection. Head on over and read Prodigy Developers – Justin Chase, by Tavis Hudson.

Out with Code Generation and in with Transformation

As I’ve been playing around with DSLs for the past couple of years I’ve been focused on Code Generation as my primary strategy. This is all well and good and I think that code generation still servers its purpose in the greater world of DSLs but it’s not quite good enough. I would like to start using the word Transformation as more generalized form of code generation and manipulation. What I used to refer to as Code Generation I will now simply call Textual Transformation. The other main form of Transformation is an AST Transformation. The Groovy folks have also adopted this to be synonymous with Compile-time Meta Programming and the Boo folks would call this a Syntactic Macro.

In order to promote the DRY principle and really allow N levels of arbitrary transformations I’ve been busy changing MetaSharp to adopt the Pipelinepattern for the compilation process (according to that wikipedia article what I have now is more of a psued-pipeline though, since each step is done synchronously). The end result is pretty simple actually.

image

The Pipeline has a series of steps and a collection of services. Each step depends on certain services and may alter / create certain services. In this way each step can be completely re-usable for different compilation scenarios. For example the MetaCompilePipeline has three steps:

  1. MetaSharpCompileStep
  2. CodeDomTransformStep
  3. CodeDomCodeGenerateStep

Which is to say, if you want to compile MetaSharp code inside of a project of a different language your pipeline needs to perform those three steps. First compile the code into MetaSharp AST nodes. Second transform those nodes into CodeDom objects. Third use a CodeDomProvider to generate code based on those CodeDom objects. The MetaTemplatePipeline is the same as the above with one extra step at the beginning, for transforming the code into something else.

The point here though, is that key to this whole process is the idea of Transformation. In fact the whole theory behind MetaSharp is simply to be a transformation tool. Each step is simply transforming the results of the previous step into something else. This is powerful because your DSL can consist of arbitrary levels of transformation, litterally your DSL could transform into a lower level DSL, which transforms into an even lower level DSL, etc. all the way down to machine code.

Transformation isn’t a new concept it’s, been around forever. At the very root of any software is essentially a bunch of 1’s and 0’s but we haven’t written raw 1’s and 0’s as our software for a long time. The compiler has always been a way for us to transform slightly more complex concepts into lower level ones. Even the extremely low level machine code is a step above raw 1’s and 0’s. General purpose programming languages themselves consist of constructs used to transform into much more verbose machine code or IL.

Taking transformation to the next level of abstraction is necessary for us to effectively create DSLs. If there was a tool to help us easily perform those transformations then it would go a long way towards making external DSL authoring more realistic, which is what I’m hoping to do with MetaSharp.

So to me, at this point, Code Generation is just another form of Transformation, which I will be calling “Textual Transformation” from now on. It has its pros and cons, of which I hope to discuss further in other posts. However, my point today is simply to convey the idea of Transformation as more general and more important to the DSL world than simply Code Generation and also to consciously force myself to update my lexicon.

CodeCamp Evaluation Results

Rating Avg: 7.7

I had a few good comments and a few negative ones. One person said “A bit shallow” and another person said “This went very deep”, so it can be a little hard to take something away from that. Maybe I’ll try to respond to various comments directly.

5, Could’ve been slightly better prepared, perhaps with more demos.

I agree with this, this commenter is probably specifically talking about the Ruby portion of the presentation. I want to apologize to Rubyists for not having a more solid demo there but Mike Frawley helped me show something at least and talk about it. Better than nothing at least :-/

9, This went very deep. I enjoyed the intro to BOO as well. I would have liked to seen at least one concrete example of how to do this with C# using extension methods.

I was thinking about showing a RhinoMocks example. That would have been better than just the simple elevator app samples. If you made this comment check out RhinoMocks or the Umbrella project for good examples of extension method driven APIs in C#.

5, A bit shallow – I wanted to hear more about M and Oslo

I wonder if this person came to the presentation expecting more M and Oslo? Or just saw me talk about it a little bit at the end and wanted to hear more. To be honest, I don’t know a lot about M or Oslo (except conceptually) but I know a lot about MGrammar (which is distinctly different). I’d love to do another presentation on that I think. Trying to hit that depth where its interesting for everyone isn’t easy I guess.

7, I dint had much background information

Well hopefully some of my general overviews of different kinds of DSLs and ways to use them helped you come away with a little something at least.

10, Very concise.  Now I know what a DSL is and why I should care.  Great examples, followed through with the same example through different DSL’s. Interesting points about AST injection and making cross cutting concerns easier to decipher.  Topped it off with an excellent grand finale.  Good job.

Thanks! I have to admit the Grand Finale was pretty sweet. For those of you not there I played my enhanced Song demo using MetaSharp, which was modified to play the Super Mario Brothers Theme Song using Console.Beep. Unfortunately I ran out of time to really dive into the workings of this more but next time MetaSharp might make an interesting presentation in and of itself.

6, Very general topic, hard to figure out how to apply what I learned.

Well that’s actually a big bummer. I might have focused on Boo more than some people would have liked specifically so I could have something concrete that people could take away. I hope this commenter isn’t dismissing Boo because that is what I was hoping, if anything, people could use to apply DSLs here and now. So if you’re still not sure how to apply your newfound DSL knowledge go try Boo!