I used my first closure in C# 2.0!

Okay, it's lame, but still:

   53                 return Array.Find<ISystemUnderTest>(

   54                     _systems,

   55                     delegate(ISystemUnderTest system)

   56                         {

   57                             return system.Name == systemName;

   58                         });

where _systems is an array of ISystemUnderTest[] and systemName was an argument to the method that contains this code.

Somebody will have to correct me, but I think the Ruby equivalent (they call them "blocks") would look like this:

systems.Find (|system| {system.name == name}) 

Ruby is definitely cleaner, but I'm happy to have some of this stuff in C# now.  I was playing quite a bit with Prototype in Javascript a couple months back and got hooked on the functional idioms like this method below:

	table.drawPage = function(iterator, columns){
this.clear();

columns.each( function(column){
this.createHeader(column);
}.bind(this));


while (subject = iterator.next()){
this.drawRow(columns, subject);
}
}

The code "columns.each( function(column){ …" is the closure.  This calls the current class's createHeader() method on each member of the columns array.  Before you run off and try this  in Javascript, it's Prototype that extends the Javascript Array object with a bunch of "Ruby-isms" like this.  You'll need to grab the Prototype library first.

Check out Martin Fowler's explanation of closures for an explanation.  I'm really looking forward to  the C# 3.0 features now.  I'm skeptical of much of the Microsoft canon, but I'm sincerely in awe of Anders Hejlsberg. 

 

 

 

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.lnbogen.com/ Oren Ellenbogen

    I love delegates & anonymous methods! really! you could create great “templates” and provide some high-level API for your developers which really cuts down repetitive code. I even did a lecture in the C# User Group (in Israel) about this subject:
    http://www.lnbogen.com/SlidesDemosFromMyCodeTemplatingPresentation.aspx

  • http://codebetter.com/blogs/jeremy.miller jmiller

    Ruby to spaghetti code ASP classic? Rough dude. There has never in the history of mankind been a nontrivial ASP classic application that wasn’t a big ball of mud.

  • http://substantiality.net Sam Smoot

    Heh, I wish. I’ve been lucky enough to code in Ruby and .NET in spurts, but I spend 90% of my time these days trying to bend ASP Classic to my will. At least at work. :-)

    I agree it’s nice to c# getting extra features though. I’m just a little concerned about the fragmentation.

  • http://codebetter.com/blogs/jeremy.miller jmiller

    I agree with you Sam, but it’s still nice to see these features coming in a mainstream, statically typed language. I know *you* get paid to write Ruby, but the rest of us (as I sit here in my No Fluff, Just Stuff, i.e. Ruby reeducation camp, t-shirt) can only dream.

  • http://substantiality.net Sam Smoot

    Actually, I think my c# example is off WRT the return statement.

    Maybe it’s just me, but I *HATE* the new lambda syntax in c#3. It’s inflexible. In Ruby you can have a block of any length, but c#3′s syntax limits you to a single expression as far as I can tell. Which is more of a nifty toy feature than anything since you could just do the same thing with Enumerable methods.

    So now, in addition to event, Delegate, and delegate we get a new syntax for lambdas. Ruby does all this with one syntax. Or Python. Or pick-your-language. Messy.

  • Duncan Godwin

    C# 3.0 it becomes nicer:

    return Array.Find(_systems,
    system => system.Name == systemName);

    Can’t wait :)

  • http://substantiality.net Sam Smoot

    I hope I’ve got the syntax right. I don’t have a Windows machine to test with right now:


    public void Main() {
    Console.WriteLine("c# supports closures? {0}", (GetClosure()() == true));
    }

    Delegate GetClosure() {
    bool capture = true;

    return delegate() {
    return capture;
    };
    }

    So, what determines a Closure is wether it captures the value of variables that would have otherwise gone out of scope.

  • btompkins

    I started using this syntax too a couple of weeks ago… But I’m still not sure what it’s called.. Is the .Find(delegate.. sytax a closure, or just a delegate?

  • karl

    It’s a bit cleaner with a generic, since you don’t have to supply the _systems parameter:

    _systems.Find(delegate(ISystemUnderTest system)
    {
    return string.Compare(system.Name, systemName, true) == 0;
    }
    );

    Thank god for Resharper’s formatting of these things :)

  • http://codebetter.com/blogs/jeremy.miller jmiller

    Thanks for the tips Sam. I’m a bit of a newbie in these areas.

  • http://substantiality.net Sam Smoot

    Your Ruby example is close, but blocks are always the last parameter to a method, so the binding parse-wise has them appearing outside of the parenthesis. Also, parameters passed to a block are defined in the block. So:

    systems.find() { |system| system.name == name }

    (Parenthesis used for clarity)

    In your example Ruby would probably see the opening curly-brace and expect a hash-literal instead of a block.

    This syntax is consistent with lambdas (a function to declare a block) and Procs (a class representing a block), so it gets reinforced and makes it a little easier to remember.

    So we could also write it like:

    condition = lambda { |system| system.name == name }
    systems.find(&condition) # Use the “&” to indicate a block-argument.

    Or:

    condition = Proc.new { |system| system.name == name }
    systems.find(&condition)

    Of course Array#find just returns the item you’re looking for. Which is known ahead of time in this case. So I’m assuming this is just a simplified example. If not, I would suggest using Array#index or Array#include? instead.

    A couple things to keep in mind with regards to the Prototype library: It’s iterators are very slow. Hopefully most of the time it shouldn’t matter. When it does, stick to a traditional for() loop though. Also, if you’re iterating over hashes like so:

    for(var key in something) {
    alert(key);
    }

    You’ll get the decorated methods too. Which is no fun. You’ll want to use this instead:

    for(var key in something) {
    if(typeof something[key] == ‘function’) { continue; }
    alert(key);
    }

    Anyways, nice post. :-)