Jeremy D. Miller -- The Shade Tree Developer

Sponsors

The Lounge

Wicked Cool Jobs

Syndication

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
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. 

 

 

 


Posted Sun, Oct 15 2006 9:09 PM by Jeremy D. Miller

[Advertisement]

Comments

Sam Smoot wrote re: I used my first closure in C# 2.0!
on Mon, Oct 16 2006 12:36 AM

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. :-)

Jeremy D. Miller wrote re: I used my first closure in C# 2.0!
on Mon, Oct 16 2006 6:14 AM

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

karl wrote re: I used my first closure in C# 2.0!
on Mon, Oct 16 2006 6:57 AM

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 :)

Brendan Tompkins wrote re: I used my first closure in C# 2.0!
on Mon, Oct 16 2006 9:39 AM

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?

Sam Smoot wrote re: I used my first closure in C# 2.0!
on Mon, Oct 16 2006 10:09 AM

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

<code>

public void Main() {

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

}

Delegate GetClosure() {

bool capture = true;

return delegate() {

return capture;

};

}

</code>

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

Duncan Godwin wrote re: I used my first closure in C# 2.0!
on Mon, Oct 16 2006 2:58 PM

C# 3.0 it becomes nicer:

return Array.Find<ISystemUnderTest>(_systems,

                        system => system.Name == systemName);

Can't wait :)

Sam Smoot wrote re: I used my first closure in C# 2.0!
on Mon, Oct 16 2006 7:25 PM

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.

Jeremy D. Miller wrote re: I used my first closure in C# 2.0!
on Mon, Oct 16 2006 7:29 PM

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.

Jason Haley wrote Interesting Finds: October 16, 2006
on Mon, Oct 16 2006 9:49 PM
Sam Smoot wrote re: I used my first closure in C# 2.0!
on Mon, Oct 16 2006 10:01 PM

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.

Jeremy D. Miller wrote re: I used my first closure in C# 2.0!
on Tue, Oct 17 2006 7:36 AM

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.

Oren Ellenbogen wrote re: I used my first closure in C# 2.0!
on Sat, Nov 25 2006 10:19 AM

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

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Devlicio.us