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

C# Design Notes for Feb 4, 2015 #396

Closed
MadsTorgersen opened this issue Feb 11, 2015 · 13 comments
Closed

C# Design Notes for Feb 4, 2015 #396

MadsTorgersen opened this issue Feb 11, 2015 · 13 comments

Comments

@MadsTorgersen
Copy link
Contributor

C# Design Meeting Notes for Feb 4, 2015

The design notes can be found at https://github.com/dotnet/roslyn/blob/master/docs/designNotes/2015-02-04%20C%23%20Design%20Meeting.md

Discussion on these design notes are in this issue.

@weltkante
Copy link
Contributor

I hope you are aware of the work in this article and blog post

Unfortunately their implementation is not public but he claims they were able to lift immutability to a modified C# language and use it extensively for optimizations and parallelism. Since it's within Microsoft there should be a possibility for collaboration.

It would be a shame if you designed yet another system without being aware of what has already been done in Microsoft Research groups. In particular since their system allows for a lot of performance optimizations over current C#. In point 4 of his blog posts he mentions "being able to easily carve out sub-arrays and sub-strings without allocating".

@stephentoub
Copy link
Member

@weltkante, yes, thanks, members of that team are very involved with this effort.

@svick
Copy link
Contributor

svick commented Feb 11, 2015

Would the "withers" syntax work for mutable types too? I think that would get pretty confusing.

For example, it's nice that for immutable Person, I can write something like:

var employee = new Person { Employer = "Initrode" };
var doe = employee { Name = "John Doe" };
var deere = employee { Name = "John Deere" };

But exactly the same code would also work for mutable Person and would mean that doe and deere are the same object (with Name = "John Deere").

@MadsTorgersen
Copy link
Contributor Author

@svick: that's a great point. This is part of the reason why we don't allow object initializers on arbitrary expressions today.

@MgSam
Copy link

MgSam commented Feb 12, 2015

Kudos on thinking so creatively- this is quite the list of features being strung together in this proposal.

That being said, I'm not sure having a member named "Value" initiate all sorts of magic compiler behavior makes a lot of sense. I think C# should avoid special-case compiler magic at all costs as it makes code a lot harder to read and reason about. I think, at minimum, a new keyword to key the behavior should be required.

Some other thoughts:

  • Requiring all of an objects parameters and/or properties to be funneled through a single member to get the new behavior seems like quite a constraining design.
  • It's unclear to me from the design notes what the Value member brings that making the "real" class get the new behavior doesn't. The Value member is an immutable struct, right? So if Value is immutable anyway, it's not truly a builder; why not just make the "real" class immutable and use a with keyword?

@JesperTreetop
Copy link

I agree with @MgSam - this is extremely promising.

What I would add is that if this class-and-nested-struct thing will have to rely on neither thing doing anything potentially troublesome, I'd much rather see that the struct would be generated and managed and probably even hidden by the compiler. So, for example, instead of:

    public class Person 
    {
        public readonly PersonValue Value;
        public Person(PersonValue value) { Value = value; }
        public string Name => Value.Name;
        public int Age => Value.Age;public struct PersonValue
        {
            public string Name;
            public int Age;
        }
    }

...it could become:

    public immutable class Person 
    {
        value string Name;
        value int Age;}

All the constructors, builders, withers would be generated from that, as would the inner struct, if that is indeed how it is managed.

Of course, the problem then becomes - what distinguishes those classes from records? Well, the current record syntax doesn't allow implementing interfaces or other methods, properties or operators, all of which would potentially be very useful. (And some which could indeed be stapled on from the side with extension methods.) Inheriting a base class could also potentially be useful, although I guess the constructor chain would be troublesome to manage - compiler-generated stuff overriding manually written stuff!

Maybe the right thing is just to use the record syntax and allow the record class to implement some other stuff with a class definition. Defining new constructors would be forbidden, but implementing interfaces, most of the operators (aside from pattern matching and maybe implicit conversion) and most types of methods and getter members would be allowed.

@paulomorgado
Copy link

@JesperTreetop, the current record syntax allows having a base class, implementing interfaces and having other members.

@MgSam
Copy link

MgSam commented Mar 10, 2015

Are there any additional design notes forthcoming since Feb 4?

@drewnoakes
Copy link
Member

+1, I really enjoy reading the notes from these design sessions.

@MadsTorgersen
Copy link
Contributor Author

I'm a little backlogged on notes, as I've been away for a couple of weeks. Just posted one more set, and there are more to come.

@danfma
Copy link

danfma commented Mar 12, 2015

The builder idea is cool and it could be used to generate some kind of DSL for a lot of things, like building an UI or something like a type safe HTML construction, for example.

@svick
Copy link
Contributor

svick commented Mar 12, 2015

@danfma Aren't the existing object initializers enough for that?

@gafter
Copy link
Member

gafter commented Nov 21, 2015

@gafter gafter closed this as completed Nov 21, 2015
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