-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: let-in construct in C# #3718
Comments
I find that syntax not intuitive at all. If I understood your intentions correctly, declaration expressions (#254) is what you're looking for:
|
@paulomorgado Nevertheless I would prefer let-in as it does not imply imperatively evalutation order, rather works on dataflow natural evalution order: computing aliased expression and then the real expression which is defacto function of the aliased expression. Other benefit of using aliasing semantics is that it can be easily interpreted by LINQ providers (by simple substitution) contrary to implementing Sequential-Evaluation Operator support which is actually much more expressive (closer to the statement list which I am trying to avoid in the first place here). |
BTW. I am definitely not insisting on this specific syntax. There are many ways to make it more C#-pish. Just proposing the mechanism that C# lacks in my opinion. Maybe even the syntax suggested by @paulomorgado looks way better and more intuitively. |
The proposals for declaration expressions on CodePlex did include semi-colon expressions: int foo = (int bar = baz(); bar * bar); // assign foo to the square of the result of baz() This feature was never fully fleshed out and was on the list to be punted before declaration expressions were cut entirely. With the clock reset and time to perhaps work through the other details (like scope) perhaps it would be reconsidered. Much of this smells like a weird expression version of |
@HaloFour In this issue: #115 there is a discussion regarding let keyword used as "readonly var". In think it would be worth to consider adding let with two syntaxes: let foo = bar(); as a readonly local declaration statement: var a = 2 + (let foo = bar() in foo.baz()) as an expression with semantics mentioned before. I didn't write it, but my proposal assumes that variable declared is readonly. Of course underlying object can be mutated by method calls. |
Your x => ((tmp => new {
A = tmp.Field1,
B = tmp.Field2,
C = tmp.Field3 == 5 ? tmp.Field1 : tmp.Field2
})(CostlyFunction(x))); |
But with declaration expressions there won't be a delegate nor a delegate instantiation nor a delegate invocation. Not even a method. |
@orthoxerox But:
|
Is it possible to make the inner portion of the let be a kind of function body? That is feeling I get when I look at this proposal, but that may just be because I have passing knowledge of this kind of construct from Clojure and other Lisps. let args*{
//let body
} usage let( temp=SomeFunction()){
A=temp.F1;
B=temp.F2;
} |
This should be closed as it addressed by #6182. x => (var tmp = CostlyFunction(x); new {
A = tmp.Field1,
B = tmp.Field2,
C = tmp.Field3 == 5 ? tmp.Field1 : tmp.Field2
}) |
This will diagnose a common typo of omitting a comma in a switch expression.
Especially #6182 makes "let-in" redundant while being much more C#-pish, elastic and compatible with approach used in top-level expressions/scripting and has better scoping, it is also shorter. |
@mkosieradzki Do you want to close this, then, in favor of #6182? |
Definitely |
I digged the issues database trying to find this one, but I failed. It's quite obvious one and very common among functional languages. So it is probably a duplicate but...
Rationale
I am writing a lot lambda expressions in every day code. I try to keep code as functional as it is reasonable. So most of my lambdas are expression lambdas and it could have stayed this way if... for peformance reasons I want to prevent multiple evaluations of some parts of expressions. Let's take a following example:
In this case reasonable workaround is:
But proper solution:
It's effient, clear. In case of LINQ it allows easily analyze this code by simple subsititution of referenced variable with proper definition expression.
We can use also multiple statements in such situation.
In case simplicity is desired in System.Linq.Expressions. Null-coalescing operators could be implemented using
let a = expr1 in a != null ? a.expr2 : null
Great point it allows to express a lot of concepts clearly and efficiently without falling back to statement lambdas what is a great value itself.
The text was updated successfully, but these errors were encountered: