Joe Walnes
  Blog



Recent Entries

Creative uses of Hamcrest matchers

Hamcrest 1.1 released

Testing on the Toilet

Building testable AJAX apps (Does my button look big in this?)

QDox is back - 1.6 released

Java and .NET RESTful interoperability with XStream

I've joined Google

OSCon: SiteMesh, SiteMesh, SiteMesh, SiteMesh

Flexible JUnit assertions with assertThat()

SiteMesh and Content Management @ O'Reilly OpenSource Conference

XStream 1.1.2 released. Java 5 Enums, JavaBeans, field aliasing, StAX, and more...

VB.Net is the bestest

XStream 1.1.1 released

Accessing generic type information at runtime

XStream 1.1 released

JUnit tip: Setting the default timezone with a TestDecorator

XStream: how to serialize objects to non XML formats

How my backflip went...

Backflippin' in 4 hours.

Is 100% test coverage a BAD thing?

Looking back at the SiteMesh HTML parser

The road ahead for SiteMesh 3

Joe's Backflipping for Autistic Research - time is nearly up...

SiteMesh 2.2 Released

Advanced SiteMesh

More... [RSS | RDF]

About Joe Walnes

I am a software engineer for Google, based in London.

Open Source

WebStuff (coming soon)

XStream

ActiveMQ

SiteMesh

QDox

nMock

jMock

Pico Container

Nano Container

OpenSymphony

Squiggle

MockDoclet

MockObjects

Jelly

Groovy

PatternStitcher

XJB

Books

Java Open Source Programming, Wiley JSP Site Design, Wrox

Talks

Mock Roles, not Objects
October 26 2004, Vancouver, Canada. OOPSLA'04

Personal Development Practices Map
June 24 2004, Salt Lake City, Utah. Agile Development Conference

SiteMesh.NET and ASP.NET MasterPages
May 20 2004, Bangalore, India. Bangalore .NET User Group

Mock Objects: Driving Top Down Development
March 29 2004, St Neots, UK. OT2004

Mock Objects
December 2 2003, London, UK. XP Day 3


The power of closures in C# 2.0

Martin Fowler (obligitary Fowlbot namedrop) recently blogged about the power of closures in languages that support them. It's worth remembering that C# 2.0 has true closure support in the form of anonymous delegates. This includes reading and modifying variables outside the context of the closure - unlike Java's anonymous inner classes.

Just for kicks, I've rewritten all of the examples Martin's Ruby examples in C# 2.0. This makes use of the improved APIs in .NET 2.0 pointed out by Zohar.

Ruby C# 2.0
def managers(emps)
  return emps.select {|e| e.isManager}
