Logo




Subscribe:
RSS 2.0 | Atom 1.0
Categories:

Sign In


[Giagnocavo]Michael::Write()

# Saturday, August 30, 2008
F# CTP Comment Selection
I find myself using "Comment Selection" often as I hack up quick scripts. Before the F# CTP, doing "Comment Selection" (Ctrl-K, Ctrl-C) would simply add (* *) around the selection. This makes it hard to uncomment specific lines. Now it goes and adds // in front of each line. Small things like this, in aggregate, decide a great IDE. For as much as I dislike some C# language decisions, their code editor is the best of anything I've ever seen.

Oh yea, the IntelliSense is also now WAY better. What's still missing is the "always active autocomplete", although I suspect this is harder in F#'s #light syntax than in C#.

FSharp
Saturday, August 30, 2008 6:10:59 PM UTC  #    Comments [0]  |  Trackback

# Friday, August 29, 2008
No, really, the Event-based Asynchronous Pattern IS bad
Came across this:
http://michaelcurbanski.com/log/2008/08/29/functional-programmers-hate-events/

His main point is that async total sucks, but that "Events don’t necessarily make async code tragically unreadable!" As a demonstration, he shows some simple async HTTP code without full or exception continuations. His code just enforces my point.

At any rate, yes, sure, if your continuation code isn't too related to your calling code, events can work. I mentioned this in my post: "events are a bad choice for code that is not loosely coupled" followed with "sometimes a simple delegate field would be a better choice". Indeed, looking at Mike's sample code, it seems as if using a simple delegate field would allow some nice refactoring.

But a point of the Event-based Asynchronous Pattern is, and I quote, to "Wait for resources to become available without stopping ("hanging") your application". So basically, you want to take an existing method, say, in response to a user action, but you can't let it block. This is exactly perfect for a continuation based approach and not so much for a loosely-coupled event-based approach. The act of "firing" an event should indicate that you're letting _other listeners_ (notice the plural) know when you did something.

More on when events are appropriate: Say you're listening for SNMP messages and when you receive one, you let "everyone" know that you did. You don't care what they do with the result, and they just go off on their own. Events can work. Or, take, for example, the BackgroundWorker. The BackgroundWorker doesn't help thread your blocking code, it just pushes the block to a background thread you don't care about. Your HTTP code will still be all sync, and you'll still burn a thread. BackgroundWorker main help is that it coordinates back to your "UI" thread, since many UI frameworks have strong thread affinity and will crash otherwise.

