4 ms·
> It isn't, that's why there's a blog article documenting how unexpected it is. The behaviour is expected for the language design. Whether developers using the
by cbsmith 1y ago
> It isn't, that's why there's a blog article documenting how unexpected it is.
The behaviour is expected for the language design. Whether developers using the language expect it is a separate matter.
The with operator clearly allows someone to break encapsulation and as such should only be used in cases where you aren't expecting encapsulation of the underlying record.
> It's probably worth reading the article:
> "Note that because Value is set after the cloning operation, we couldn’t write a copy constructor to do the right thing here anyway."
It's probably worth reading the entire article, as that quote is followed by: "(At least, not in any sort of straightforward way – I’ll mention a convoluted approach later.)", which presumably was what was being referred to there.
In general, there's a whole ton of gotchyas around encapsulation of precomputed values. That's just life outside of a purely functional programming context.
- louthy 1y ago> The behaviour is expected for the language design. So, Microsoft meant it. Ok... > Whether developers using the language expect it is a separate matter. Really? Perhaps read the 'Principle of Least Astonishment' [1] to see why this is a problem. If I create a new object I would expect the 'init time' properties to be initialised. > It's probably worth reading the entire article, as that quote is followed by: "(At least, not in any sort of straightforward way – I’ll mention a convoluted approach later.)", which presumably was what was being referred to there. It's probably worth continuing to read the article. Because the attempt to deal with it required manual writing of Lazy properties: private readonly Lazy<ComputedMembers> computed = new(() => new(Value), LazyThreadSafetyMode.ExecutionAndPublication); That's not practical. Might as well use computed properties. > In general, there's a whole ton of gotchyas around encapsulation of precomputed values. That's just life outside of a purely functional programming context. Great insight. Let's not run the 'init time' properties for a newly initialised object, just in case it works as expected. This 'feature' can't even be manually resolved by doing post-`with` updates (because often the properties are init/read-only). It makes the whole init-property feature brittle as fuck. [1] https://en.wikipedia.org/wiki/Principle_of_least_astonishment https://en.wikipedia.org/wiki/Principle_of_least_astonishmen...
- cbsmith 1y ago> Really? Perhaps read the 'Principle of Least Astonishment' [1] to see why this is a problem. If I create a new object I would expect the 'init time' properties to be initialised. The Principle of Least Astonishment definitely applies. It's a deliberate design choice that unfortunately violates the principle. > Great insight. Let's not run the 'init time' properties for a newly initialised object, just in case it works as expected. This 'feature' can't even be manually resolved by doing post-`with` updates (because often the properties are init/read-only). It makes the whole init-property feature brittle as fuck. ? I'm not sure I follow what you are going with here, but yeah, in general you'd have to carefully limit all uses of "with" for objects with precomputed values to inside the encapsulation of said objects. Alternatively, as you mentioned, you could just not have precomputed properties.
- louthy 1y ago> in general you'd have to carefully limit all uses of "with" for objects with precomputed values What you’re describing is incidental complexity. It is not a good thing. We can’t constrain the complexity with language constraints, we have to rely on the programmer following some guidance and never ever making a mistake. In large teams and large code-bases that's a problem. And it's an offloaded problem from Microsoft to every software development team on the planet that uses C#. The incidental complexity for the average C# developer has increased, whereas a better direction of travel would be toward correctness and declarative features. I would prefer it if the csharplang team worked toward that.
- cbsmith 1y ago> What you’re describing is incidental complexity. It is not a good thing. Yes.