... the use (or lack of use) of delegates can capture a developer's intention with more precision than would be possible in a simple class/interface world.
For me, the most important aspect of delegates is they tend to result in more loosely-coupled designs than one gets with traditional class/interface-based approaches. Specifically, when you expose an extensibility or integration point as a delegate, you are effectively saying that the contract between your code and the outside world is implicit rather than explicit.
Given that delegates are just the .NET way of expressing function references (with semi closures) as first class citizens, Don is basically demonstrating some advantages of higher order programming.
BTW, monikers are a COM mechanism for identifying object instances (and more) using a human-readable name (with other amenities such as name composition).
Posted to critiques by Dan Shappir on 7/22/03; 1:53:25 AM
foreach (object o in Tester1.Generate(new Predicate(A2.Is42))) {
Console.WriteLine(o);
}
Why not just:
foreach (object o in Tester1.Generate(A2.Is42)) {
Console.WriteLine(o);
}
Or even better:
Tester1.Generate(A.Is42).foreach(Console.WriteLine);
But that's not C#, that's BeyondJS ;-)
He may even realize *explicit* static typing is just not a good idea, period.
Ok, I'll bite. (... donning asbestos...) What is your argument for that position?
I have dynamic arguments and static arguments.
Dynamic: Smalltalk, Lisp, Perl, Python, etc.
Static: ML, Haskell, etc.
And there is just the conventional wisdom that says a programmer can get X lines of code running per day. If some of that X are devoted to explicitly typing then that is effort not devoted to something that happens at run-time.
Ok, so this proves that it is possible to produce effective solutions without static typing.
Static: ML, Haskell, etc.
I would want to make a distinction between "explicit" and "redundant" static typing here. Type inference eliminates redundant marking of type, but a programmer still needs to understand type and mark it in situations where there is ambiguity, to set up pattern matching, etc.
Even if type inference eliminated all explicit type marking, it would still only prove that it is possible to produce effective code without explicit type marking.
And there is just the conventional wisdom that says a programmer can get X lines of code running per day.
Who says the types are necessarily on a separate line? ;-) This is pretty fuzzy conventional wisdom, and I'm sure I could construe a scenario to show that typing either had no effect on productivity or showed a long-term benefit to productivity by clarifying intent, etc.
So, your argument has proven that there exists a large set of situations where you can live without explicit static typing, but that doesn't prove it is necessarily a bad idea in all situations.
Which makes this a good time to point out that people should lurk a bit before posting. Indeed, they should at least read ten papers previously discussed on LtU, before posting...
When it comes down to it, articles like this just seem like a excuse to dump on C# (or Java, etc). Fish in a barrel.
Indeed. Everyone has different sets of experiences and frames of reference.
Speaking for myself, I've been a programming language geek for more than 20 years and am relatively (to Don Box) poor.
Don has been a Microsoft technology (COM, DCOM, dotnet) geek for at least half that time. He also is an architect at Microsoft for some key leading edge technologies. But he also started, grew, and sold a very successful consulting business, and is more than absolutely rich compared to me and most other people.
So I can suggest my perspective on programming language issues is only slightly broader than his, but I wouldn't intentionally insult him. His is obviously a sharp mind.
I think he was at UCI before starting DevelopMentor.
rather than
Without explicitly stating so, Don Box reveals a preference for FP over OOP
struck me as insufficiently polite. That's all.
Besides, it would be a little awkward for Box to openly advocate a programming approach where Microsoft doesn't compete well against open source (the page does carry a Microsoft copyright).
Obfuscated C# Description: "With props to my hommies in the functional language 'hood"
A less obscure version Description: "Pre-empting the functional language police"
Thanks for defending my honor over here.
Yes, I have been attracted to functional programming from an early age. I first came to terms with my attraction late in grad school but didn't have my first functional programming experience until I found XSLT.
After years of dabbling, I found myself in a committed relationship with ML early this year. However, like many a programmer, I do have a wandering eye.
As to what I did before coming to the big house, yes, I owned (and sold) a software education firm (developmentor) and before that I was a grad student at UC Irvine. At MSFT, I work as an architect on XML messaging. The consistent theme is that I've spent most of my career trying to get two or more programs to work together without killing one another.
As for Dan's less-than-cheritable assessment, they issue us asbestos underpants at new employee orientation, so no harm no foul.
Keep 'em flying, DB
This IS a blog (in the Slashdot sense); you've got to expect a bit of snarkiness. ;-)
Having said that, form is only form, it's in the substance that the really interesting exchanges take place. If you think substantive issues or features are being given short shrift, engage us on those points.
You'll probably get a response from me, anyway based on my current volume. ;-)
Without explicitly stating so, Don Box reveals a preference for FP over OOPActually I'd consider that complimentary - i.e. I read it as his ideas are correct - he just doesn't necessarily carry them to their logical conclusion.struck me as insufficiently polite. That's all.
Having worked some with C#, I'd agree that delegates are quite a useful feature to have in the toolbox. But as others may point out, they are the poor man's form of closures. Give functions first class citizenship in the language, and you obviate the need for a special syntactical construct to addresses this one particular need.
BTW I have meet Don once (though given the situation I doubt he would remember) when he came to Israel to deliver a presentation on SOAP and stuff a few years ago. I do have to say that he is one of the best presenters I have ever witnessed. I have also found his book on COM to be one of the better ones.
These debates are, almost by definition, adversarial in nature. If you present an opinion online, especially a technical one, you should be prepared to face criticism. If you don't like the heat get of the kitchen. Don does not need my validation, but when he expresses an opinion I find a bit lacking, I too will express my POV. And I have found that such POVs when presented a bit forcefully, and with a bit of humor, tend to inspire more interesting debates. I'm sorry this time the debate went the wrong way.
Getting back to the technical issue, I find it surprising that the C# compiler is able to provide automatic boxing and unboxing, yet is not smart enough to implicitly insert new Predicate given the original example. I also liked the extensions the C# iteration syntax, but again found it surprising they did not go all the way given the introduction of anonymous delegates (AKA lambdas).
Given Microsoft's power in the software development field, the huge investment they have made in introducing new technologies to developers, and their investment in PL research, I'm a bit disappointed that they haven't leveraged this to introduce obviously useful techniques. They could have introduced these techniques gradually, in a take-them-or-leave-them approach. Maybe they thought this would be too out-there for the average Windows developer. If so, I find that insulting.
And Don Box, given his position as architect at MS, shares the blame for such design decisions.
</rant>
Interesting that Don says he came to FP through XSLT. It's likely that a programmer using XSLT to translate between some XML data and an XHTML report will end up applying some basic FP principles, even if it's only by accident. Although it's possible to completely miss the point, and end up nesting loads of <xsl:for-each> tags instead. I've read too many on-line tutorials that actually encourage this.
As has been noted here before, another way in to FP for programmers who can't be persuaded simply to start learning Scheme is via one of the scripting languages that support first class functions - Python (even without the broken lambda), Ruby (which has real closures, in the form of blocks), Javascript and so on. Don doesn't say what his example code is really an example of, but you don't have to be an FP maven to recognise a filter function when you see it:
public delegate bool Predicate (object value);
public sealed class Tester2 {
static IEnumerable<object> Generate(Predicate p) {
List<object> list = new List<object>();
foreach (object o in MyGoop) {
if (p(o))
list.Add(o);
}
return list;
}
}
being roughly equivalent to Python's
class Tester: def Generate(self, aPredicate): return [o for o in self.MyGoop if aPredicate(o)]for instance...
Tester.Generate = function(aPredicate) {
return this.MyGoop.filter(aPredicate);
};
Well, ok, its three lines, but I could have written it as one line ;-)
Even if you add explicit type info the BeyondJS code snippet, it would still come out much shorter than the C# example. And IMO a lot more readable, even to someone unfamiliar with FP.
One nice feature of BeyondJS is that you can use only as much FP as you feel comfortable with, using plain old imperative JavaScript for the rest. I think MS could have easily done the same with C#. In the long run, they would have done the development community a great service. They would have also one-upped Java.
True, you can develop an app for .NET using C# and Mondrian or S# or whatever in conjunction. But realistically, I don't think this is going to happen all that often. Functional features within C# itself would have been much more approachable.
And I still think that automatic "boxing" of functions as delegates is a no-brainer.
Even if you add explicit type info the BeyondJS code snippet, it would still come out much shorter than the C# example
Type inference would be even better...
Also, I wonder if JScript.NET's type inference would be up to that task.
Well, that's a bit of a strong conclusion, I'd say. Microsoft has lots of "architects" and lots of projects. Should we blame Don Box for the shortcomings of their OS, their browser and their media player as well? Better yet, Simon Peyton Jones works for MS, too, let's blame him for C#'s shortcomings! (I always knew that one day Simon would let us all down...)
Indeed. And given that these anonymous methods support closures (or so it seems), I ask again, why that whole iterator thing? Why not just pass an anonymous function to a map-like construct? Or, at least, support both.
I wonder if JScript.NET's type inference would be up to that task
AFAIK JScript.NET does not have type inference. Instead it supports untyped references, that is references to variables whose type is specified at runtime. Sort of like Frank's U definition.
Notice the anonymous method in my Obfuscated C# post relies on the new C# compiler's ability to do the type inference in most cases.
Specifically, the new DelegateType(...) is not needed when using an anonmymous method UNLESS the type inference relies on return-type. I can't recall the last time I needed to do the explicit-style delegate passing but I know there are scenarios where the compiler doesn't have enough context to do the inference without a hint.
And while I'm happy to take heat for anything MSFT does (remember the asbestos skivies), my day job is as an architect on the XML messaging team, which is somewhat removed from the CLR and very removed from the languages teams at Microsoft. That stated, I am a very vocal user :-)
DB
Cool, I hadn't noticed that. But note the following quote from this page:
... while type inferencing provides performance improvements, it won't help you catch type mismatch errors or other programming errors. To overcome this, JScript .NET provides a way to explicitly declare a variable as being of a particular type.
Type inferencing in JScript.NET is a code optimization feature only. I believe that most people in this forum view type inferencing primarily as a mechanism to verify correctness.
Also, as I've pointed out in the past, I have some issues with JScript.NET
I had actually noticed that when you use the delegate keyword to declare an anonymous method you don't need to apply the new operator. This reinforces my question as to the need to explicitly invoke it for named methods.
... my day job is as an architect on the XML messaging team, which is somewhat removed from the CLR and very removed from the languages teams at Microsoft.
This is an interesting statement given how BEA, for example, are building XML support into their implementation of ECMAScript (E4X).
I also recall something about a .NET PL with intrinsic XML support. X# or something.
Dan asked, "why that whole iterator thing?". I would imagine that the short answer is, "because that's the way Java does it". True, the STL has iterators too; but it has them in a context where generics are supported from the outset (that's why it's the Standard Template Library) and you don't have to deal with an IEnumerator.Current() that always returns an Object that you then have to cast to a Foo before you can do anything with it...
Incidentally, does anybody know if VB.NET is going to support generics? If not, how's it going to work with C# assemblies that do? Parameterise everything as Foo<Object>?
I also recall something about a .NET PL with intrinsic XML support. X# or something.
I fail to see what any of this has to do with XML messaging, as in XML-RPC, SOAP, and web services...
I fail to see what any of this has to do with XML messaging, as in XML-RPC, SOAP, and web services...
If I were using ECMAScript on either the server or the client to read and write XML documents for passing backwards and forwards over HTTP, I'd be quite pleased about the addition of some handy DOM-traversal methods. If I were using SOAP plus some software tool that automatically lathered up method invocations on my C# objects, I wouldn't care about it at all.
Intrinsic XML support is besides the point if you never see any XML because it's just being used as a behind-the-scenes encoding for an RPC mechanism. But it's very much to the point if you're doing REST-ful, document-centric web services, particularly if you want ordinary browser clients to be scriptable in ways that allow them to take advantage of such services.