end
public List<Employee> Managers(List<Employee> emps) {
  return emps.FindAll(delegate(Employee e) { 
    return e.IsManager; 
  }
}
def highPaid(emps)
  threshold = 150
  return emps.select {|e| e.salary > threshold}
end
public List<Employee> HighPaid(List<Employee> emps) {
  int threshold = 150;
  return emps.FindAll(delegate(Employee e) { 
    return e.Salary > threshold; 
  });
}
def paidMore(amount)
  return Proc.new {|e| e.salary > amount}
end
public Predicate<Employee> PaidMore(int amount) {
  return delegate(Employee e) { 
    return e.Salary > amount; 
  }
}
highPaid = paidMore(150)
john = Employee.new
john.salary = 200
print highPaid.call(john)
Predicate<Employee> highPaid = PaidMore(150);
Employee john = new Employee();
john.Salary = 200;
Console.WriteLine(highPaid(john));

The code difference between the languages isn't that difference. The C# 2.0 code is obviously longer (though not a lot) because:

  • C# 2.0 is staticly typed (let's not get started on the static vs dynamic debate).
  • C# 2.0 requires the 'delegate' keyword.
  • Ruby allows you to ignore the 'return' keyword.

You can try this stuff out yourself by playing with Visual C# Express.

Comments

Obie

Cool, but what's with the capitalized method names? ICK!!!

Joe Walnes

Here is a sample comparison of anonymous delegates in C# 2.0 with anonymous inner classes in Java.

C# 2.0

int total = 0;
order.EachItem(delegate(Item item) {
  total += item.Price;
}
Console.WriteLine("Total of order is {0}", total);

Java

final int[] total = { 0 };
order.eachItem(new OrderBlock() {
  public void handle(Item item) {
    total[0] += item.getPrice();
  }
});
System.out.println("Total of order is " + total[0]);

This is something I end up doing a lot, and I cringe everytime. The anonymous bloat I don't mind so much, but the final array hack is what really gets me. This is necessary because any local variable outside the scope the of the inner must be final, so the only way to write to it is to use an array. Thankfully IDEA always automagically sorts this out for me, but it's still confusing for someone who is later trying to understand the code.

verbat

I said many times: c# 2.0 is a kind of statically typed ruby. Even the icollection apis wich gets anonimous delegates as parameters really resemble ruby's Enumerable.

Pavel Tavoda

If you want use scripting languages, go with Groovy. This have very extended closure support.

Meitsi

"The C# 2.0 code is obviously longer (though not a lot) because:

C# 2.0 is staticly typed (let's not get started on the static vs dynamic debate)."

No, not quite the right reason. C# is longer specifically because it uses manifest typing.

Eric Hodel

Eeee! The code runs all over the sidebar. Unreadable even at 1024 px width!

Try putting such code blocks in a div with the style "overflow:auto" set

Yuriy

just to remind that JScript supports this technique

small sample:
function A(D) {
var C = 10;
if (D == 1) {
B = function () {
WScript.Echo(C);
}
C = 11;
}
else
C = 12;

B();
C = 13;
}

var
C = 90;

A(1);
A();
B();

The example code is wrong, I think. Shouldn't the FindAll example actually be:


public List Managers(List emps) {
return emps.FindAll(delegate(Employee e) {
return e.IsManager;
} );
}


Note the additional round bracket and semicolon at the end of the return statement. The code doesn't look quite so clean now, unfortunately.

Bill Wood

I've put boo versions of these examples here:
http://docs.codehaus.org/display/BOO/Martin+Fowler%27s+closure+examples+in+boo

Boo is a new object oriented statically typed programming language for the Common Language Infrastructure with a python inspired syntax and a special focus on language and compiler extensibility.

http://boo.codehuas.org

Bill Wood

Sorry the second link above to boo should be:

http://boo.codehaus.org/

Jay

I would like to check this out, but I can't read the C# because it drools out into the right sidebar.

David Vallner

Minor note by a rubyist - the Ruby code examples don't make use of omitting the return keyword. If you used return inside a closure, it would return from the method it was defined in.

Chris

Please God fix the messed up tables created by SiteMash and UnmoveableType so I can read this example.

Thomas Hafner

Quote:
|The C# 2.0 code is obviously longer (though not a lot) because:
| * C# 2.0 is staticly typed (let's not get started on the static vs
| dynamic debate).

Static typing is a bad excuse for longer code. It's not obvious at
all. Look at this Haskell example:

f x = (\y -> x + y)

It's a closure (see ).

Nevertheless Haskel is a statically typed language (see table "Type
system cross reference list" in
).

Regards
Thomas

Thomas Hafner

Sorry that I've to post it again, but the Blog software skipped the
URLs because of the surrounding angle brackets.

Quote:
|The C# 2.0 code is obviously longer (though not a lot) because:
| * C# 2.0 is staticly typed (let's not get started on the static vs
| dynamic debate).

Static typing is a bad excuse for longer code. It's not obvious at
all. Look at this Haskell example:

f x = (\y -> x + y)

It's a closure (see http://www.haskell.org/hawiki/Closure).

Nevertheless Haskell is a statically typed language (see table "Type
system cross reference list" in
http://en.wikipedia.org/wiki/Dynamic_typing ).

Regards
Thomas

Eric

Essential C# 2.0
http://www.awprofessional.com/bookstore/product.asp?isbn=0321150775&rl=1 (sample chapter “Generics”
Essential C# 2.0 is a clear, concise guide to C#—including the features new to C# 2.0. The book clearly presents material for beginners and experts and provides contrasts and comparisons between C# and other languages. The C# language is covered comprehensively and each important construct is illustrated with succinct code examples. Complete code examples are available online. Mark Michaelis has organized the material for quick access. Graphical “mind maps” at the beginning of each chapter show what material is covered and how each topic relates to the whole.
Following the C# introduction, readers will learn about
• C# primitive data types, value types, reference types, type conversions, and arrays
• Operators and control flow, loops, conditional logic, and sequential programming
• Methods, parameters, exception handling, and structured programming
• Classes, inheritance, structures, interfaces, and object-oriented programming
• Well-formed types, operator overloading, namespaces, and garbage collection
• Generics, collections, and iterators
• Reflection, attributes, and declarative programming
• Threading, synchronization, and multi-threaded patterns
• Interoperability and unsafe code
• The Common Language Infrastructure that underlies C#

Name:
Email:
URL:

ThoughtBloggers

Martin Fowler

Dan North

Aslak Hellesoy

Darren Hobbs

Geoff Oliphant

Mike Roberts

Chris Stevenson

Jon Tirsen

Loads More...

Agile Bloggers

Ken Arnold

Ward Cunningham

Brian Marick

Robert Martin

Bret Pettichord

Java Bloggers

Ara Abrahamian

Mike Cannon-Brookes

Vincent Massol

Bob McWhirter

Rickard Oberg

Joseph Ottinger

James Strachan

Hani Suleiman

Communities

eXtreme Tuesday Club (XTC)

Thursday GeekSpeek

ThoughtWorks GeekNight

London Java Meetup

The Codehaus

[RSS | RDF]
© 2001-2004, Joe Walnes

Powered by SiteMesh and Moveable Type.