Discussion: Inferred "Quantum" Lambdas #1694
-
Lambda expressions are currently not supported for local variable inference. This is because the signature of the lambda expression does not indicate the type of the delegate which is necessary to create an instance of that delegate type. What if the compiler didn't have to actually know the delegate type at the time that the variable is declared? What if the variable could have a form of "pseudo-type" based on its signature and the compiler could "collapse the wave function", as it were (hence the name), at the point that the instance needed to be converted to a delegate? Here's an example with captures, which isn't very different: public void M(bool b, int x) {
var f = (int y) => x == y;
if (b) {
M1(f);
}
else {
M2(f);
}
}
public void M1(Func<int, bool> f) { }
public void M2(Predicate<int> p) { }
// under the hood
[CompilerGenerated]
private class $DisplayClass {
public int x;
public bool $M(int y) {
return x == y;
}
}
public void M(bool b, int x) {
var displayClass = new $DisplayClass();
displayClass.x = x;
if (b) {
Func<int, bool> $temp1 = displayClass.$M;
M1($temp1);
}
else {
Predicate<int> $temp2 = displayClass.$M;
M2($temp2);
}
} Here's an example without captures: public void M(bool b) {
var f = (int y) => x % 2 == 0;
if (b) {
M1(f);
}
else {
M2(f);
}
}
public void M1(Func<int, bool> f) { }
public void M2(Predicate<int> p) { }
// under the hood
[Serializable]
[CompilerGenerated]
private sealed class $C {
public static readonly $C _c = new $C();
public static Predicate<int> _p;
public static Func<int, bool> _f;
internal bool $M(int x) {
return x % 2 == 0;
}
}
public void M(bool b) {
if (b) {
Predicate<int> $temp1 = $C._p ?? ($C._p = $C._c.$M);
M1($temp1);
}
else {
Func<int, bool> $temp2 = $C._f ?? ($C._f = $C._c.$M);
M2($temp2);
}
} Advantages:
Disadvantages:
While typing this up I believe I've come to the conclusion that it's not a terribly good idea. But whatever, tear it up folks! |
Beta Was this translation helpful? Give feedback.
Replies: 44 comments 4 replies
-
I like your unspeakable types notation. $DisplayClass is easier to type than something like |
Beta Was this translation helpful? Give feedback.
-
@bbarry Not to mention you can read it without trying to pick the dots out of a wall of angle brackets and underscores. |
Beta Was this translation helpful? Give feedback.
-
I believe C++ does something similar with Trying to get a literal to target-type to the appropriate thing is hard enough when the literal is actually inline, but when it's in a variable you end up with "spooky action at a distance" (to continue the quantum superposition metaphor 😉). |
Beta Was this translation helpful? Give feedback.
-
I largely agree. The only problem with those assumptions is that |
Beta Was this translation helpful? Give feedback.
-
I think the cleanest solution would be inferring a native function type: |
Beta Was this translation helpful? Give feedback.
-
Internally there would need to be a more generalized concept of lambdas than exists today ( In that case, why not expose it somehow? lambda(int => bool) f = (int y) => x == y; Then (perhaps) you could return it, pass it as a parameter, declare it as a field, etc. |
Beta Was this translation helpful? Give feedback.
-
If you have to write the type, the point is lost anyway. Someone still needs to work out the inference algorithm. |
Beta Was this translation helpful? Give feedback.
-
That could be true for any (Edit... I say it is more complex, but I'm not sure I really believe it. The inferred type of |
Beta Was this translation helpful? Give feedback.
-
If we really don't want a new keyword: delegate(int => bool) f = (int y) => x == y; |
Beta Was this translation helpful? Give feedback.
-
@bondsbw what about |
Beta Was this translation helpful? Give feedback.
-
@bbarry Like (assuming you meant |
Beta Was this translation helpful? Give feedback.
-
yes (edited) I mean I'd propose to do exactly that: the
could simply exist and be inlined by the compiler wherever that identifer exists in scope (edit: as @agocke implies there is a devil here in identifying type information within this statement). (not actually suggesting this, I personally think this proposal is of very little value) |
Beta Was this translation helpful? Give feedback.
-
That's precisely what |
Beta Was this translation helpful? Give feedback.
-
An |
Beta Was this translation helpful? Give feedback.
-
Why should there be any additional syntax then for that? Why not merely relax the language from:
to:
and then add something like: If the initializer expression is a lambda_expression, the following process is invoked:
|
Beta Was this translation helpful? Give feedback.
-
Many of my delegates are quite a bit younger than |
Beta Was this translation helpful? Give feedback.
-
What does this really buy over imbuing the language with knowledge of the underlying method group? |
Beta Was this translation helpful? Give feedback.
-
it would be much simpler to provide, for one. |
Beta Was this translation helpful? Give feedback.
-
The question is not if they're used or not. The question is: is there enough value from just getting Func/Action working as to make this 'good enough'. IMO, i think it would. For the other cases, you can still do what you do today. i.e. using a local function, or just using a named-type when supplying the lambda. Note: i completely agree the quantum-lambda approach is more powerful and would handle more scenarios. But i also think it's less likely to happen, and the power it provides isn't worth the cost. So i'm reproposing narrowing things down to something that would be quite easy to provider, and which which would support many scenarios. Also, note that my suggestion doesn't not eliminate the possibility of doing quantum lambdas. Indeed, they are complimentary. |
Beta Was this translation helpful? Give feedback.
-
If |
Beta Was this translation helpful? Give feedback.
-
I agree. For one thing, Predicate reads better than the word "func". But putting that aside, I can see why it's nice to name the delegate sometimes and especially name the arguments or even provide a doc. I think in an ideal world, there would be first-class function types, and if you wanted to name them, you would use global type-aliases. But they'd still be compatible. And many times, you wouldn't even need that as much if these function types had optional names similar tu tuples... What a nice dream 😄 |
Beta Was this translation helpful? Give feedback.
-
'var f' woudl be resolved to |
Beta Was this translation helpful? Give feedback.
This comment was marked as spam.
This comment was marked as spam.
-
@Makeloft Check what you quoted. Your solution forces a delegate type, which this proposal is trying to avoid. |
Beta Was this translation helpful? Give feedback.
This comment was marked as spam.
This comment was marked as spam.
-
The comments from As a general note: Repeatedly advertising your own repository as a solution to most language proposals, after being warned, is deemed to be "unprofessional conduct"; as is attempting to circumvent a ban. The Code of Conduct is expected to be followed by all contributors/posters to The |
Beta Was this translation helpful? Give feedback.
This comment was marked as disruptive content.
This comment was marked as disruptive content.
-
I think lambda should be quantum and anonymous all along. It was a mistake to have it must be typed when it could have duplicate signature We should starting to deprecate the old delegate system |
Beta Was this translation helpful? Give feedback.
-
The only problem I see with this is the confusion of What I would be in favor of is The only options I could make sense with:
I'm pretty sure there can be a better idea for that keyword in question. |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
#1694 (reply in thread)