4

Suppose we have a domain in which we can generalise some operation by passing in a function, like the Select \ map functions. Now suppose that the function we pass in has some domain specific name, and fixed parameter types. Let's call it a BazFunction

We can approach defining a BazFunction in two ways:

  • As a delegate: Bar delegate BazFunction(int x)
  • As a lambda: Func<int, Bar>

Their usage when calling the operation is identical (Foo((x) => x)) but the function definition is different

public Bar Foo(Func<int, Bar> baz) 
public Bar Foo(BazFunction baz)

The obvious benefit of using a delegate is the readability, at least to somebody familiar with the domain.

What are the cons of such an approach? Both technical and non-technical.

2
  • 6
    Func<T, U> is also a delegate, and not a lambda - it just happens to be one which is defined in the BCL. A lambda is a function object defined using the lambda syntax - i.e. x => x + 5;. I think what you actually mean is "Should I use a delegate from the BCL or define my own?" Mar 29 '16 at 14:08
  • Yes, that's almost exactly what I was trying to get at, you've just managed to word it a lot better than I.
    – Andy Hunt
    Mar 30 '16 at 8:31
5

I do functional programming full time, where higher-order functions are used frequently. If other languages have features that let you write code like your delegate style, I have never seen it used, because it is completely unreadable.

I can look at a function signature like public Bar Foo(Func<int, Bar> baz) and instantly know how to call it, without having to refer to any other documentation, or tax my memory. baz gives it a concise, helpful semantic name as to its purpose. It has that ugly parameterized type syntax, but that's a C-family legacy because they insisted on putting their type signatures first.

On the other hand, public Bar Foo(BazFunction baz), looks prettier, but is completely useless. You have to look elsewhere to find out how to actually use the thing. You give it a type name that's redundant with the parameter name. Also, I don't know how to declare one of these delegates, but I'm guessing it involves a bit of annoying boilerplate, for something maybe only used in one or two places.

Of course, OO programmers are more accustomed to having things like boilerplate interface declarations separated from where they are used, so it might not be as big of a deal. That doesn't mean it isn't a usability issue, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.