11 September, 2007
I find it fascinating that after so many decades of support for closures, we’re still stuck in a C-style mentality of passing function-pointers that take an explicit context argument rather than a proper closure object. Witness the design of .NET’s Type.FindInterfaces method:
public virtual Type FindInterfaces (TypeFilter filter, Object filterCriteria);
The TypeFilter argument is a delegate. The Object argument is context that the delegate may require! This is pretty much exactly the old-school C-style way of implementing closures:
/* Yes, pretty crude translation, I know */ TypeArray find_interfaces(int (*type_filter)(Type*, void*), void *argument);
Smalltalk (and Lisps) would do it in the natural way, with a block (a closure):
someType selectInterfaces: [:interface | ... ]
Lisp 1.5, complete with support for lexical closures, appeared in 1959. It’s 2007. That’s forty-eight years.
On 11 September, 2007 at 1:32 pm,wrote:
Yes, it’s comical, but why do you think it is so?
“I think the “new style” of coding is hard to read, understand and debug …”
On 11 September, 2007 at 2:58 pm,wrote:
We need a eugenics program for software developers…
On 11 September, 2007 at 4:39 pm,wrote:
This method was around during C# 1.0, when there were no closures. An alternative to what you have shown would be to have FindInterfaces take a class instance (common for Java IIRC). If this method were updated for C# 2.0+, it could simply take a Predicate. You should probably aim your criticism at Java. :-p C# 3.0 syntax would look like this:
someType.FindInterfaces(iface => iface.Name == "IFoolishness");
Pretty readable if you ask me!
On 12 August, 2008 at 11:03 pm,wrote:
c# 3.0 lambda expression is:
ob.GetType().FindInterfaces((iface, criteria) => iface.FullName == criteria.ToString(), typeof(IMapas).FullName);