C# Design Meeting 2015-03-25 ============================ Discussion thread for these notes can be found at https://github.com/dotnet/roslyn/issues/1572. These are notes that were part of a presentation on 2015-03-25 of a snapshot of our design discussions for C# 7 and VB 15. The features under discussion are described in detail in #206 and elsewhere. [Records](https://github.com/dotnet/roslyn/issues/206) ======= Changes since Semih Okur's work: - Remove `record` modifier - `with` expressions (#5172) - Working on serialization Working proposal resembles Scala case classes with active patterns. ------ ```cs class Point(int X, int Y); ``` - defines a class (struct) and common members - constructor - `readonly` properties - GetHashCode, Equals, ToString - operator== and operator!= (?) - Pattern-matching decomposition operator - an association between ctor parameters and properties - Any of these can be replaced by hand-written code - Ctor-parameter and property can have distinct names ------ ### Use Cases - Simplifies common scenarios - Simple immutable user-defined data types - Roslyn Syntax Trees, bound nodes - Over-the-wire data - Multiple return values ------ ### With expressions Illustrates an example of the value of having parameter-property association. Given ```cs struct Point(int X, int Y); Point p = ... ``` the expression ```cs p with { Y = 4 } ``` is translated to ```cs new Point(p.X, 4) ``` ------ ### Open issues - Closed hierarchy (and tag fields) - Readonly - Parameter names - Can you opt out of part of the machinery? - Serialization (in all of its forms) - Construction and decomposition syntax ------ [Pattern Matching](https://github.com/dotnet/roslyn/issues/206) ================ ### Sources of Inspiration - Scala - F# - Swift - Rust - Erlang - Nemerle ------ ### A pattern-matching operation - Matches a *value* with a *pattern* - Either *succeeds* or *fails* - Extracts selected values into *variables* ```cs object x = ...; if (x is 3) ... if (x is string s) ... if (x is Point { X is 3, Y is int y }) ... if (x is Point(3, int y)) ... ``` ------ ### Other aspects - Patterns defined recursively - "select" from among a set of pattern forms - Typically an expression form - *active patterns* support interop and user-defined types ```cs switch (o) { case 3: ... break; case string s: M(s); break; case Point(3, int y): M(y); break; case Point(int x, 4): M(x); break; } ``` We think we want an expression form too (no proposed syntax yet, but for inspiration): ```cs M(match(e) { 3 => x, string s => s.foo, Point(3, int y) => y, * => null }) ``` ------ ### Benefits - Condenses long sequences of complex logic with a test that resembles the shape of the thing tested ### Use Cases - Simplifies common scenarios - Language manipulation code - Roslyn - Analyzers - Protocol across a wire ------ ### Open questions - How much of the pattern-matching experience do we want (if any)? - Matching may be compiler-checked for completeness - May be implemented using tags instead of type tests - Which types have syntactic support? - Primitives and string - Records - Nullable\ - objects with properties - anonymous types? - arrays? - List? Dictionary? - Tuple<...>? - IEnumerable\?