# Friday, March 13, 2009

Another approach I'm investigating for HTML form generation is using VB's XML literals.

Check out this screencast for a demo: http://screencast.com/t/WSoDB4B9M2

 

XML literals + Expression Trees gives us some serious power!

.net | html | screencast | vb.net | web | xml
Friday, March 13, 2009 6:44:33 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, November 26, 2008

Now that the ASP.NET MVC API has settled down I decided to bring some of my ideas about REST and resource-oriented programming to it.

The following screencast shows my current prototype in action:
http://www.aboutcode.net/screencasts/snooze-aspnet-mvc.wmv

I'm keen for comments and feedback.

The source code is currently available via SVN here:
http://svn2.assembla.com/svn/snooze/branches/aspnet

.net | c# | mvc | REST | screencast | web
Wednesday, November 26, 2008 3:23:02 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Saturday, November 08, 2008

Correctly implementing structural equality involves a lot of code. My macro implements this for you.

Watch the Screencast

Before

using System;
using System.Console;
using Nemerle.Utility;
 
module Program
{
    [Record]
    public class Location
    {
        public Latitude : double;
        public Longitude : double;
 
        public override Equals(other : object) : bool
        {
            match (other)
            {
                | null => false
                | l is Location => l.Latitude == Latitude && l.Longitude == Longitude
                | _ => false;
            }
        }
 
        public override GetHashCode() : int
        {
            Latitude.GetHashCode() ^ Longitude.GetHashCode()
        }
 
        public static @==(l1 : Location, l2 : Location) : bool
        {
            def l1IsNull = object.ReferenceEquals(l1, null);
            def l2IsNull = object.ReferenceEquals(l2, null);
            match (l1IsNull, l2IsNull)
            {
                | (true, true) => true
                | (false, false) => l1.Equals(l2)
                | _ => false
            }
        }
 
        public static @!=(l1 : Location, l2 : Location) : bool
        {
            !(l1 == l2)
        }
    }
 
    module Program
    {
        Main() : void
        {
            def l1 = Location(30, 70);
            def l2 = Location(30, 70);
            def l3 = Location(40, 90);
 
            WriteLine("l1.Equals(l2) -> {0}", l1.Equals(l2));
            WriteLine("l1 == l2 -> {0}", l1 == l2);
            WriteLine("l1 != l2 -> {0}", l1 != l2);
            WriteLine("l1.GetHashCode() == l2.GetHashCode() -> {0}", l1.GetHashCode() == l2.GetHashCode());
            WriteLine("l1 != l3 -> {0}", l1 != l3);
 
            _ = ReadLine();
        }
    }
}

After

using System;
using System.Console;
using Nemerle.Utility;
using SampleMacros;
 
module Program
{
    [Record]
    [ImplementEquality(Latitude, Longitude)]
    public class Location
    {
        public Latitude : double;
        public Longitude : double;
    }
 
    module Program
    {
        Main() : void
        {
            def l1 = Location(30, 70);
            def l2 = Location(30, 70);
            def l3 = Location(40, 90);
 
            WriteLine("l1.Equals(l2) -> {0}", l1.Equals(l2));
            WriteLine("l1 == l2 -> {0}", l1 == l2);
            WriteLine("l1 != l2 -> {0}", l1 != l2);
            WriteLine("l1.GetHashCode() == l2.GetHashCode() -> {0}", l1.GetHashCode() == l2.GetHashCode());
            WriteLine("l1 != l3 -> {0}", l1 != l3);
 
            _ = ReadLine();
        }
    }
}

ImplementEquality.n

using Nemerle;
using Nemerle.Compiler;
using Nemerle.Compiler.Parsetree;
using Nemerle.Macros;
 
namespace SampleMacros
{
    [MacroUsage(MacroPhase.BeforeInheritance, MacroTargets.Class)] 
    public macro ImplementEquality(typeBuilder : TypeBuilder, params members : list[PExpr]) 
    { 
        ImplementEqualityModule.AddEqualsMethod(typeBuilder, members); 
        ImplementEqualityModule.AddEqualityOperator(typeBuilder); 
        ImplementEqualityModule.AddInequalityOperator(typeBuilder); 
    } 
 
 
    module ImplementEqualityModule 
    { 
        public AddEqualsMethod(typeBuilder : TypeBuilder, members : list[PExpr]) : void 
        { 
            def other = Macros.NewSymbol(); 
            def comparisons = members.Map(m => { 
                def s = Splicable.Name(Name(m.ToString())); 
                <[ (this.$s).Equals($(other : name).$s) ]> 
            }); 
 
 
            def b = comparisons.Tail.FoldLeft(comparisons.Head, (c, acc) => <[ $acc && $c ]>); 
            typeBuilder.Define(<[ decl: 
                public override Equals(obj : object) : bool 
                { 
                    match (obj) { 
                        | null => false 
                        | $(other : name) is $(typeBuilder.ParsedTypeName) => $b 
                        | _ => false 
                    } 
                } 
            ]>); 
 
 
            def hashCodes = members.Map(m => { def s = Splicable.Name(Name(m.ToString())); <[ this.$s.GetHashCode() ]> }); 
            def hashCode = hashCodes.Tail.FoldLeft(hashCodes.Head, (c, acc) => <[ $acc ^ $c ]>); 
            typeBuilder.Define(<[ decl: 
                public override GetHashCode() : int 
                { 
                    $hashCode 
                } 
            ]>); 
        } 
 
 
        public AddEqualityOperator(typeBuilder : TypeBuilder) : void 
        { 
            typeBuilder.Define(CreateEqualityOperator(typeBuilder.ParsedTypeName, false)); 
        } 
 
 
        public AddInequalityOperator(typeBuilder : TypeBuilder) : void 
        { 
            typeBuilder.Define(CreateEqualityOperator(typeBuilder.ParsedTypeName, true)); 
        } 
 
 
        CreateEqualityOperator(typeRef : PExpr, invert : bool) : ClassMember.Function 
        { 
            def op = Splicable.Name(Name(if (invert) "!=" else "==")); 
 
 
            <[ decl: 
                public static $op(p1 : $(typeRef), p2 : $(typeRef)) : bool 
                { 
                    def p1Null = object.ReferenceEquals(null, p1); 
                    def p2Null = object.ReferenceEquals(null, p2); 
                    match (p1Null, p2Null) { 
                        | (true, true) => true 
                        | (false, false) => $(if (invert) <[false == p1.Equals(p2)]> else <[p1.Equals(p2)]> ) 
                        | _ => false 
                    } 
                } 
            ]> 
        } 
    } 
 
 
 
}
Saturday, November 08, 2008 5:18:15 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [3]  | 

