Primitives in Generics

Pavel Minaev int19h at
Fri Jul 9 16:18:08 PDT 2010

On Fri, Jul 9, 2010 at 4:00 PM, Neal Gafter <neal at> wrote:
> On Fri, Jul 9, 2010 at 3:36 PM, Pavel Minaev <int19h at> wrote:
>> C# lambda expressions and anonymous delegate expressions are not of
>> delegate types. C# 4.0 language specification, section 7.15 "Anonymous
>> function expressions":
>>    "An anonymous function is an expression that represents an
>> “in-line” method definition. An anonymous function does not have a
>> value or type in and of itself, but is convertible to a compatible
>> delegate or expression tree type."
> That is compatible with what I described.  Any given lambda expression in
> any given valid C# program has a delegate type which is selected by
> target-typing.  But the target type is required (i.e., the lambda does not
> have a type in and of itself independent of the target of the conversion).
> BGGA works that way too; that aspect of project lambda does not bother me at
> all.

You previously wrote:

> what is Brian is now calling a lambda expression is neither lexically scoped nor function-valued ...
> because they aren't of a function type, which is because function types have been dropped.

We have already established that neither proposed Java nor C# lambdas
have function types per se, but obtain them via target-typing. So your
claim then boils down to "SAMs are not function types". And why aren't
they? Why shouldn't C# delegate types rather be treated as mere
syntactic sugar for a single-method interface or abstract class?

>> So far as I can see, C# has precisely the same limitations here as the
>> proposed no-function-types-but-SAM-conversion for Java.
> C# lambdas bind names lexically.  The proposed lambdas do not.

Do you mean SAM type members?

> C# lambdas bind "this" lexically.  The proposed lambdas do not.

I don't like it, either, and hope it will be changed by the time of
release, but it's far from being a major issue, in my opinion.

> C# "function types" (delegates) are typically defined to be covariant in
> return types and contravariant in argument types.  SAMs cannot be so
> defined.

That boils down to declaration-site variance in C# vs use-site
variance in Java. SAMs cannot be so defined, but nothing prevents you
from using wildcards when referencing them to achieve the same effect.

> C#'s generic delegate types such as Func<Arg,Return> can specialize over
> primitives and over different numbers of arguments.  SAMs cannot.

That is a separate problem which is also much broader, and should be
solved as such (i.e. reify generics, then you get that for function
types for free - any other solution is going to be partial, anyway).

> C# lambdas can bind mutable local variables.  The proposed lambdas do not.
> C# lambdas can infer lambda argument types even when passed as an argument
> to an overloaded method.  The proposed lambdas do not.

Both are negative, I agree.

But, anyway, I do not want to get into the discussion on all those
points, here. I only wanted to clarify the claim that dropping
structural function types somehow changes the status of lambdas such
that they are no longer proper closures.

More information about the lambda-dev mailing list