Skip to content
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

Champion "pattern-based with expressions" #162

Open
5 tasks
gafter opened this issue Feb 22, 2017 · 14 comments
Open
5 tasks

Champion "pattern-based with expressions" #162

gafter opened this issue Feb 22, 2017 · 14 comments

Comments

@gafter
Copy link
Member

gafter commented Feb 22, 2017

  • Proposal added
  • Discussed in LDM
  • Decision in LDM
  • Finalized (done, rejected, inactive)
  • Spec'ed

In C# 9.0, we did with on records only, not some generalized pattern-based with expression.

See also

Design meetings

https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-09-26.md#construction-improvements

@orthoxerox
Copy link

Why is it tentatively planned for 7.2 if records themselves are in 8.0?

@gafter
Copy link
Member Author

gafter commented Apr 8, 2017

Records build on this, not vice versa.

@MadsTorgersen are you working on a proposal for this?

@alrz
Copy link
Contributor

alrz commented Nov 28, 2018

pattern-based

I assume it's not only for records (where we need a new instance). For regular objects I think this should also work:

e with { id = v }

->

(var _t = e; _t.id = v; _t)

We have the same situation as switch expression where we possibly want to use with as an statement.

@DavidArno
Copy link

@alrz,

Not sure if I'm misunderstanding your example, but if e is a class instance, then surely your wither will modify the original instance, rather than creating a modified copy?

@alrz
Copy link
Contributor

alrz commented Nov 28, 2018

@DavidArno

Yes, I think in the absence of a With method we could just modify the original instance, see #1879 for some examples where this is useful. In that case, with returns the same object on the left-hand-side, so you could return it or use it an statement.

db.Persons.Find(id) with { Name = data.Name, ... };

or simply

db.Persons.Find(id) with { data.Name, ... };

I think there is a need for null checked withers here which could be implemented via with? along with await? and foreach?.

@orthoxerox
Copy link

@alrz this will change with from a purely syntactic transformation like LINQ query expressions to a more involved one.

@DavidArno
Copy link

@alrz, I'd see update blocks as unrelated to this. Having a with expression modify the original data would be really bad in my view.

@Odonno
Copy link

Odonno commented Nov 28, 2018

I think like @DavidArno We should stay with the immutable state of the with keyword.

About the with? suggestion, it looks interesting but I think it is not that useful if we have the strict null-check feature in C#8.

@YairHalberstadt
Copy link
Contributor

I agree with @DavidArno
It would be confusing if sometimes with changes the original object, and sometimes returns a new one. It would be useful to have two different syntaxes.

@alrz
Copy link
Contributor

alrz commented Nov 28, 2018

@orthoxerox

this will change with from a purely syntactic transformation like LINQ query expressions to a more involved one.

Actually the pattern-based with is not that simple since we first need caller-receiver default-argument (mentioned in the records proposal) to substitute absent init values,

class Person {
  // ...
  public Person With(string name = this.Name, int age = this.Age) { ... }
}

So that something like person with { Name = "newName" } could be translated to:

(var _t = person; _t.With(name: "newName", _t.Age))

There is a lot more moving parts here but the simple initialization does not necessarily depend on it.

@DavidArno

Having a with expression modify the original data would be really bad in my view.

This is a known papercut that could simplify various applications and there's no alternatives for that either except for member-wise assignments.

@Odonno

We should stay with the immutable state of the with keyword.

The immutable state is not a property of With methods, so you could totally get around it as it's all user code, except if the class itself is defined as a "record".

I think it is not that useful if we have the strict null-check feature in C#8.

with? does not depend on NRT but it does affect it. We just produce a null check before member initialization and omit it in case of a null in LHS, much like the ?. operator.

@YairHalberstadt

It would be useful to have two different syntaxes.

I don't know what it buys you since there's no guarantee with pattern-based With methods, again, except if the class itself is defined as a "record".

@YairHalberstadt
Copy link
Contributor

@alrz
That's fair enough.
I agree with you proposal in that case.

@orthoxerox
Copy link

@alrz

Actually the pattern-based with is not that simple since we first need caller-receiver default-argument (mentioned in the records proposal) to substitute absent init values

But this will get taken care of by the great and powerful overload resolution like any other optional arguments, won't it?

@gafter gafter modified the milestones: 8.0 candidate, 9.0 candidate Apr 29, 2019
@jcouv jcouv changed the title Champion "pattern-based with expressions" Champion "pattern-based with expressions" (VS 16.8, .NET 5) Sep 1, 2020
@MadsTorgersen MadsTorgersen modified the milestones: 9.0 candidate, 10.0 candidate Sep 9, 2020
@jcouv jcouv changed the title Champion "pattern-based with expressions" (VS 16.8, .NET 5) Champion "pattern-based with expressions" Sep 9, 2020
@333fred 333fred modified the milestones: 10.0 candidate, 10.0 Working Set Oct 14, 2020
@333fred 333fred modified the milestones: Working Set, Backlog Sep 26, 2022
@WhitWaldo
Copy link

I would very much like to see this added to a future language version to accomplish my example here regarding using the with statement when implementing methods with generics.

@Lavshyak
Copy link

Lavshyak commented Dec 8, 2023

#7752 - another case when this will be very convenient. (I don't force you to do this, it's all up to you)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants