Open JeanCollas opened 6 years ago
Indeed, not easy to find if there is a relevant issue corresponding :)
However I prefer the use of a '.' than a keyword which does not look like C# syntax. As mentioned in #1434 it can be followed by a question mark '.?' to avoid null exceptions. So far I feel like keywords are more declarative in C#, where '.' which links properties of objects seems more appropriate.
Thanks for the links!
@JeanCollas Certainly not easy! No problem.
C# is adding many new keywords such as catch (Exception ex) when (ex.X == 42)
and case Foo foo when foo.X == 42
and besides x is null
, there are more proposed for pattern matching such as and
, or
and not
. Not to mention LINQ. A with
keyword seems consistent with those, doesn't it?
Now whether .
could be a better syntax than when
: maybe? I'm not fond of foo.{
which feels a little like we're heading toward ascii sneeze, but it's really not that bad and you make good points.
@jnm2
For what I have in mind, that kind of keywords in only filters/test, a bit like linq or SQL syntax, or could be declarative like if(oldVar is Type myVar)
.
Except for this case, not so many keywords are used for assignment shortcut/value handling, it is most of the time done by operators ( =>
, autoproperties {get;set;} = defaultValue
, ...)
That is the reason why I don't see it as a great improvement.
However I will still be fine of course if this is the final choice of the team, but I am afraid that C# gets too verbose/complicated instead of keeping it straight (like javascript syntax). The shorter is the code, the easiest to read it is, and keep the words for what really needs explanations (how is the method, how is the class, etc).
To focus on the with
keyword, I feel it would also be confusing as "does it returns the given object with updated values" or "does it gives a new object, copied from the given object, but also with the new values".
If you take a List<string>
for example, I would feel like
list.With("A", "B")
would give me a new list with merged content, and not the initial list with two new values.
Actually to be more precise, I would not expect a new list with merged content, nor an update of the list, but a VIEW of the original list, with these two additional values, like a new presenter of the object with overridden properties.
From what I see there: https://github.com/DavidArno/SuccincT/issues/44 it is already planned as ' with ' syntax for C#8. So I guess any discussion is now just almost vain :D
I do prefer the syntax proposed by @JeanCollas ... hope this is not too late to change our mind on the with
....
@JeanCollas,
Please don't go trusting statements made by random folk on the internet, especially when that random folk is me! 😀
with
syntax is currently assigned to the C# 8.0 bucket. But there is no guarantee that it will make it into that release and that release may still be a way off (7.3 is the next release, likely due in the next couple of months). So I'd say that the discussion is potentially far from over.
Isn't with
about creating a new instance with the same property values except for those explicitly specified in the initializer anyway? It's not the same as trying to use initializer-like syntax to modify the current instance.
There are some other proposals around supporting initializer syntax on expressions to support factory methods. That would probably be very similar to this proposal, sans the dot operator. But the team have also expressed little interest in the various proposals to promote mutation of the current state of an instance so I'm not convinced that such proposals have much in the way of legs at the moment.
@DavidArno I will take this advice seriously :D
I am not fan of the with
syntax solution, and I hope it will be improved.
@HaloFour It is actually not really clear to me. After more reading, I guess you are right. In that case, I believe this with
operator could lead to potential unexpected forbidden states, and shall be used carefully.
It would be nice if this could work to initializers, and to methods. I think that a WinForm code could eventually look structured with this proposal.
@JeanCollas,
I see MS proved my point about trying to guess releases of the language. On the very same day that I suggest C# 7.3 might appear in a month or two, they release C# 7.3! 😆
@Makeman-from-Makeloft Thanks for your message. I am not sure this exactly answers my issue with is more about simplified syntax/code structure, but it is very interesting on patterns. There are several new points I do not master enough yet. The Check/Match pattern looks nice
After a second read of this long post, I only half agree with this. It looks nice, but actually it induces some things similar to global variables / inline delegates that you actually cannot easily extract from the code. The possibilities are nice on a first approach, but a deeper reflection will make me not use them because it will look like quick and dirty solutions :/
For those who weren't around earlier: The banning has nothing to do with the workarounds he is suggesting. Personally, like @JeanCollas, we've seen (and tried to discuss) some drawbacks with them, but we are happy for anyone to look at them and use them if they like them. The reason the community would rather ignore Makeman/Makeloft is due to this person's blatant disregard for the code of conduct. This person is responsible for a series of both in-your-face rude comments and incessant spamming on threads that were not related, and he was recalcitrant to appeals. After many community members complained, the admins banned this person. He has since created dozens of sock puppet accounts and continued the spamming. In other words, all the signs say that talking to this person is a waste of time. 😟
Is there a place for a word like populate
in that syntax or can it be modified so? I think it's worth considering. But I like the idea and the syntax.
Isn't this sort've similar to a with
keyword in other languages?
public class MyLink
{
public string Name { get; set; }
public string Description { get; set; }
public string Link { get; set; }
public MetaData Meta { get; set; }
public void DrawLink() { }
}
...
public void UpdateLink(MyLink link, string name, string description, DateTime lastUpdate)
{
with link
{
Name = name;
Description = description;
with Meta
{
LastUpdate = lastUpdate;
}
DrawLink();
}
}
Basically, the with
keyword creates a block of code that behaves as if it is a part of that class, allowing you to access the fields and methods directly. It probably shouldn't expose private
fields and methods, though.
Regardless of if it uses .
or with
, might as well allow the usage of methods inside, right?
@AustinBryan I agree. Also, just a thought: instead of with
, how about scope
? Like scope (link) { }
. Also, I think the brackets are better suited for the language.
@AustinBryan I agree this is similar to with
, however having keywords in the middle of the code like this is not much like C#. Except maybe very last updates, there is no keywords inside the methods that modify the scope (using does, but the usage is quite clear).
My belief is that it shouldn't be like with or scope, because it induces some interferences if you can add code inside this scope, and how do you manage the following:
public string Name = "alpha";
public void T()
{
var s=new S() { Name = "beta" };
with(s)
{
Name = "gamma";
}
Console.WriteLine(this.Name);
Console.WriteLine(s.Name);
}
That is why I think this should not be treated as scope, but only as shortcut
public void UpdateLink(MyLink link, string name, string description, DateTime lastUpdate)
{
link.{
Name = name,
Description = description,
Meta.{
LastUpdate = lastUpdate
}
};
}
would be translated:
public void UpdateLink(MyLink link, string name, string description, DateTime lastUpdate)
{
link.Name = name;
link.Description = description;
link.Meta.LastUpdate = lastUpdate;
}
which seems quite obvious.
@JeanCollas I agree. with
feels way more high level and I really didn't like that language. (GML, had so many issues, like everything being implicitly an int
).
So a few questions, would you be able to call methods too, from within the block? I would think so. And would private
/protected
fields be visible? I'd say no.
What I like about this syntax is that it behaves consistently with if
braces. Whenever I see:
if (b)
{
// do stuff
}
I think, "just make it simpler and do this:
if (b)
// do stuff
And in your example, the braces for Meta
are unnecessary, I instinctively thought to remove them, which makes:
// braces
Meta.{
LastUpdate = lastUpdate;
}
// simplified
Meta.LastUpdate = lastUpdate;
Without the braces it's just simply the original syntax, which I really like. If we used with
or something, we'd have:
with (Meta) {
LastUpdate = lastUpdate;
}
// simplified
with (Meta) LastUpdate = lastUpdate;
And that does the exact same thing as the normal way, so there's no point in there being more than one way. That just confuses people.
I don't find any way to update several properties of a single object in C# (similar to the with VB statement). It may be useful to clarify some mapping functions where several properties has to be updated at once.
I believe a
.
is a very concise and clear way to handle such case, and that it should not require an additional keyword for this functionality.Here is a very short example
Although it might induce some recursive conflicts. The
UpdateLink
method would be translated by the compiler as:It can be used following factories calls
Only a
.
away from what people is already used to:It can easily handle null values to avoid exceptions: