you can't see the slides
you can see them all right hey hey
there's audio
there's light
hi everyone
uh Welcome to My Party
um my name is if you ask many people
many Danes in this room
if you want to know how to really
pronounce my last name you got to ask
some of the Norwegian organizers of the
conference I don't really know it's a
Norwegian one my American friends call
me mads
that sometimes you can't really hear the
S there I don't know what's up with that
the um
um but enough about me uh I work on C
sharp we're going to talk about C sharp
uh how many people here
use C sharp
okay one or two
good so it's an object-oriented language
you know it how many people don't just
it wasn't like a fool there's one there
good good
there okay all right
okay
um
so I'm probably gonna skew it a little
to people who know C sharp and then and
but do ask you know to come up after if
there's something like that was
interesting didn't understand that bit
um that goes for all of you
um
so I work on c-sharp on the design of
the language and uh
I will I'm going to show you some of
this in UC sharp every year it's kind of
crazy I mean it's C sharp 12 next I
can't keep up anymore because I work on
I always work on the next version except
right now I work and then you know the
thing that's out there the thing that is
about to ship and the thing that I'm
currently like thinking about there are
three different versions and they change
every year I'm too old for that I can't
I can't keep track anymore but the the C
sharp that comes out in November is C
shop 12 we'll show a few features from
that and I also thought I'd spent some
of the time since it's kind of getting
close and there's a lot of material out
there about the next C sharp
um I thought we'd spend some time
talking about things that we're thinking
about for the further future and that's
of course with all the caveats this may
never happen uh this is just a fever
dream in mads his head and it's never
gonna you know but I I thought that
would just be more fun and I'll do that
at the expense of some detail and not
showing all the features of c-sharp 12.
so I hope you're okay with that
trade-off that feels like more a thing I
can do that other people would have a
harder time kind of I have a hard enough
time getting into my head but you know
harder for other people okay
before we dive in I was going to say I
don't have slides I do but they have
code on them so I hope it's okay but
that's that's towards the end if we get
there uh just as a matter of kind of
orienting yourself
um
the docs page is really good now the
Microsoft c-sharp docs are super good
and actually as we are putting out new
features in preview most of these
features now the ones I'm showing today
are out in preview you can turn on Lang
version preview and use them if you want
um and as they go out you know this this
watch new and C sharp here fills up with
documentation for it so documentation is
in preview at the same time as the uh as
the features I think that's pretty cool
um go Bill Wagner who's over there
um running that uh here's the c-sharp
language strategy if you if you're
wondering like do they ever stop
evolving do they stop putting new stuff
in c-sharp all the time at this break
night Pace this is where you can go and
and see no we don't
um like if you if you ever want to read
that I'm not going to like go into
details too much on this but if you ever
want to kind of read our statement
that's supposed to be like a long-term
statement for how we think about uh
evolving C sharp this is where to get it
and the sort of some of the main points
are we do evolve and innovate
aggressively because we want to be
relevant to the developers and the
domains of today not just of yesteryear
like we want to be a programming
language that would be great for your
next project and not just for your
previous project so you got to lean in
there and we do
um and on top of that
um well we also have a commitment in
here to backwards compat we might touch
on that a little later that's going to
be fun
um and um and then also uh the strong
role that the community has come to play
in and the ever greater role at the
community plays in the future of c-sharp
where we have I mean everything's open
source I'll show you in a second we have
more and more contributions not just in
terms of like
increasingly not just in terms of little
ideas or not that they're also useful
but also whole features that are being
driven and contributed and even
implemented by community members that
are not that do not work for Microsoft
so that is really cool to see and um the
way we kind of
um
the way we kind of keep
um keep in touch with the sort of high
touch place to get involved with c-sharp
is is on GitHub that's the uh the
compiler repos called Roslin that's
where the c-sharp compiler is
implemented in C sharp and the vb1 and
VB actually if you're interested
um and over here for instance we have
this status page that everyone can go
and check out
um it recently got a C sharp 12
category here which is all the features
big and small even like little Dell
tester features that are shipping in
c-sharp 12. so you can see it's a big
release if you just count here some of
these are maybe not relevant to you some
of these are tiny and they will just
like remove things that you didn't even
know was a problem and some of them are
indeed big features
um and then up here are the four things
that we already have some developer
activity on that actually somebody's
been working on this feature not just
from a conceptual point of view but
actually from a code point of view so
we're already like engaging on what
might become C sharp 13.
um and some of those features are that's
some of what I will touch on later in
the talk
um and of course the c-sharp Lang which
is the repo where we do the actual
language design we used to be together
that wasn't like a good fit
um so we ripped them apart we have a
separate repo for c-sharp language
design uh where the the code the
documents are documents right it's it's
not it's the signs proposals meeting
notes that kind of stuff we don't there
aren't a lot of Cs files in here
um they're over in Roslyn and
um and that's just like our that's where
we do our daily work just like on a
coding project this is where the design
team we do our daily work you can see
the latest the latest meetings you can
see the notes and what we thought out of
those uh let's dive into this year
um
there's a the readme has a
kind of a has the agenda actually what
are they going to discuss next uh looks
like there are some things that we would
love to look at soon here are notes that
I actually took the notes but I haven't
published them yet because I was heading
out the door for this
um and here you can just go and see what
what are they thinking about that's a
high touch kind of Engagement and lots
and lots of discussion in here
um so if you're really interested
um this is where to go
that's probably enough for
for looking at web pages now okay
luckily Visual Studio is just behind
here it's got code in it uh we're going
to do some coding I apologize it's a
little bit I'm I'm kind of a tall guy
not for Dane but you know and um the
code is far so I'm so your beautiful
audience and it's hard to look at you
and at uh the screen at the same time so
sorry for like you having to watch my
forehead a lot but we'll make it work
okay so uh let's look at some of the
features that I just like heading out
right now and we have they're features
in different categories so I'm going to
start with one that I'm not actually
going to show
um because uh how many were here for
Nick chapsis talk just uh just before
um yeah a good smearing of you
um so
uh I was walking through
I had breakfast with Layla and Irina
there are also speakers here and and it
started to rain and they and then it
stopped and they're like okay Now's the
Time to go to the venue and I went up to
my huddle room to hotel room to grab my
stuff and instead I sat down and looked
at my presentation some more and it
started raining again so I was dripping
wet as I came in and Nick was just
talking about
um the improvements we made to
um uh
interpolator string handlers which is uh
so if you if you didn't hear it never
mind it's just an example of us there
are several features that we do that can
help you improve the performance of your
code if you were kind of low level or
that can help Library writers do things
that make their users code more
performant like
features that in and of themselves most
c-sharp developers will not be using as
in like putting them in in their syntax
but that many people will benefit from
there's always a few of those features
there are some in C sharp 12 as well I'm
not going to show any of them today
they're they're a little bit more Niche
but they're good for everyone so we do
it anyway we try to not make c-sharp
have too many Niche features in general
but Niche features that are for people
that make things that build on them
faster that's great we want to support
that we always did we always had unsafe
code in c-sharp from from the GetGo and
then we've sort of done a transition
where more and more of what you could do
with unsafe code there's now a safe
alternative to and that does add
complexity to a corner of the language
but hopefully complexity that doesn't
affect most of you so that's one
category then we do things that are just
like
as I said you didn't even realize this
was a problem but some people stumble on
it all the time the stub their toes and
things we just kind of clean up all the
time there's a bunch of that little kind
of cleanup we're going to start with one
of those as kind of like a palette
cleanser and then there are those
features that I genuinely like you write
nicest C sharp now you have less
boilerplate that kind of stuff
um and I have two of those today that
are really like
I think meaningfully helpful even though
you can't technically do anything new
with them they're meaningfully helpful
in making your code not just have less
characters but be more abstracted and
more elegant okay
and then there's a category that's
pretty rare
and should be pretty rare which is we
actually change fundamentally what you
can express in C sharp it's like
deep fundamental expressiveness that you
just couldn't do this before okay we did
one of those in C sharp 11 which is uh
you can have static virtual methods and
interfaces static virtual members and
that becomes huge for various scenarios
um in you know
implementing some design patterns more
beautifully it's it's huge for numerics
it's huge for uh being able to build
abstract static factories and that kind
of stuff and we really kind of
open up a whole new way that you can
abstract things
and there's another one of those a
couple of those features that we're
contemplating and one of them I hope to
get to in the end of this talk and and
show you as well but but there's none of
that in c2f12 there's not like a a
fundamentally expressiveness expanding
feature and they shouldn't be one in
every release that's just too much
okay let's go palette cleanser
why can't you just feature so for some
reason you have a using Alias here for
some reason you always had to put like a
name type type that was declared
somewhere so I can't just in C sharp 11
and all the way up to C sharp 11 I can't
just say decimal here
it's an error why well because you're
using a keyword and there's supposed to
be a name there
okay well can I just put decimal with
capital D no because even though I have
usings in the background they don't
apply to other usings duh so you have to
write the whole thing
that's pretty annoying so we didn't
solve that ladder problem but in C sharp
uh in C 12 at least we made it so that
um so I'm going to upgrade to C sharp 12
now and stay there
um
at least you can write any old type
expression
um so that's obviously the um the
keyword types int and so on just
abbreviations not a big deal but it
becomes a little more of a big deal uh
when you think about like two full types
for instance let's say you have decimal
comma decimal maybe you maybe the
elements of the tube will have names the
this is the actual grade and this is the
weight
assigned to it when you compute the GPA
um stuff like that now that's now that's
legal and that was really you couldn't
really do that before and of course for
those of you all of you those of you
still using unsafe code you couldn't put
pointers in an alias either
and you still can't
because it's not in an unsafe context
um but you can make the context unsafe
because now you can also put the unsafe
keyword and then using Alias okay so so
just like
this should have been like this all
along it wasn't sorry now it is you're
welcome
um so we do that kind of thing
don't usually make a lot of fanfare
about it but hey I thought I'd show you
one
um
so
let's get to something more meaty
um and now we sometimes we end up in
this awkward spot where we have this
feature we want to do a broad feature we
want to do
and the one I'm going to talk about next
primary Constructors was that in C sharp
six like I can't even tell you how many
years ago
we were going to put in primary
Constructors to the language okay I'm
going to show you what it is in a minute
and then we didn't we didn't get around
to it there was some gnarliness and then
we put in records much later and we said
okay at least records should have
primary constructures so records in C
sharp as you can say they're primary
certain let me tell you what a primary
structure is it's this idea that you can
put Constructor parameters directly on
the class and many other languages have
this this is not like a new thing we
invented for C sharp and it's really
convenient that you could get your
Constructor parameters
directly on the class you a you don't
have if the Constructor is simple you
don't have to write a Constructor at all
like you just put the parameters there
and they're in scope for your whole
class and that means that members even
members
even after initialization
function members in the class can just
use those parameters they're just in
scope and you just use them and you
don't have to think about how did it get
there you know in which order were
things assigned to the fields or
whatever uh it's just there
so that's kind of elegant I'm going to
need some water here
that's nice and elegant and it's been in
C sharp for a couple of releases for
records
but records how many people how many uh
in this room have used records or looked
at them fairly much yeah so you so about
half of you records that sort of this
opinionated feature in c-sharp but like
classes and Strikes are great but
sometimes you want to express value
semantics rather than object reference
semantics right you want a thing that
just represents value but value types
like structs aren't good enough because
for whatever reason you can't inherit
um and you can't build up change of them
that kind of stuff right so you you need
more expressiveness you want classes
also you know structs can be expensive
to pass around a lot because they they
can be big so classes are great but
classes have all the wrong behaviors for
a value they compare that equality by
reference and all that kind of stuff so
we so we made a whole like opinionated
feature that if you put the record
keyword on your class instruct then we
flip all the defaults to be value
friendly well one of the value friendly
defaults is that if you're a value you
want all the stuff that you you just
have public State you're like flat
state right you're not encapsulated and
smart
and so when you put a primary structure
on a record all those things should just
also become public properties on the
thing and we even throw a deconstructor
in there that matches it for good
measure and so when I do this for a
record then
indeed it has ID and name and grades as
public properties on the on the object
um which is great if you're in that area
but it's not great if you're trying to
encapsulate something if what you're
getting into your Constructor is
actually like supposed to be secret or
you want to expose it in a different way
like dependency injection anyone you
know kind of sucks if you're like just
put that up there and you know so
um so for uh let me put let me keep the
ID up here just for to make the point so
when you do this for a record you should
really use uppercase names here because
then the properties get named in the
right convention and so on but in C
sharp 12 you don't have to be a record
anymore and when you are when you put a
primary Constructor on a non-record this
whole exposing things as properties goes
away so it's like a smaller feature but
better suited for you being in charge of
what gets exposed and how classic optic
grinder style right so
so um
so you can see now that the ID is no
longer available if you look at the if
you look at the object the only thing
that's there is the property that I
actually declare at the GPA
and these are no longer referenced
because they are just privately in scope
in the class and and nobody's accessing
them
so we can but we can expose them we just
have to do it ourselves and then we also
get get to decide exactly how we do it
so let's expose the name
a public string name
this is really bad for my posture you're
gonna you're gonna I'm gonna be sitting
down after this for sure you're gonna
have to bring me beer
um
so I can do an auto property and then
just take that parameter which is in
scope that Constructor parameter and I
can just assign it
in the initializer okay
so now I decided my storage and my
representation
I could also do something else let's do
the ID
I could do that as a computed property
so the the getter here is you know
expression Bodied properties just
implicitly have a getter the getter here
will evaluate this expression this ID
variable every time so that means after
the object has been initialized and the
Constructor is done running the ID has
to still be around
and same down here you see the grade
grades that's being accessed in a
function member as well so we have to so
from the language point of view we have
to keep these things around after the
thing that got them as a parameter is
over after the Constructor is over
well that's familiar already in C sharp
from other places if you have lambdas or
local functions they can see the
parameters to the enclosing method as
well and they can also survive the
lifetime of the enclosing method so what
we do there is what's generally called
capture right we we find an object to
stash these supposedly local parameters
in so that that object can can be kept
alive and can stick around after that
method has run so you can have it so you
can sign up an event that references for
instance sign up a delegate that you
created from a Lambda that had something
in scope that is no longer around
um well we keep it around we generate an
object behind the scenes stick it in
there keep that alive as long as you're
that's why that's why events can memory
leak so bad right that's um
if you don't if you don't unsubscribe
so we just want to do a similar thing
here we want to do Implement capture and
where to stick
this state
we stick it in the object itself right
it's really part of object State you
want to think about it as yes it's a
parameter but it's part of object state
it's a parameter to the object that
sticks around so behind the scenes we
will generate some field it'll have an a
god-awful name that you can't say in C
sharp and then we will implement the the
parameter axis in that way okay so you
just so generally you don't have to
think about a thing it just happens it
only happens if you use it though like
this this name thing here doesn't get
captured it doesn't waste a field in the
object because you'd only ever reference
it during initialization but when you go
in and use it in in function members it
gets captured and a field gets allocated
so sometimes you need to know that
um
this does still add to the footprint of
the object if you will and can have
other effects like maybe your struct
isn't unmanaged anymore or something
because of it but generally speaking
we try to make it as transparent as
possible
okay
um actually any questions so far
all right oh there's one
what if I have different naming
conventions for parameters and for
parameter names and field names that's a
good question we thought about that some
and uh it doesn't mean that
if you kind of mix
uh capture and and and self-declared
Fields and some of the object state will
be with one naming convention and the
other with another right of course you
could choose to name your parameters
with an underscore for instance if
that's your naming convention feels but
that looks ugly from the outside when
you're calling the Constructor
so we did discuss oh should there be
some feature that you could have an
internal name and an external name and
all that kind of stuff and for now we
were like let's wait and see
it might not be that much of a problem
or maybe if you really insistent about
it and you want to be consistent that
all like object state has the same
naming convention maybe you just don't
use capture maybe you're maybe you just
write the field declaration that says
you know
int ID
equals ID
and then the oh and underscore here
right so you're just saying I'm doing
this
[Music]
um
myself still
it's still easier than having to write
the Constructor yourself right you still
get to just initialize it right there
you still get benefit from the feature
you just don't get benefit from the
capture part of it so that's the
trade-off you get you get to make
um and
and
um you know there's an interesting thing
here so this actually allows me to make
a point I was going to make later
um you see there's a warning on the ID
here
um and that's because we realized that a
common failure mode and this happens in
other languages as well that that have
primary Constructors the common failure
mode is that you actually allocate your
own storage for the thing and you and
you initialize it but somewhere else you
accidentally capture the parameter which
is right there in scope you accidentally
say ID instead of underscore ID oops you
know and now you have two copies and you
modify one it doesn't change the other
and you know it's just that's a mess and
a waste
so we decided to detect if you both if
you have a a parameter that gets
captured like ID does here and also
either get used uh as an initializer or
actually or gets passed to the base
class then we're going to assume
that this is a double storage kind of
bug that you have and we're going to
give you a warning about it so we try to
protect you from
kind of that oops I I did both
situations
all right yeah another question there
could you also put interfaces in what
sorry
on the you don't have a Constructor
anymore so in the parameter list yeah uh
sure include any type of work any type
you like and the DI will work with it
and d-o-d-i yeah
um yeah this is so
this is just a Constructor signature
and then we do some additional things
with it so di should work the same it
always does and this is indeed a
dependency injection is
one of the places where we've hurt the
most about I love primary Constructors
they will be perfect for dependency
injection but they only work for records
and Records suck for things that have
dependency injection you you've gone so
tantalizing they closed and you didn't
so it's a core scenario for us I haven't
played with it recently if it doesn't
work definitely tell us because it's
that's like a core scenario
um so good good question there uh we'll
take one more and then I'll uh then I'll
move on
um hello just for laziness purposes
could we replace the lines 11 and 12
that you have there by something just in
the primary Constructor like something
indicated public string name and
gradiently gets public by Magic great
question and that's been discussed
intensively like we um should we have
we've jumped onto a slippery slope
slippery slope we have a few terms that
always come up in language design Cliff
is one we'll get to that in a second
slippery slope is another have we put
ourselves on a slippery slope now people
are going to ask for more and more
things in this primary Constructor uh
signature when is it gonna stop
um and the good thing about releasing
often is that we can just release the
Bare Bones here and then we can see
then we get time to sort of see do we
want to take the next step do we want to
for instance do we want to say that you
could say public
string name and then it becomes then it
becomes a proper member okay but it
should really be a property then if it's
public but do you need to use property
syntax in your parameter list that's
kind of ugly but if you don't do we pick
a default for whether it's get or set or
is it in you know what kind of property
is it actually is it an auto property
and so now we're we're getting into
opinionated space again which this was
precisely about trying to stay out of
opinionated space a feature that that's
good for all so it it just comes with
this like Pandora's box of design
questions that we were happy to leave
for our future cells you know maybe
until after I retire or something
but it keeps coming up so it clearly and
other languages have it there's also
like is it is it a good thing that some
of the members
the actual members that you can access
from the outside are declared in like a
parameter list somewhere rather than on
the
at the actual top level of the class I'm
not sure I mean that it's a discussion
so
you you're absolutely right in pointing
out that that is something that
you know is worth a serious discussion
okay I'm gonna move on
um a little bit uh and just point out a
few more things about this
uh let's see actually maybe not that
much more I think we covered most of it
um let me just think
oh yeah one more thing
um
of course you might wonder how do I yeah
a few things about
relationship to other Constructors so
you see that there's another Constructor
in here that normal Constructor
declaration it delegates to the primary
Constructor and indeed it has to like
directly indirectly every if you have a
primary Constructor every other
Constructor needs to call this
uh and that's to make sure that those
parameters actually get passed at some
point so they have a value when when
they get captured and used in other
contexts
um
so the way to call base is actually
let's say I have a base I have prepared
a base class for the purpose
um the um
it takes a name that was very handy so I
just pass Constructor arguments to the
base where the base class is it kind of
fits together nicely
um
now
um
one thing to one thing to be aware of is
that so that's the only thing that can
call Base essentially and then it can
call any Constructor in the base
one thing to be aware of is if you were
um I have to delete the The Inheritance
here if you're declaring a struct and
not a class
um
all struct
can exist in as in a zero state right
you can get structs without running a
Constructor you can say default or you
can get an array of structs and they're
already in there and that in the zero
State and even if you say new student
open friend close paren that'll
translate into giving you the zero one
unless it has a parameter-less
Constructor of its own and so
you just so that also means that if you
have primary Constructor parameters that
are captured those will also be zero you
know
just as if they had been filled if you
had them in fields it would be zero
they're still zero even though they're
like parameters those parameters never
came through nobody ever called to
Constructor so they're just there I hope
that's not surprising but it's something
to be aware of this does not protect you
from that nothing protects you from that
um
yeah good
so
um let me take this back to a class I
don't know if it matters but just to be
on a safe side so I'm going to jump to
the next feature which is collection
expressions and I am very very very very
excited about collection expressions
um and it might show I'm going to try
not to jump because who knows but
uh so the the issue we're trying to go
for here is that even as we've unified
many things into sharp over the years
collection creating collections is kind
of like a mess it's a hodgepodge
depending on your choice of collection
you have to do different things to
create one with some elements in it
here in this example for the grade array
there
I've been using yeah arrays and so I
have to create a new array this way and
the two places I'm calling here I'm
actually being smart I'm calling it
right at empty because I know that's
more efficient because all empty arrays
of this element type are immutable
it has zero
elements that you can sign into so we
can share one okay great you have to
know that trick though I mean David
where are you David you would have to
have yeah you would have to have told
them to do that right
um so
um
but if I if I decide ah you know what
this should this should really be a list
of a list of grade let's write it
backwards here list of grade instead
well oops now all those things don't
work anymore
um up here well maybe I can I can create
a new list and then use a collection
initializer syntax which is kind of
similar and that adds adds ads adds
every element individually to the list
which is not super efficient but it
works
well down here I can just call
list.empty right
oh wait there is no list at empty
actually there's no list
unless you go and include the
non-generic ones but it doesn't have an
empty that's generic I can guarantee you
that there's no way of saying listed
empty you just have to create an empty
list
so we will do new
and rely on the target type new to get
to provide the rest but this okay and
now great
now I want to actually no you know what
it has to be an immutable array
and um
surprisingly this compiles
so you like how can so I'm using an
object initializer here it's calling add
to mutate the immutable array multiple
times to put the new element in how does
this not how does the compiler not
complain about this well that's because
collection initializes they if there's
an ad method they call it and they
consider it good well immutable array
has an ad method it just doesn't behave
the same way as other AD methods it
doesn't mutate because hey I'm in
immutable array you know so don't so I'm
not going to mutate you give me an
element to my ad method I'm going to
give you a new immutable array that has
that element added
but collection initializes they call the
ad they get that thing back and they're
like huh
and they just throw it out
and you're left with the same immutable
array that you created it has no
elements in it
so and the fact we don't even warn you
about this it's kind of a little bad
actually
um but instead we're going to give you a
new feature which is like I don't care
how this is going to get initialized I
care that it does you know the what not
the how that's one of our mottos from
all the way back to link and the Syntax
for collection Expressions is this
um square brackets they get Target type
to whatever is expected where you use
them whether it's set use them as an
argument or assign them to a variable or
whatever in all those places even if you
cast it to a type then based on the type
that they're being targeted to
they'll do the right thing
okay that's and the right thing
is efficient
that's our so our goal here is we'll
just do the right thing for you and you
wouldn't have been able to do a better
job yourself like in
99.7 case or something where you don't
have like super specialized domain
knowledge
so um
so what does that mean well for
um it means that there are various ways
that a type can enable itself to be
created with a collection expression
okay if it's array that's just built
into the compiler all right compiler
knows about arrays it's going to new up
the array unless it's empty in which
case it's going to call the radar empty
right it's going to do the right thing
um
if it's
um
and sort of so we sort of have a list of
prioritized list of things we want to
try at the bottom of the list is okay if
if a collection initializer would work
we're going to do that thing we're going
to call add all those times
but in between there are better options
um and in particular we introduced a new
code pattern
um
essentially you put an attribute on your
collection and it tells you where to go
to look for a factory method and then
the compiler will call that factory
method with a span that it just uh
created in the most efficient way it can
containing all the elements that you
provided
that's exactly the details of how it
creates that span can change over time
but if you have a factory method that
will take the span then we will give it
to you and you get all the elements in
one fill swoop and you can do whatever
you want with that
um
so
um so a list of t for instance is an ex
or in in fact immutable array here is a
better example
um actually now has that attribute and
it will just do the right thing it will
create a beautiful immutable array uh as
efficiently as it can
and if it's not as efficient as it can
be David will tell us and it will be in
the next release
so
your next book yeah yeah we have to read
your book we have to pay for your book
we all have just we have one copy we'll
we'll pitch in for one copy that we'll
keep around
so
um
so that's pretty good now that and we're
kind of like sort of ready to ship like
this we're like okay but what about
interfaces well interfaces can also they
can also actually put that attribute on
and they can so the factory method can
for for instance for I immutable list
it's an interface but it's pretty fair
to assume that creating an immutable
list is a good concrete type to choose
so but it will point to a factory method
that makes that decision for it so the
the even the interface decides but for
the core collection interfaces in
c-sharp the ones that are sort of known
by the language
um
we felt we can do better
so so let's say that you put let's put I
let's actually put inumerable here like
a super
simple interface I innumerable of grade
now all the pattern matching here is not
going to work anymore list patterns
don't work on I know mobile we should
probably fix that but that was not like
a
we'll get there I think
um
it's harder than with the other
collections but anyway you can see that
the collection Expressions work out just
fine here and that's because and we made
a choice
what to do in the compiler what concrete
type to create
when this happens
but we're not going to tell you what
choice we made we can keep this secret
or at least we're going to say that if
you find out
relying on that knowledge is not
supported why because especially for
these read-only types like iron mobile
and I read only lists and I read only
collection
we can do so much better than just
creating list of t for instance from a
performance point of view we can really
kill you know if we if it has like fixed
length we can use that if it has
um if it's empty of course we can reuse
the same thing and all kinds of other
optimizations we can do
to really really create the best
concrete thing that supports the iron
mobile
of T interface in your specific scenario
we with your the specific elements that
you provided to it so we're reserving
the right
to do the best even if it means a
compiler generates new implementations
of iron removal of T behind the scenes
doesn't even use Library once it
generates private ones because that's
the best way it can do it it uses inline
arrays which is a feature in C sharp 12
that's for performance I'm not going to
show you whatever it can do whatever it
wants and it can change and do better
release over release because we under
specified it on purpose okay
sounds good so now you can write the
most beautiful code the most like the
least vulnerable to these changes of
concrete type and so on and also the
most efficient with the same syntax at
the same time that's pretty cool right
oh okay
not not that cool all right thank you
thank you
I'm just I'm only going to ask for one I
asked for one now it's fine you can be
you can go back to grumping it okay
uh in the future oh actually there's a
few more things you can do uh already
today it has a it has a
um spread mechanism so you can spread in
some other collection like I can take my
my friend Dustin's grades to to get my
to get my GPA up a little bit and spread
in his grades into mine it's probably
not the best example
um you'll notice that the Syntax for
these um collection Expressions kind of
mirrors the Syntax for list patterns if
you looked at those and that's a nice
Duality we have that further
tuples for instance that the creation
syntax and the the pattern match sort of
deconstruct syntax match each other
um usually we start with the creation
syntax and then we make it pattern
matching syntax and that looks like that
this time we actually went the other way
around we had the list patterns first
and also
dictionary literals we're probably going
to do them we just need to find out
exactly all the details about them and
also what happens if you don't give a
type at all but you just say VAR x
equals some stuff here
and that's a really hard question
actually it's much different question
than what happens when you know the
interface because then people have told
you this is the surface area I'm
interested in if you just say bar x
equals and how do we know what surface
area you want and if we if we just say
list of T you get all the surface area
you can do everything but it's not going
to be very efficient if you don't make
use of it so the choice we make
will be right or wrong depending on what
you do well should we like do flow
analysis and see what you do with it
I don't know it kind of gets complicated
so that's an open question we'll get to
it later
um and we'll do something once we're
confident that we have the right the
right answer for that okay
all right
um
I'm going to move on and talk about okay
Mark
you get this one
can you use that in a stack alloc that's
a good question I'm not sure
use what to spread
uh I don't think so
um I repeated the question so
I don't think so
um why don't you try it out
and tell me because I'm actually
interested
okay
um Mark wants to stack of course you do
it's actually it's a good question
um
here's a feature we didn't do uh that we
were going to do the last time around
then we realized we hadn't actually
there was a hard technical problem we
hadn't solved then as we went back to
this release we realized that the heart
technical problem was sort of the mirror
of a philosophical problem and we didn't
solve the philosophical problem uh so I
think we have a solution to the
philosophical problem now uh but let's
see what kind of problem we've been
um we might have a piss off the user
problem next so um so we'll see but the
idea is
um so now this is where the word Cliff
comes in I told you we had a vocabulary
Auto properties have a cliff right if I
wanted so let's say this is a get set
property and I you know this is great
but I just want to do it one tiny little
thing differently than what the auto
property does I want to just like trim
uh White space away from the string as
it comes into the setter well now I fall
off the cliff and I can't use an auto
property anymore I have to explicitly
declare my backing field and I have to
also write the getter even though it's
trivial and all that stuff well what if
you didn't have to do that we could we
can we can support that if we let you
write optionally write bodies in your
auto properties and those bodies can
reference the backing field
of the property with the variable name
or the parameter name field that's the
design so I so really if it does like
just the the standard thing the way you
would write that explicitly is just to
say field equals value
and value is a special parameter right
it represents whatever you
whatever you assign to the property when
you call the setter uh field similarly
would be think of it as a as a special
reference parameter that really
references some the backing field but
we're not telling you the backing
Field's name we're giving you
through this ref primer instead okay so
we could do that that's that's kind of
neat now I didn't fall off the cliff
when I decided that I wanted to trim my
stuff
you can still keep this one
unimplemented if I want of course you
get squiggles here because it doesn't
work but that's the sign I'm just
showing you the sign I could implement
this explicitly as well I could say that
just returns whatever is in field
and it's still an auto property because
it references the backing field so it'll
generate a backing field if it needs to
all properties are order properties if
you want them to be just mention the
backing field and it will be there it's
like a Genie in a Bottle but you get
more than three so
so that's kind of great and we love that
design simple it's easy to explain it's
kind of similar to how value already
works so no
of course
now we realize this is a breaking change
in the language right because if you had
if you let's say you had let's say you
had a field called field string field
okay and now okay
um I'm not
and let's say it doesn't initialize now
this is perfectly valid c-sharp code
today
and the and the occurrences of the word
field here reference the field outside
or they reference something called field
that may be very far away you know but
it's in scope and if we make it mean
something else we have performed what is
known as a breaking change we're going
to break some users code somewhere
without them having done anything wrong
it's not their fault they couldn't know
that there was going to be a thing
called field in the future
well we can't do that but but if and so
what we've been telling ourselves uh
previously in this kind of situation is
well we can't do that we can't break
them you know page one we can't break
anyone so we're gonna make the feature
design less optimal we're gonna
diminish the new feature
in order to respect
those small small percentages of code
out there that would have been broken by
it
is that a good trade-off for those
people absolutely yes for the rest of us
I don't know is there a way that can we
square that differently
um so either we diminish it by having a
worse syntax like somebody said just use
two keywords or you know whatever but
or you know we could also use the syntax
but have really Arcane rules for how it
works
um so we could say that well field means
the underlying field unless there's
something in scope somewhere called
field in which case it means that so but
that means that in in new code where you
actually want to use field to mean the
then all of a sudden somebody introduces
field somewhere in scope that you don't
care about at all and your code silently
changes meaning as a spooky action at a
distance right that that's horrible too
so that's why we didn't ship it this
time we're like oh
so instead we looked at is there a way
that we can occasionally cautiously
start doing breaking changes in C sharp
okay
and there's a long story I'm not going
to tell the long story because I have
something else I want to show you and
we're getting close to time
the short story is
we want to
we want to inconvenience you now
rather than forever and want to
inconvenience the few rather than the
many okay
now CGR is different from many other
programming languages in that there's
pretty much just one compiler out there
most people use it and even
when you upgrade the compiler you keep
generally keep using the same language
version until you opt into a new Target
framework or you explicitly up the
language version so you have newer
compilers compiling older language
versions essentially every time you get
the you do a tool set upgrade or
whatever you get a new compiler might
have a new language version with it but
that's not the language version you get
in most cases nowadays the way things
work
you keep compiling with the old language
version
so we could make the new compiler give
you warnings in your in your code when
you're targeting the old language
version saying in the future when you
upgrade to a new language version this
use of field here will break
can I help you fix it now so that it's
resilient to the Future can I help you
write what you would have written if you
had started out in the new version of
the language can I help you
upgrade to the Future
okay so that would be something like
saying this dot field instead
like so we would ship it with a fix and
you could apply it automatically to
everything if you don't care just fix
them
most people won't have any
few people have a few
so we'll only do this when it's really
blocking at a sign that we think is cool
and work and and valuable and when we
have an automatic fix that's foolproof
that's sort of like that would be our
criteria for doing a break like this
it'll be rare
but when we do
it's just like before you go to C sharp
13 or whatever
I now know that this code will be broken
let me tell you now and let me give you
a fix so you'll be good you'll be able
to move into the future unhindered and
then of course we can have all kinds of
catch-alls then people will say I not
right now tell me again when the uh tell
me again when I when I start to upgrade
and then we'll try to also hook any
upgrade gestures you do and so on but
but the general mechanism we think is
the gentlest way
to get the breaking changes out of the
way and have you and have neither the
language nor your code suffer from these
clashes forevermore
okay
rip the Band-Aid off and you're good
yeah
what if you skipped several versions
well if we keep doing breaking changes
of course they will accumulate so we
have to really be judicious here and not
accumulate a lot but if you skip several
versions all that'll happen is that you
when you when you get the new compiler
it'll be flat it'll flag all those
things and you'll fix all those things
and we'll make sure it works that that
that it works across several versions
it's not it's not as the only problem
with several versions should be that
okay there'll be more of them and
they'll still be uh this be you know
Visual Studio menu item that says fix
all the breaking changes with the
automatic fix I don't care it's going to
guarantee that your code is going to be
semantically equivalent and it's going
to be robust against all these all the
breaking changes that your compiler
knows about
okay
so if we can get that
in the dot net nine time frame then we
can get this feature into C sharp 13. we
start talking about some of the other
ugly ones like VAR or or
um in particular
discards which are a feature that is
very hubbled
by this problem of backwards
compatibility
sometimes underscore means variable
sometimes it means discard depends on
which syntax you use to declare it
because the syntaxes are already there
we couldn't break them so that's
horrible and we could we could
potentially fix that in the future
even go back and fix the existing ones
so that's it that's something that just
to show you something hard that's on our
minds and that we're trying to kind of
trying to push through with something
that's reasonable for everyone and we're
going to need a lot of feedback over the
coming year year hopefully no more than
a year to kind of to thread that needle
we've sort of this controversy on all
sides and you know people with scenarios
and so on we're going to have to try the
most inclusive we can to
um
to arrive at something reasonable here
okay
I'm gonna now
I'm going to save and close this as well
um
okay sure
and I'm actually going to do slides for
a bit just a bit because we only have a
bit left we have 10 minutes left
so
when we talked about this at build we
decided to put this fireplace and and
hot chocolate slide in so we can sort of
go in we get you all into story mode
story mode
so
you all like extension methods right
who here does not like extension methods
okay
let's talk after I want to know why but
not now
um
the cool thing about extension methods
is
I can put things that are relevant to me
on a type that I get from somewhere
someone else
I get it's a it's a form of software
composition that is actually genius
right it allows for loose coupling
with but higher discoverability I can
now walk up and say dot on that type
that I didn't write because I put that
extension method on it or somebody else
wrote the extension method I need
that thing is immediately discoverable
to me fantastic and the syntax looks
good it's also it's nice and dandy but
it only works
for instance methods you can make
something look like an instance method
but that the buck stops there
so ever since
we did extension map the first public
preview that had extensions extension
methods and it came out
two months after I joined Microsoft 18
years ago
and for all that time people have been
saying but what about properties what
about operators what about indexes what
about static methods
yeah we even we tried really hard in C
sharp four and the approach we took just
fell apart the thing is the extension
methods we have today they're in a dead
end in an evolutionary dead end the way
you express them the way you declare
them does not generalize to other kinds
of members it relies on you putting the
this keyword on a parameter well not
everything has parameters you know
and how do you and and that doesn't even
make sense where you're an extension
static thing there is no this there's no
instance but you still want to extend
the type
so we just gave up and then we tried
some years later and then we tried some
years later and then we try some years
later
then in parallel we saw
some scenarios that seem to be
completely unrelated like just a whole
another set of scenarios that were also
interesting and where we also really not
weren't able to provide the best so
those scenarios had to do with
week weekly type data this is it's kind
of like a broad way of saying like wire
data or you know that kind of stuff
we look with Envy at the things that you
looking at
um Excel spreadsheets and so on F sharp
this is one of the places where we
actually looked enviously at F sharp a
lot of people say Hey you steal all your
features from F sharp yeah have you
looked at ml you know where do you think
they got it from but this one
I love F sharp
and we do steal from them
um
but this one but they had this really
really cool thing called type providers
which means that at at development time
as you're sitting there typing a coding
time
the compiler could have these little
plugins that would look at a particular
data source and interpret it
into types
like it could look at Wikipedia data or
um adjacent schema or even just
representative Json data and
programmatically it could cook up some
fake types
that it could show to you at compile
time and you could do strongly typed
programming against this weekly type
data how cool is that
it's a little not so cool when the data
changes shape and it doesn't match up
anymore but that's I mean that's the
nature of working with static types over
Dynamic data that that same thing
happens in typescript as well like you
have you put Types on those payloads
well the payload changes your types
your thing still type checks just fine
but you start getting
um you start getting a lot of uh a lot
of errors in the code that actually runs
your types of code right because the
data doesn't fit the types
seems like an acceptable circumstance
but you can get types for those weekly
type things
and yeah and typescript as well you can
type everything in typescript is really
just a dictionary but you can express it
as a type and then you get a really nice
development experience just pretending
you know what type it is and usually
you're right
okay
so it turns out that those two stories
connect
and so I'm going to start with the
latter and then we're going to work our
way back around to how does that apply
to extension everything
so let's say that you have something
that we let's call them explicit
extensions okay and let's just start
thinking about it it's a type
declaration that is really like a fancy
Alias it's just an alias it's just a
very good Alias not those sucky aliases
that we started to talk with today like
these are like aliases for the future
because it was so what this says here is
that data set is really
a dictionary
but
um but unlike an alias it can you know
there are all kinds of things that
that's better about it
um one is that it can have an
accessibility you can put it in metadata
somewhere you can put it you can be in
an assembly and you consume it from
another assembly it's a real type
not just some FICO name for your file
can be generic
because there's a real type and real
types can be generic
um and it can reference
other types because it's not in that
using blog where you have to say full
names all the time that's a small but
important like I couldn't say uppercase
decimal before just do that because it
sits with the other type declarations
where everything has been imported
and
mysteriously it can have a body can have
just a semicolon and it's just an alias
but it can have a body what does this
all mean let's look at an example and
actually explicit
I put explicit explicitly here but we
can that's probably the the reason it
has explicit is because it's going to be
an implicit later but I'm going to make
the explicit implicit and then we're
going to make the implicit explicit when
we get to it okay
so just we'll just do this that wasn't
confusing at all
so here I'm I have a method that takes a
string that's supposed to represent some
Json that I'm going to do some something
with and then I call it with a Json
string and yay it's a raw string literal
because we have those now
uh maybe I could I could declare an
alias for it that I can share that says
well this string is supposed to be a
Json string it's just
still an alias but it's just a hint that
I can now say well my method takes
adjacent strings hint to the user okay
it's meant to be Json
but it could be more than a hint to the
user maybe we can give it a body that
has function members well it's not that
state here but it could have extra
function members that make sense only on
strings that represent Json
like parse and get me something that we
call data object like a dictionary
object of some kind you know represents
structured representation of that of
that data there I'm almost out of time
oh my God
and then um you know I could actually
call that method it's sort of like an
extension method but it's only there
when I explicitly say that it's a Json
object it's not on all data objects
so I'm going to have to cut the story
short a little I could have multiple of
these and they're sort of like strongly
typed aliases think about the wire Data
customer and order they're really just
dictionaries but I'm putting like
typescript like uh Types on top of them
that just look up they have strongly
typed members that just look up in the
dictionary and as long as it matches
whatever schema those things follow
you'll have a strongly typed developer
experience against these and hey we
could use Source generators to generate
these from schema or typescript types or
whatever so so we have like typescript
like and we have F sharp typewriter like
it's heaven
but they can also be implicit and what
implicit then means is they
automatically apply by default to the
underlying type that they extend okay so
not only are they a view an enhanced
view on the original type they enhance
the original type
with instance methods
but also with static methods and all
with all the other kinds of things you
can imagine right so these are this is
extension everything this is where you
get all the extension members
this is where those two features come
together because you're just saying and
all data objects are Json objects in
scope here where I include this
extension and nowhere else but here they
are
and that means that I can call to Jason
on my data object and I can call from
Json on data the data object type itself
because it's static
and
sort of the stretch goal and this is
going to be the end of the talk what if
they could Implement interfaces for you
on the types that you don't own
so hey Json object is parsable
and you you know you can put an explicit
implementation in there if you want like
you can you can Implement interfaces on
behalf of the underlying type that are
only in force whatever that means right
here where you import the extension
now you can satisfy
you can you you can take types from over
here that know nothing about the frame
I'll go over here and you can satisfy
the interface that is sort of the ticket
to entry of this framework on behalf of
the types that didn't that didn't know
they should okay now you have software
this software composition benefit we
talked about before even more Loosely
coupled
and I think that has like immense if we
can get it to work that has immense
potential
um probably also for abuse and with that
I'm going to say thank you very much
you've been a patient audience
[Applause]