But that was the whole point
The event async pattern, specifically in things like Silverlight, is completely aimed at *not letting the thread block*. That's the _only_ problem it is trying to solve. Silverlight only forces this because the main thread is the UI thread, and they won't want the browser hanging by dumb apps that don't put the block on a background thread. If they didn't want to do continuations, they could have at least kept the sync APIs, and thrown an exception if called from the main thread (thus letting people who know what they're doing not have to deal with the ugly event syntax).

BTW, F# kicks the crap out of your language
I didn't mention it in my previous event post, but F#'s computation expressions let you deal with continuations in a totally sexy way. H.H. Don Syme, writes about it here: Introducing F# Asynchronous Workflows. You learn F# if you don't know it. But just to demonstrate, here's an example from that introduction:

    let AsyncHttp(url:string) =

        async {  // Create the web request object

                 let req = WebRequest.Create(url)

                

                 // Get the response, asynchronously

                 let! rsp = req.GetResponseAsync()

                

                 // Grab the response stream and a reader. Clean up when we're done

                 use stream = rsp.GetResponseStream()

                 use reader = new System.IO.StreamReader(stream)

 

                 // synchronous read-to-end

                 return reader.ReadToEnd() }

The let! binding handles things asynchronously; the rest of the body becomes a continuation. If that isn't superior to any C# approach and doesn't make async easy, I don't know what would.

Code | FSharp
Friday, August 29, 2008 9:03:55 PM UTC  #    Comments [0]  |  Trackback

The most anticipated release of the year is out: F#
A huge thank you and congratulations to MSRC and the F# team! (And to MSFT in general for taking their commercial languages up quite a few notches.)

http://blogs.msdn.com/dsyme/archive/2008/08/29/detailed-release-notes-for-the-f-september-2008-ctp-release.aspx

I was up late last night reading different things on MSR and came across Andrew Kennedy's page. What a surprise to see this morning that F# includes Units of Measure Inference and Checking. http://research.microsoft.com/~akenn/units/intro.html Edit: Oh cool, Mr. Kennedy now has a blog and goes into detail: Units of Measure in F#: Part One, Introducing Units

It seems they did a ton of general clean up and added consistency with .NET and so on. (For instance, you don't need to explicitly accept subtypes with #.)

There's also an "AutoOpen" feature for modules, which allows modules to automatically get opened if their container namespace is -- I suppose this allows more namespace oriented development like .NET prefers. 

Too much stuff to understand the full impact just by browsing the release notes. I think the license has changed; at least it's quite clear that our commercial plans with F# are perfectly allowable (there was some question before). So, now it gets interesting...

FSharp
Friday, August 29, 2008 7:19:13 PM UTC  #    Comments [1]  |  Trackback

# Thursday, August 28, 2008
Tsk, tsk, Silverlight - Events are not async's friend
OK, so Silverlight 2 is still in Beta 2 and hopefully will have time to change. But I would have thought this fix would have gotten into Beta 2 (as far as I can tell, it has not). At any rate, it applies to async design in general.

Scenario: You are writing an async method and need to call code when your async process finishes. How do you expose this to your caller? For some reason (I'd love to know what it is), it seems to be getting more popular to expose an event to accomplish this.

Events suck: Let's use a simple case. You want to get two URLs, using the return of one to get the other, then print the result to the console. You have a few local variables you need to use as well. Let's see what it'd look like without async:

// Inside some method:
var url1 = Console.ReadLine();
var url2 = Console.ReadLine();
var someData = Console.ReadLine();
// onEx = some exception handler
try {
    var res1 = webThingy.Download(url1);
    var res2 = webThingy.Download(url2 + "?data=" + res1.Data);
    Console.WriteLine(someData + res2);
} catch (Exception ex) {
    onEx(ex);
}

Straightforward, eh? Now, with async + events? You _could_ go create a new object type and add all sorts of fields and methods and whatnot, but that's a lot of work and gets ugly quickly. Closures are a natural help here. So how does the event-based async code look?

// Inside some method:
var url1 = Console.ReadLine();
var url2 = Console.ReadLine();
var someData = Console.ReadLine();
// onEx = some exception handler
OnDownloadCompleteEventHandler first;
webThingy.OnDownloadComplete += first = (o, res1) => {
    if (res1.Exception != null) {
        onEx(res1.Exception);
        return;
    }
    webThingy.OnDownloadComplete -= first;
    webThingy.OnDownloadComplete += (o2, res2) => {
        if (res2.Exception != null) {
            onEx(res2.Exception);
            return;
        }
        try {
            Console.WriteLine(someData + res2.Data);
        } catch (Exception ex) { onEx(ex); }
    }
    try {
        webThingy.DownloadAsync(url2 + "?data=" + res1.Data);
    } catch (Exception ex) { onEx(ex); }
};
try {
    webThingy.DownloadAsync(url1);
} catch (Exception ex) { onEx(ex); }


I think this judges itself.

Better
The way it SHOULD be is that any async method should take two arguments, one to call for result, one for exception. Let's see how that would look:

// Inside some method:
var url1 = Console.ReadLine();
var url2 = Console.ReadLine();
var someData = Console.ReadLine();
// onEx = some exception handler
webThingy.DownloadAsync(url1, onEx, res1 => {
    webThingy.DownloadAsync(url2 + ?data=" + res1, onEx, res2 => {
        Console.WriteLine(someData + res2);
    });
});

This code isn't perfect, but it's sure a ton better than the event-based system. With a bit extra work, you could build a simple async framework. Every Async method could return an Async object that would allow you to consolidate stuff like exception handling and cancellation. But even without that, this code straight away is much superior.

The extra downside
Interestingly enough, .NET 1 had the concept of BeginXXX/EndXXX, but because there were no closures, it was always a bit more of a pain to implement. BeginXXX/EndXXX, while not making exception handling as easy, are at least a good start.

The cool thing about BeginXXX/EndXXX was that you could refactor them generically into nice async syntax. Heres a quick and dirty example [F#'s async stuff works similarly.]:

static Action<A1, Action<Exception>, Action<R>> ToAsync<A1, R>(
    Func<A1, AsyncCallback, object, IAsyncResult> begin,
    Func<IAsyncResult, R> end) {
    return (arg, onEx, cont) => {
        begin(arg, iar => {
            try { cont(end(iar)); } catch (Exception ex) { onEx(ex); }
        }, null);
    };
}
static void BeginAcceptAsync(this Socket s, int timeout,
    Action<Exception> onEx, Action<Socket> cont) {
    ToAsync<int, Socket>(s.BeginAccept, s.EndAccept)(timeout, onEx, cont);
}
static void Main() {
    Socket s = ...;
    s.BeginAcceptAsync(10,
        ex => Console.WriteLine(ex),
        sock => sock.Close());
}

(Yes, I think this is a legitimate use of type extensions, but again, only because the original library had a design flaw. And even the non-extension syntax wouldn't necesarily be bad.)

But, to my knowledge, since there's no way to reference an event, this is not possible with the async + event approach t hat is becoming all the rage (yes, SocketAsyncEventArgs, I'm talking about you too). If you know of a way to ease the pain of async+events, tell me.

In summary
It seems that events are a bad choice for code that is not loosely coupled, such as UIs. Even when loosely coupled, sometimes a simple delegate field would be a better choice, since you can compose (like tacking on a filter or otherwise augmenting the callback). But in the case of async, I cannot see how it is good.

Code
Thursday, August 28, 2008 1:48:31 AM UTC  #    Comments [1]  |  Trackback

Why are there still delegates?
Can someone explain to me the point of having delegate types in C#/.NET? They made sense in the non-generic .NET 1 world, but with generics they should have no reason to exist (except maybe purely as a type alias). All the delegates in common use are representable with a generic definition (think Action/Func<...>). But for some reason, you cannot automatically use an equivalent delegate in C#.

This manifests a bit more when you consider a local such as:

var inc = (int x) => i + 1;

As Expression<T> syntax takes the same form, the compiler cannot tell if it's an expression or a delegate. Additionally, since Func<int,int> is "just as good" as any other generic type, even if the compiler wanted to create a delegate, it wouldn't know to use Func<int,int>. Thus, you must specify it, and inner functions are too clunky to be used in C#.

The answer I got from Microsoft (not an official answer, just a response to a Connect item) was that C# might allow auto-conversion in version 4, but also that delegates aren't totally useless because recursive delegate types can't be declared in that fashion. But for the relatively few uses (fixed-point combinators?) of such types, built-in, specific support would be a small sacrifice, wouldn't it?

This is just something I've been wondering about.

Update: Thanks for Jonathan Pryor for pointing out in the comments what my limited functional mind missed: ref/out parameters and of course, and high-arity delegates. While these should be easy to work around, they are accurate technical reasons. Thanks.

Code
Thursday, August 28, 2008 12:18:44 AM UTC  #    Comments [11]  |  Trackback

# Wednesday, August 27, 2008
ASP.NET MVC Begs for Tuples

[Yea, I’m not a web dev, and actively avoid it as much as possible, so I’m late to this party.]

The interesting thing about ASP.NET MVC is that it takes an opposite approach to ASP.NET in general. ASP.NET concepts try to “build up”, so as to shelter us from the evolved idiocy that is HTML, as well as clean up the inherently stateless nature of HTTP. ASP.NET MVC makes no attempt and forces you to deal with reality. Considering ASP.NET’s abstraction isn’t really perfect (example: databinding sucks), MVC’s approach is unfortunately refreshing.

Because of its “raw” nature, you’ll be writing a lot more HTML than you’d do with ASP.NET, and this HTML must line up with code on your server. To make this less of a pain, there are some HTML helper functions. Rob “ type inference” Conery has an overview here.

Here’s the signature for one of the functions:

    public static string CheckBox(this HtmlHelper helper, string htmlName, string text, string value, bool isChecked, object htmlAttributes);

The last parameter confused me. Why would it be an object? Am I supposed to pass in an IDictionary<string,string>? Just a long string? To make it more confusing, other helpers had two overloads:

    public static string TextArea(this HtmlHelper helper, string htmlName, object value, IDictionary<string, object> htmlAttributes);

    public static string TextArea(this HtmlHelper helper, string htmlName, object value, object htmlAttributes);

OK, so they explicitly called out the IDictionary there – THEN WHO WAS OBJECT HTMLATTRIBUTES?

Rob covers in his overview. The idea is that you’re supposed to use anonymous types to hack around the lack of tuples.

<%=Html.Whatever(arg1, bla, …,
                             new { @class=”cssx”, style=”x:f” …}) %>

What a great case of not-having-built-in-tuples-is-lame. It’s so lame, Microsoft’s own developer teams have to resort to weird (but quite creative!) hacks like this so that their syntax won’t completely suck*. Damn.

And now, a duck

For bonus points, there is another C# compiler feature that the MVC team could have [ab]used, and it would arguably have made more sense (although the syntax isn’t as tight). C# supports duck typing on collection initializers! So, they could create a class like this:

    public class HtmlAttributes : System.Collections.IEnumerable

    {

        public System.Collections.IEnumerator GetEnumerator() { ... }

        public void Add(string name, object val) { ... }

    }

And then they can write this:

new HtmlAttributes { { "A", 123} , {"B", "test"} }

No, it’s not as tight as the anonymous type syntax, but it does make a lot more sense.  And tuples still make much more sense than either approach, and have benefits for the rest of the language to boot (death to out parameters!).

 *The only benefit I see in anonymous types is that, at compile time, you'll  know there are no key conflicts - but that is totally trivial in the way they use them, since all the keys are declared right there.

ASP.NET | Code
Wednesday, August 27, 2008 1:12:13 AM UTC  #    Comments [10]  |  Trackback

Extension Methods Suck
Been meaning to write this for a while, and I think I touched on it here, but I'd like to expand a bit. C# Extension Methods are just a hack to compensate for C#'s poor handling of functions in general. As far as I can tell, they were added solely so you can do this type of thing in LINQ:

  var squares = myInts.Select(i => i * i)

Instead of:

  var squares = Enumerable.Select(myInts, i => i * i)

In other words, they wanted to provide some simple infix syntax for functions. Well, that's a poor approach to the problem.

    - First off, it only works on function specially declared to be "extensions", which means your composition options are limited to whatever the library has built in. I can't send arguments to arbitrary static methods, like, say, "someVar.Console.WriteLine".

    - Second, since extension methods are defined solely by their method name, ambiguity is quite easy to come across. There's no way to qualify Foo.Function versus Bar.Function.

Pipeline                                                       
Other languages approach this with two simple things (which actually simplify the entire language/type system overall). First off, we need to be able to define function operators. I'll demonstrate with F#'s pipeline operator:

    let (|>) x f = f x

[As a side note, any language that lets you toss around operators and functions will allow this kind of syntax – it isn’t that F# had to have compiler support for this particular operator.]

In fake C#, it’d be something like (for fun, notice the lack of type inference):

B operator|> <A, B>(A x, Func<A, B> f) { return f(x); }

This means that the |> operator will take x on the left and apply it to f on the right side. If this existed in C#, you'd be able to write something like:

    "Hello" |> Console.WriteLine
or
    if (myInts |> Enumerable.Any) { .... }

Now we can pass in a parameter to static methods. But, hey, whaddya know? With this, Extension Methods are solved for all single-argument static methods! That was easy. But what about Select – it takes two parameters, so this won’t work.

Enter the Lambda
What if ALL functions took one parameter and output one parameter? If that were the case, then we’d be set. But how do allow more than one parameter? Well, what if, every time you declared a method with more than one parameter, it actually returned a method that took the next parameter? For example, we could write “Add” as:

        Func<int,int> Add(Func<int,int> a) { return b =>  a + b; }

This is known as the curried form of Add. We’d now call it as: Add(5)(6). We can do cute stuff like “var inc = Add(1)”. But, as the Add declaration shows, in C# this is too unwieldy (and this is a simple example!). The compiler should actually do all this for us, so we can just write our functions normally but use them as if they were written in curried form.

Now, if we simply swap the order of arguments for Enumerable.Select, we have our extension method ready to roll: Enumerable.Select(Func, IEnumerable) can be used so:

var squares = myInts |> Enumerable.Select(i => i * i)

Now the call to Select takes the lambda (i * i) and returns a function that takes an Enumerable. It is then given the myInts, and everyone is happy. This is just a quick, crap, explanation. Google can lead you to many more interesting resources about partial application, currying and so on.

At any rate, I think if C# had taken this approach, we'd all be much better off. To top it off, more functions would take their arguments in a proper style. As it is, uncurried versions of Extension Methods are incompatible with normal function pipelining. Oh well.


Code | FSharp
Wednesday, August 27, 2008 12:17:53 AM UTC  #    Comments [15]  |  Trackback

# Tuesday, August 26, 2008
ASP.NET MVC - Abusing Using (At VB's request?)
Someone on our team started using ASP.NET MVC for a new web interface we're doing. I must say I'm impressed with the level that the MVC team [ab]uses the C# compiler, mostly in a good way. On the plus side, they end up with a bit more compiler time checking than would be possible otherwise (we can only hope WPF will follow suit some day).

But one thing struck me odd was how their helper method for generating an HTML form works. The goal is to generate an HTML form tag with the right action, and they use lambdas as symbolic references to figure out the action. The next problem is making sure that the <form> gets closed with a </form>. The straightforward answer to this is "create a function that takes a function". The C# signature would be: void Form<A>(Expression<Action<A>>, Action). Then your ASPX code would be:

<% Html.Form<FooController>(x => x.Edit(someVar.FieldX), () => { %>
    Some Html <% SomeCode%>
<% }); %>

The code is nicely bracketed and works fine. But ASP.NET MVC doesn't actually do that. Instead, the Form method returns an IDisposable! The code to use it is:

<% using (Html.Form<FooController>(x => x.Edit(someVar.FieldX)) { %>
    Some Html <% SomeCode%>
<% } %>

Why do they use an IDisposable? The rest of the MVC framework seems to assumes people are somewhat familiar with lambdas, closures and what not. The only thing I can think of is that VB doesn't support anonymous methods. So in order to make it VB friendly, they come up with quite a strange use of IDisposable to abuse language support for it. Overall, I'm not sure if this is dumb or cute.

Code | ASP.NET
Tuesday, August 26, 2008 9:19:59 PM UTC  #    Comments [4]  |  Trackback

# Saturday, August 16, 2008
Reference cells in F# sequences
I saw this stack implementation (http://blogs.msdn.com/jaredpar/archive/2008/08/15/immutablestack-in-f.aspx) and wanted to see how I'd approach it:
 
#light
open System

type 'a ImmutableStack =
   | Empty
   | Stack
of 'a * 'a ImmutableStack
  
member x.Peek() = match x with | Stack (v, _) -> Some v | _ -> None
  
member x.Pop() = match x with | Stack (_, s) -> s | _ -> failwith "empty stack"
   member x.Push a = Stack(a, x)
  
member x.IsEmpty = x = Empty
 
(Well, I'd probably just use a list in most cases.) But interestingly, he has an All function, which returns a sequence of the entire stack. Chris suggested using sequence expressions and then recursively calling the function:
 
member x.All =
    match data with
        | Empty
-> Seq.empty
        | Value (v,n)
->
            seq {
               
yield v
               
yield! n.All }
 
This is pretty nice as far as syntax goes. For some reason, I wanted to see how it'd look without the recursion (which needs to generate a new enumerator, unless the compiler is doing some wicked awesome stuff, which wouldn't surprise me). Here are some of the things I came up with:
 
member x.All1 = 
  
let until f = Seq.generate (fun () -> ref x) f (fun _ -> ())
   until (
fun cur -> match (!cur) with 
                        | Stack(v, s)
-> cur := s
                                         Some v 
                        | _
-> None)
 
Seq.generate continues calling the function until None is returned, so this provides the loop termination. Another similar approach:
 
member x.All2 =
      
let until f = Seq.generate (fun () -> ref x) f (fun _ -> ())
      until (
fun cur -> try (!cur).Peek()
                        
finally if not (!cur).IsEmpty then cur := (!cur).Pop())

Since Peek already returns 'a option, we can use it directly. The problem is that we need to update cur to cur.Pop
and then return a value. The try/finally works, but the whole deal still doesn't seem very elegant. Sequence expressions allow us to yield:
 
member x.All3 =
      
let cur = ref x
      {
while not (!cur).IsEmpty do
          yield (!cur).Peek()
          
do cur := (!cur).Pop() }
      |> Seq.choose(
fun x -> x)

I dislike this one. Because we're not doing the pattern match ourselves, we end up yielding 'a option. But None is never valid because we guard on IsEmpty. This makes us stick a Seq.choose on with an identity function to strip off the Some. [Side note, is there no built-in identity function?] Bringing the match into the seq fixes the issue, but the code is pretty long:

member x.All4 =
      
let cur = ref x
      {
while not (!cur).IsEmpty do
          match (!cur).Peek() with
                      | None
-> do ()
                      | Some v
-> do cur := (!cur).Pop()
                                  
yield v }

 I think what bothers me the most here is that the while and match are redundant. The None case will never be matches because we guard on IsEmpty. Moving that into a separate function gives:

member x.All5 =
      let v = function Stack(vl, _) -> vl | _ -> failwith "dont call on empty"
      let cur = ref x
      {
while (!cur) <> Empty do
          yield v (!cur)
          
do cur := (!cur).Pop() }

I prefer All5 to All4, but still think All1 or All2 are nicer. (Chris's original is best as far as I can tell.) How else can this be done?

Edit: I lost sight of one of the principals of functional programming: Composition. Here's a simple update to All5 that, IMHO, vastly improves it:

member x.All6 =
      
let cur = ref x
      
let toVal = function Stack(v, _) -> v | _ -> failwith "dont call on empty"
      let next () = try toVal (!cur) finally cur := (!cur).Pop()
      {
while (!cur) <> Empty do yield next () }
 

Every line builds up and you don't have to keep its details "active" in your mind. This makes the sequence expression (which is the driver of the algorithm) easy to verify. And again, to clarify, in a real system I'd probably use what Chris suggested since it's the nicest syntax. The other versions are only seeing what it looks like if we toss recursion and use a reference cell.

Code | FSharp
Saturday, August 16, 2008 4:09:49 AM UTC  #    Comments [0]  |  Trackback

# Friday, August 15, 2008
Typing string IDs

I just read these two posts:
http://blogs.msdn.com/simonince/archive/2008/08/15/strongly-typed-primitives.aspx
http://www.thejoyofcode.com/Avoiding_Primitive_Obsession_to_tip_developers_into_the_pit_of_success.aspx

And that reminded me about something we recently did. One system we're working on uses a lot of string identifiers for many different types of objects. There are many, many of these stored and passed around, so keeping things efficient was of high concern. 

The downside of string IDs (really, using any common type as an ID) is that it's legal to pass any primitive of the same type. Strings and integers abound, both as IDs of other classes, as well as general use. So it's not unimaginable that someone could pass the wrong parameter some where. This could lead to runtime crashes or unexpected results (if the ID is actually a real record of another class of object). Finally, using common types for IDs reduces usability. The signature "public void Delete(int id)" leaves a lot to be desired.

We wanted to hit all these issues, in addition to keeping things simple. There are times when untyped data needs to be converted, and this should be easy and clear. We wanted to avoid having to define new types when we had new classes of objects to identify It is also customer-visible code, so C# is used.

Using a reference type was unacceptable, because it'd add at least 12 bytes overhead (I think more on x64). Using a struct fixes this, in addition to dealing with silly nullability issues. [If a type can be null, it should always be explicit. C#'s "references types can be null" makes this hard.]

The end result was quite simple. Wrap a string in a structure so equality and hashing pass through. But, take advantage and remove case/cultural sensitivity (since in many systems, data IDs are not case sensitive). Provide explicit conversions so you can easily convert to and from strings, but never by accident. (If the conversions were implicit, you're back in the starting point.) Finally, add a generic parameter that is never used. The generic parameter gives you distinct types without having to define them. Now the APIs can look like:

    public void Delete(Id<Product> id)...

    Dictionary<Id<Group>, List<Id<User>>> members...

When you do have hardcoded IDs, as the blog entries I mentioned do, you can convert easily: (Id<User>)"Admin". Nulls are treated as empty, all the time (empty may be a valid value anyways).

When a truly optional ID is needed, use nullable types: "Id<Whatever>?". This fully captures how values are handled. This is vastly better than "It's a reference type, so maybe null is allowed. Or maybe null will crash. Empty string might be considered null, or maybe empty string means optional." With explicit nullability, the type system says it all.

The best part is that there should be pretty much no overhead. I'd expect the equality functions to be inlined, and there's no memory overhead, since the struct is simply a string reference.


Here's the class.:
public struct Id<T> : IEquatable<Id<T>>
{
    public Id(string name) {
        this.name = name ?? "";
    }
    readonly string name;
    
    public static explicit operator string(Id<T> x) { return x.name ?? ""; }
    public static explicit operator Id<T>(string s) { return new Id<T>(s); }

    public override bool Equals(object obj) {
        return
            !(obj is Id<T>) ? false :
            ((Id<T>)obj) == this;
    }

    public bool Equals(Id<T> other) {
        return other == this;
    }

    public override int GetHashCode() {
        return (name ?? "").GetHashCode();
    }
    public override string ToString() {
        return name ?? "";
    }
    public static bool operator ==(Id<T> a, Id<T> b) {
        return StringComparer.InvariantCultureIgnoreCase.Compare(a.name, b.name) == 0;
    }
    public static bool operator !=(Id<T> a, Id<T> b) {
        return !(a == b);
    }
}
I'd be interested in seeing a more generic, yet very simple, solution: one that doesn't rely on the underlying type to be string, but still provides all the same functionality. I don't think it's possible, since there's no way to get a generic constraint that'd allow similar handling of "string" and "int?". Additionally, structs can't inherit, so you'd end up using "Id<string, Product>" everywhere, which is far from elegant.
Code
Friday, August 15, 2008 7:39:11 PM UTC  #    Comments [8]  |  Trackback

# Thursday, June 26, 2008
I underestimated the power of query comprehensions

In my last post, I said I'd write the sample in C# to compare to F#. Well, I grossly underestimated the power of query comprehensions. The C# version is almost the same length (formatting differences, mainly). I'm surprised and impressed. (Or maybe I'm writing F# like I'd write C#.) Edit: I think maybe sequence expressions could cut it down a bit...

...But... C# still can't do discriminated unions efficiently or effectively ;).


    1 // crudcreatecompare.cs: Generates LINQ CRUD table fields using the horribly named DatabaseBase code

    2 //

    3 // Tables look like: [Table(Name="dbo.Accounts")]

    4 // Columns look like this:

    5 //  [Column(Storage="_AccountName", DbType="VarChar(128) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]

    6 //  [DataMember(Order=1)] // Exists if serialization is turned on; used to order key parameters

    7 // Emits:

    8 //  public static readonly TableHelper<Account, String> Accounts =

    9 //      CreateTable(dc => dc.Accounts, a => a.AccountName);

   10 

   11 using System;

   12 using System.Collections.Generic;

   13 using System.Data.Linq.Mapping;

   14 using System.IO;

   15 using System.Linq;

   16 using System.Reflection;

   17 using System.Runtime.Serialization;

   18 

   19 class Program

   20 {

   21     static void Main()

   22     {

   23         Console.WriteLine(

   24             new Program().generate(

   25             "C:\\yourlinq.dll"));

   26     }

   27 

   28     string generate(string asmpath)

   29     {

   30         var asm = Assembly.LoadFrom(asmpath);

   31         var lines = from t in asm.GetExportedTypes()

   32                     let ta = getAttr<TableAttribute>(t)

   33                     where ta != null

   34                     let name = pluralize(ta.Name.Replace("dbo.", ""))

   35                     orderby name

   36                     select genTable(t, name);

   37         return joinStrings("", lines);

   38     }

   39 

   40     string genTable(Type t, string tableName)

   41     {

   42         var keyProps =

   43             from p in t.GetProperties()

   44             let c = getAttr<ColumnAttribute>(p)

   45             where c != null && c.IsPrimaryKey

   46             let dm = getAttr<DataMemberAttribute>(p)

   47             orderby dm == null ? 0 : dm.Order

   48             select p;

   49         var tw = new StringWriter();

   50         tw.WriteLine("public static readonly TableHelper<{0}, {1}> {2} =",

   51             t.Name,

   52             joinStrings(", ", keyProps.Select(p => p.PropertyType.Name)),

   53             tableName);

   54         tw.WriteLine("\tCreateTable(dc => dc.{0}, {1});",

   55             tableName,

   56             joinStrings(", ", keyProps.Select(p => "a => a." + p.Name)));

   57         tw.WriteLine();

   58         return tw.ToString();

   59     }

   60 

   61     string joinStrings(string sep, IEnumerable<string> items)

   62     {

   63         return string.Join(sep, items.ToArray());

   64     }

   65     string pluralize(string s)

   66     {

   67         return s.EndsWith("s") ? s : s + "s";

   68     }

   69 

   70     T getAttr<T>(ICustomAttributeProvider icap)

   71     {

   72         var a = icap.GetCustomAttributes(typeof(T), true);

   73         return a.Length == 0 ? default(T) : (T)a[0];

   74     }

   75 }

Code | FSharp
Thursday, June 26, 2008 6:15:10 AM UTC  #    Comments [0]  |  Trackback

LINQ to the CRUD CreateTable generator in F#

With the DatabaseBase and TableHelper classes, you still have to generate a CreateTable field per table. Why do it by hand? I wrote an F# script to generate the statements. I must say, I'm loving F# more than I had hoped. The more I learn, the better it gets. I've noticed (even in C#) that using a functional style generally means less errors. This script worked without bugs the first time (i.e., as soon as it compiled), which is pretty cool (granted, it's not big, but I'm sure if I had tons of for loops, I woulda messed up somewhere). Maybe this weekend I'll try writing it in C# just to compare (pretty sure it'll be more than 59 lines!). And I'll preempt comments about readability: Yes, it may be difficult to read if you don't know F#, but more on that later...

I'd love feedback as to making it more "functional"; years of imperative programming don't die quickly. Also, I'm not very happy with the definition of chooseAttr, but I can't seem to get it to infer the type I want otherwise.

Anyways, here's the code. You'll need to specify the references when compiling: -r "C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.Linq.dll" -r "C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.Runtime.Serialization.dll"


    1 // crudcreatetable.fsx: Generates LINQ CRUD table fields using the horribly named DatabaseBase code

    2 //

    3 // Tables look like: [Table(Name="dbo.Accounts")]

    4 // Columns look like this:

    5 //  [Column(Storage="_AccountName", DbType="VarChar(128) NOT NULL", CanBeNull=false, IsPrimaryKey=true)]

    6 //  [DataMember(Order=1)] // Exists if serialization is turned on; used to order key parameters

    7 // Emits:

    8 //  public static readonly TableHelper<Account, String> Accounts =

    9 //      CreateTable(dc => dc.Accounts, a => a.AccountName);

   10 

   11 #light

   12 open System

   13 open System.Reflection

   14 open System.Data.Linq.Mapping

   15 open System.Runtime.Serialization

   16 

   17 let getAttr<'target, 'a when 'a :> ICustomAttributeProvider> (ty : 'a) =

   18     match List.of_array (ty.GetCustomAttributes(typeof<'target>, true)) with

   19         | a::_ -> Some (a :?> 'target)

   20         | [] -> None

   21 let chooseAttr<'target, 'a when 'a :> ICustomAttributeProvider> (ty : 'a) =

   22     match getAttr<'target,_> ty with

   23         | Some(a) -> Some(ty,a)

   24         | None -> None

   25 

   26 let joinStrings (sep:string) items = items |> Seq.fold1 (fun acc x -> acc + sep + x)

   27 let pluralize (name:string) = if name.EndsWith("s") then name else name + "s"

   28 

   29 let generate(asmpath:string) =

   30     let genTable (t:Type, tableName) =

   31         let keyProps =

   32             t.GetProperties()

   33             |> Seq.choose (chooseAttr<ColumnAttribute,_>)

   34             |> Seq.filter(fun (p,c) -> c.IsPrimaryKey)

   35             |> Seq.map(fun (p,_) -> p, getAttr<DataMemberAttribute, _> p)

   36             |> Seq.orderBy(function | _,Some(dm) -> dm.Order | _ -> 0)

   37             |> Seq.map (fun (p,_) -> p)

   38         let tw = new IO.StringWriter()

   39         let pn fmt = Printf.twprintfn tw fmt

   40         pn "public static readonly TableHelper<%s, %s> %s ="

   41             t.Name

   42             (joinStrings ", " (keyProps |> Seq.map (fun p -> p.PropertyType.Name)))

   43             tableName

   44         pn "\tCreateTable(dc => dc.%s, %s);"

   45             tableName

   46             (joinStrings ", " (keyProps |> Seq.map (fun p -> "a => a." + p.Name)))

   47         pn ""

   48         tw.ToString()

   49 

   50     let asm = Assembly.LoadFrom asmpath // Don't use ReflectionOnly 'cause it won't resolve dependencies

   51     asm.GetExportedTypes ()

   52         |> Seq.choose (chooseAttr<TableAttribute,_>)

   53         |> Seq.map (fun (t,ta) -> t, ta.Name.Replace("dbo.", "") |> pluralize)

   54         |> Seq.orderBy (fun (t,_) -> t.Name)

   55         |> Seq.map genTable

   56         |> Seq.fold1 (+)

   57 

   58 generate "C:\\yourlinq.dll"

   59     |> Console.WriteLine

FSharp
Thursday, June 26, 2008 5:13:44 AM UTC  #    Comments [0]  |  Trackback

LINQ to the CRUD RTM

[Reposting because it appears to have been deleted somehow.]

A bit ago, I posted some info on doing CRUD operations using LINQ: http://www.atrevido.net/blog/2007/08/26/A+LINQ+To+The+CRUD.aspx

This is a lightweight way (no codegen at all, only 2 lines of code per table) to get some CRUD stuff with LINQ. It's not the most efficient or fantastic way of doing things, but it works fine in the several projects we've used it so far. And we get to use C# 3's expression trees, which is a fantastic and under-exploited feature. At any rate, it does show that doing disconnected work with LINQ is trivial.

The code I posted was for Beta 2 and no longer works. I've since added a few new features, but the basic idea remains the same as before. I'm just posting the new code as I've gotten a few emails and one comment about the old code no longer working.

DatabaseBase.cs (10.47 KB)

While working on it in a real project, I started using our Tuple struct, so you'll need that too:
Tuple.cs (2.8 KB)

As Scott Peterson pointed out, this class doesn't implement IEquatable<T>. Just add it and call the == operator.

As always I welcome any criticism.

Misc. Technology
Thursday, June 26, 2008 4:56:24 AM UTC  #    Comments [0]  |  Trackback

# Monday, March 31, 2008
The reason VB.NET is truly a second class citizen

No support for anonymous methods/lambda statements. I first realised this when someone commented on one of my functional C# postings, asking "how can I write this in VB"? Turns out VB has no support for anonymous methods. Ouch.

This lack of capability rules out a so much functionality, I honestly cannot imagine writing anything significant today using VB.NET. But with LINQ and F# making such a big splashes, I have high hopes for the future of functional programming on the .NET languages, and I'm sure VB.NET will get itself fixed up.

Really, dropping anonymous methods in favour of stuff like XML literals? Maybe that's why it's listed as first time or casual programming ;). (No, I jest. Scheme is far better for first time programming.)

Code
Monday, March 31, 2008 9:55:56 PM UTC  #    Comments [8]  |  Trackback

Empty WCF services references - no code generated

Usually I use WCF just by referencing the contracts directly and using my own generic helper methods. Unfortunately, I had to make use of the built-in async patterns that the codegen can provide. Hence, I ended up using the "Add Service Reference" dialog, which notices (unlike svcutil on the command line) that since I'm requesting async, it'll need to generate my interfaces even though they're already referenced. Maybe in .NET 4 we'll have a new async pattern that'll leverage Expression Trees to rid us of having to use the rather ugly FooAsync/BeingFoo patterns.

Things were working just fine until I added a reference to a new service. Adding the service reference didn't work; it failed silently. It added all the schema files to the project, but the Reference.cs file was empty. If I told it to NOT used referenced assemblies, then it generated everything just fine.

After switching to the command line and using svcutil, I got these errors:
Error: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Referenced type 'MyApp.Management.CoolFunction.CoolThingRule, MyApp.Management.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' with data contract name 'CoolThingRule' in namespace 'http://schemas.MyApp.com/management/v2/00' cannot be used since it does not match imported DataContract. Need to exclude this type from referenced types.XPath to Error Source: //wsdl:definitions[@targetNamespace='http://schemas.MyApp.com/management/v2/00']/wsdl:portType[@name='ICoolThingManagement']

I regenerated without the referenced code and figured out that the problem was that one type referenced an enum which had some values without the [EnumMember] attribute (although it had a DataContractAttribute on the enum itself). Because of this, WCF wanted to represent the enum with a string and thus was incompatible. Adding the EnumMemberAttribute to all the values sorted out this issue.

Code
Monday, March 31, 2008 9:06:51 AM UTC  #    Comments [5]  |  Trackback