InheritConstructors is a handy macro when you need to simply pass all arguments to a base constructor.

Watch the Screencast 

Before

using System;

 

namespace MacrosDemo

{

    public class MyBaseClass

    {

        public this(name : string, foo : int, bar : bool)

        {

            _name = name;

            _foo = foo;

            _bar = bar;

        }

 

        _name : string;

        _foo : int;

        _bar : bool;

 

        public virtual Test() : string

        {

            "Hello from MyBaseClass"

        }

    }

 

    public class MySubClass : MyBaseClass

    {

        public this(name : string, foo : int, bar : bool)

        {

            base(name, foo, bar)

        }

 

        public override Test() : string

        {

            "Hello from MySubClass"

        }

    }

 

    module Program

    {

        Main() : void

        {

        }

    }

}

After

using System;

using Nemerle;

 

namespace MacrosDemo

{

    public class MyBaseClass

    {

        public this(name : string, foo : int, bar : bool)

        {

            _name = name;

            _foo = foo;

            _bar = bar;

        }

 

        _name : string;

        _foo : int;

        _bar : bool;

 

        public virtual Test() : string

        {

            "Hello from MyBaseClass"

        }

    }

 

    [InheritConstructors]

    public class MySubClass : MyBaseClass

    {

        public override Test() : string

        {

            "Hello from MySubClass"

        }

    }

 

    module Program

    {

        Main() : void

        {

        }

    }

}

Saturday, November 08, 2008 5:13:02 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 

The [Record] macro is applied to classes and makes it very easy to create simple data-transfer objects.

Watch the Screencast

Before

using System;

 

namespace MacrosDemo

{

    public class CustomerDto

    {

        public Id : int;

        public FirstName : string;

        public LastName : string;

        public IsPrefered : bool;

 

        public this(id : int, firstName : string, lastName : string, isPrefered : bool)

        {

            Id = id;

            FirstName = firstName;

            LastName = lastName;

            IsPrefered = isPrefered;

        }

    }

 

    module Program

    {

        Main() : void

        {

            def dto = CustomerDto(1, "John", "Smith", true);

        }

    }

}

 

After

using System;

using Nemerle.Utility;

 

namespace MacrosDemo

{

    [Record]

    public class CustomerDto

    {

        public Id : int;

        public FirstName : string;

        public LastName : string;

        public IsPrefered : bool;

    }

 

    module Program

    {

        Main() : void

        {

            def dto = CustomerDto(1, "John", "Smith", true);

        }

    }

}

 

Saturday, November 08, 2008 5:04:29 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, July 02, 2008

This is a very quick video showing the work I've been doing with Nemerle, ASP.NET routing and VB 9 XML literals.
I'm trying to find the most efficient way to create RESTful web applications. I'm willing to use all the tools in the box and even make my own to achieve this.

.net | nemerle | REST | screencast | vb.net
Wednesday, July 02, 2008 11:19:24 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Wednesday, October 17, 2007

My latest screencast is online: Mobile Model in MVP web app

This screencast continues from the work I demonstrated in a previous screencast: http://channel9.msdn.com/Showpost.aspx?postid=344711
When implemented a Model-View-Presenter pattern client-side in JavaScript there is a need to get data from the server. Rather than make this divide explicit with HTTP request, etc, I have used the idea of a model object that moves between the client and server.
So the programmer simply writes the client and server pieces of functionality and lets my framework do the plumbing.
I use code generation and Script# to make writing a client-side web app much more seemless than the usual javascript/XML/JSON/web service madness.
I'm developing the ideas shown here in a project at the moment. If there is sufficient interest I may extract a framework to give to the community.
How do people feel about this approach to web development? What kinds of additions/modifications should be made?
p.s. I have a bit of a cold at the moment, so sorry for the croaky voice in the recording!

.net | c# | mvp | programming | ria | screencast | tier_split | web
Wednesday, October 17, 2007 9:32:19 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [11]  | 
# Saturday, September 29, 2007

Check out my latest screencast over at Channel 9. It demonstrates how to implement a model-view-presenter architecture that runs client-side in a web browser. I am using Script# to compile a C# project into JavaScript.

.net | c# | mvp | programming | screencast
Saturday, September 29, 2007 5:08:52 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  | 
# Saturday, August 25, 2007

I recorded a screencast explaining my tier splitting tool for C#. It uses a Model-View-Presenter style application to demonstrate the features of the tool.

Check out the video (wmv format, 14.8 MB)

I'd love to get some feedback from people...

Saturday, August 25, 2007 5:18:50 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  |