Skip to content

Latest commit

 

History

History
75 lines (59 loc) · 5.89 KB

LDM-2020-12-02.md

File metadata and controls

75 lines (59 loc) · 5.89 KB

C# Language Design Meeting for December 2nd, 2020

Agenda

  1. Partner scenarios in roles and extensions

Quote(s) of the Day

  • "Have you noticed how similar what you just said is to function pointers?"
  • "This is a modern version of COM aggregation." "But in a good way."

Discussion

Partner scenarios in roles and extensions

Today, we heard from partner teams on the Azure SDK and on ASP.NET, talking about friction they currently encounter with some scenarios that might be addressable through roles, extension everything, or potentially some other solution.

ASP.NET Feature Collections

ASP.NET models contexts through an aggregation system that allows different services to be composed onto a single HttpContext. For example, adding TLS to a session involves creating a TLS connection, wrapping the existing connection, and adding it as an available feature to the context. This underlying connection could be one of several types connections: it could be routed through a socket, or it could be in-process, or any of a number of other connection mechanisms, each with its own set of properties. It is possible to retrieve each of these sets of features from a Get method on the context, but this is cumbersome and not generally extensible: for their users, it would be nice to be able to expose a view over a context or connection that exposed the underlying properties.

This scenario seems like a clear-cut use case for roles and extension-everything as we last discussed them. A role could be used to expose a grouping of properties on an upper layer from a lower layer. In fact, the ASP.NET architecture was designed with the eventual intention of using extension properties to remove a number of extension methods that they have in place today to expose these underlying properties from a decorated type. Of the 3 scenarios we discussed today, this seems the most obviously-addressed by the existing proposal.

Azure SDKs

The Azure SDK scenario presents a more interesting challenge. Feature collections were designed with C# in mind, meaning that both types and type names were thoughtfully designed when creating the API. The Azure SDK (and by extension many web APIs), by comparison, are designed in a web-first manner. In this context, property names are important, and general structures of an API are important, but names of these structures are not important. These APIs are often described and generated using Swagger, which uses JSON to describe the structure of a response. JSON structures can be strongly typed, of course: the structure itself is the type. But the nested properties of a JSON object, which can be nested objects themselves, are described entirely in a structural manner, not in a nominal manner as we do in C#. Here, C#'s paradigms break down, and the SDK teams run into trouble when creating a C# API to wrap this structure. All of these nested structures need to be named, so that C# can talk about them. This leads to an explosion of types, which can be made even more difficult when you consider identical structures developed by different teams (perhaps even different companies). By necessity, each team will need to create their own "named" data structure to give C# an ability to talk about the object, but these names are really meaningless. The JSON didn't have this name, and the structures cannot unify. There are also scenarios with very similar objects (perhaps one object has an extra field that the former does not have). This necessitates an entirely new object to be created, and users often end up needing to write boilerplate methods that just translate objects from representation A to B, changing nothing about the data other than making sure the type's name lines up.

This set of scenarios is not addressed by roles and extension methods, as they currently stand. We theorized that teams might be able to a combination of dynamic and a custom completion provider/analyzer, to give users help in writing and validating code that is, in essence, a set of dynamic calls to nested properties of unnamed types that does have a structure, but this is a complicated solution to the scenario that is likely not generally-leverageable. There are more IDEs than just VS, and more IDE scenarios than just completion: what would go-to-def do on these, or quick info on hover?

Data Processing

Finally, we took a look at a small proof-of-concept library exploring what replicating parts of the popular Python library Pandas could be like in C#, with stronger typing around the data generated from a given input. This scenario is very reminiscent of F# type providers, allowing users to simply dot into a data structure. However, it suffers from the same set of issues that affect the Azure SDK scenarios above. In order to talk about nested data structures, they have to be named. And while the Azure examples entirely focus on the types of structures representable in JSON, Pandas is far more flexible. Additionally, Pandas allows you create new objects as they flow through a pipeline, adding or removing properties as they are manipulated.

Looking at these last two examples, it seems that there are some scenarios not served well by C# today, involving JSON or other structured but unnamed data. These scenarios care deeply about the names of properties, and the structure attached to each property name, but the domains these scenarios interact with do not care about naming these structures. Further, adding names to these structures in C# can be harmful, because it locks out scenarios that can be accomplished in the original domain and forces a naming structure where none was intended, which can result in confusing or badly-named types that can then never be changed because of backwards compatibility concerns. As we continue to evolve the roles and extension everything proposals, we should look at these scenarios and see if there are ways to improve the experience for them.