Every new C# version there is less reason to switch to F#. I have considered it multiple times but sacrificing ReSharper would be too much of a trade off for what F# is offering.
Strange post, or maybe I'm missing the point, or is it supposed to be sarcastic? Also what's with the generalisations ('enterprise shops don't like change & non-enterprise do', come on)?
half assed versions things of F# already had (tuples, async and tasks I’m looking at you)
yes F# has those, but afaik so do a myriad of other languages. Even before F# saw the daylight. I'm also not sure what is half assed about them, the implementation seems quite complete?
a language that is afraid to change anything
coming from a post talking about new features and 'changing into F#' that's quite a contradiction, no?
> yes F# has those, but afaik so do a myriad of other languages. Even before F# saw the daylight. I'm also not sure what is half assed about them, the implementation seems quite complete?
it's true, but c# advocates in microsoft have been quite parasitic in their behavior of pushing the language(inside of microsoft). they have also been averse to competition. i remember it's not too long ago, that we weren't really sure if microsoft was about to pull the plug on f# or not.
there haven't been too many clr languages, and ironpython was suffocated fairly quickly. yes you can use clojure on the clr, but who's using that, and is a meaningful customer to microsoft?
f# has been really smart in it's behavior in my opinion, by fairly quickly targeting the microsoft enterprise stack, stuff like share point, dynamics, and other crap like that.
it's also a hybrid language that is close enough to c# that you can claim c# developers can just pick it up. you could argue that good developers can pick up any language, but we're not talking about good developers here. we're talking about something that is more akin to factory work.
this is just my opinion, but i think the biggest customers of microsoft are government, government contractors, and people that sell to government contractors.
it's not about whether f# is really revolutionary or not. f# is very close to ocaml. f# is revolutionary to the microsoft enterprise stack.
asp.net mvc wasn't revolutionary either, but it was revolutionary to the .net culture.
I've been using C# for close to a decade at this point (wow, wtf) and I'm fairly familiar with functional programming techniques - I use a lot of closures, immutability, and map/reduce patterns in my code - but F# is still really awkward for me to write and use compared to C#. Even if they can express the same things, and F# is more powerful, it's a far more inconvenient language to use for someone that hasn't been living and breathing ML for years.
Furthermore, in general F# seems to generate far less efficient code than C# does, and for the kind of development I do (games/multimedia) I'm not really willing to sacrifice even more performance just because some FP fanatic thinks C# should go away. Personally, I think the C# compiler and the .NET JIT should have a lot more tuning applied, and get things like SIMD introduced, but MS doesn't seem to care about that.
Writing code in C# also makes it accessible to a much wider set of developers. The overlap and shared heritage with languages like Java is definitely a plus, even if I don't like some of the shitty design baggage that comes with it. It's already a struggle to get the community engaged with my project, JSIL - if it was written in an obscure language like F#, it'd be nearly impossible.
> I'm fairly familiar with functional programming techniques - I use a lot of closures, immutability, and map/reduce patterns in my code
i think that's the minority of c# developers though.
> I'm not really willing to sacrifice even more performance just because some FP fanatic thinks C# should go away
why should that even be question though? now think of a web application. suddenly f# reduces the amount of cruft you have to a great extent. why do people always think it's an either or? why can i not like html5, and still want it to stay outside of my desktop application?
> it's a far more inconvenient language to use for someone that hasn't been living and breathing ML for years.
yes, you may be right. but i think most programming is really copy and paste programming. when they know where they can find what they need to write their program it doesn't really matter what language it is written in.
> even if I don't like some of the shitty design baggage that comes with it
:D
> It's already a struggle to get the community engaged with my project, JSIL - if it was written in an obscure language like F#, it'd be nearly impossible
interesting project. well, i would argue that it's because your project is not really playing to the masses. vsvim for example has more forks and stars than your project, 33% of it (the core) is written in f#. but it has also been around for much longer, and addresses a need people have.
My point re: engagement is that for anything that isn't utterly mass-market, it's a fight to get users and other developers engaged, so every quirk that makes your project harder to contribute to ultimately makes it less likely to survive.
It's not simply a matter of deciding to build software for the masses. It's essential that we have software that aims at small niches because bigger mass market software can be built on top of it.
LLVM is a great example. LLVM is only useful to the tiny subset of programmers who do compiler/JIT engineering, and it requires a lot of domain expertise. Regardless, its existence has enabled a huge set of new software to be built - clang is a great compiler, emscripten is one of the first real options for running native apps in the browser, etc. None of those would exist without LLVM. Imagine how hard it would be for people to contribute to LLVM if it were written in an obscure functional language instead of in a ubiquitous one?
As far as cruft goes, yeah, F# is less verbose, but it's also harder for me to understand and harder for me to debug. A few years of practice might solve that, but it doesn't offer me enough advantages to justify that huge investment, especially since during that time I'll be writing worse-performing software whether I like it or not. The same applies for any new language, really, and I don't think new languages are a bad thing. I just think the idea that a widely-used language should be replaced with a niche one is pretty out of touch.
If you're really just doing copy/paste programming, I don't think the language you use matters, and F# offers no particular advantage for that. It seems most useful in scenarios where you are writing code from scratch, and the more robust type system and expressiveness can let you do that faster with less mistakes.
If you're seeing significantly worse performance with F#, then that's pretty unusual (most people see very similar perf characteristics, with some things slightly faster in F# and some in C#). You might want to fire an email to fsbugs@microsoft.com explaining your scenario - the F# team is quite responsive.
The RyuJIT project shows that .NET JIT performance is still on the radar, though I haven't seen any indication that SIMD is on the roadmap.
To your final point, it's clearly true that C# is familiar to a wider variety of developers than F# is. However, I've been impressed by the uptake of some F# libraries, like FAKE. F# reads so mush like pseudocode in some cases that it's easy for people to buy in even if they're not especially familiar with the language.
Glad to hear it. The main problem I noticed the last time I used F# is that it generates more function calls, along with more heap references (vs stack-allocated structs) for things like boxed values, generators, etc to do simple tasks compared with C#. Is it the case that you can optimize all this out using parts of the language I don't know about?
F# supports value types just like C# does, so I wouldn't expect more boxing on the F# side. Some types like tuples that are used more in F# than in C# are reference types, so you might want to avoid them in your inner loops, but that generally just means writing F# that looks a bit more like C#. Likewise, as to the number of function calls, it's probably a question of style more than features, though you can do things like use the `inline` keyword to make sure that particular functions always get inlined at call sites, which can be a big win in some cases (it also allows you to write type-safe generic math code, which is an oft-lamented unsupported scenario in C#). Lots of people are making good use of F# in contexts where heavy computational requirements exist (e.g. finance or scientific computing), but I'm not too familiar with projects using it where more real-time requirements exist (though I think someone's in the midst of porting Quake III to F#, so it'll be interesting to see how that goes).
"but c# advocates in microsoft have been quite parasitic in their behavior of pushing the language(inside of microsoft)"
How could you possibly have decided that "parasitic" was the best word? Is C# hanging off the back of F#'s success?
Not really. .NET has succeeded to the degree it has because C# is a credible, robust, general purpose, accessible but powerful language.
This whole submission is a desperate, misled, confused attempt at elitism, and becomes particularly ridiculous when it's talking about what are trivial syntactical sugar changes.
Particularly bizarre is this confused notion that F# is being ripped off, as if there aren't many languages with most of the same rudiments.
It's trying to be F# except the whole part about not being functional which is why most people will not switch to F#. Instead, we rather use the language that has worked well for us but want it to have useful features that some other functional languages happen to have.
Type inference is not an exclusive feature of FP languages, though there is no known system that can deal well with nominal subtyping (scala makes a good go at it, but only locally).
What would you say is the usefulness and value of local inference vs global inference?
In my experience, local inference eliminates a lot of boilerplate and clutter, while global inference isn't so important, because writing types is good documentation as you zoom out from the details of functions.
It also emphasizes the importance of good tooling support: when using global inference it would be cool to always show the inferred types as a little semi-transparent text on the top...
I just wish C# had algebraic types. That's the only thing keeping me looking for another programming language right now. Everything else, I love. But I do a lot of runtime reflection right now that is really only necessary because C# generics are not a powerful enough type system to represent what I want succinctly.
So I might end up implementing a lot of things as F# libraries glued together by C#. I'd prefer not to have that bit of context switch there, and I've had some trouble getting the F# compiler to work with Visual Studio on all of my machines (my Windows 8 machine was fine, but my two Windows 7 setups are broken).
Okay, that's not the only thing. I really want macros. Lisp-style, not C-style. I don't care if they are "considered dangerous" to lowly corporate developers. They can pass corporate policy against their use. That should be no reason to keep them out of the hands of adults.
The algebraic types wish is to be able to do scientific calculations more safely. I have built a system figures out the maximum safe speed limit for a car on a tight curve, and having the compiler validate my units of measure would go a long way towards ensuring the quality of the formulae over time as we tweak it.
The wish for a macro system is a different story entirely.
For the last, ooooh, 7 years or so, I've been building a relational data access system that I have come to realize is an attempt to build a static type checker for SQL queries. It's not quite to that level yet, but right now, for me it's the most convenient way to make type-safe access to a relational database. I also think it is a very convenient way to manage change of schema over time.
I know, every hot-headed developer makes his own "ORM", but I had some specific uses cases that made sense for me to roll my own system. At the time, the only options for data access were ADO.NET [0], NHibernate[1], and a slew of NHibernate clones[2].
I needed the ability to execute fairly arbitrary SQL against a slew of databases whose schema was off limits to me. I could make all the stored procedures I wanted, but i couldn't change any tables. I needed a better way to manage those stored procedures through different environments, for versioning and for regression testing if parameters changed. And I needed it to automatically manage things, so the idiot developers on my team wouldn't screw shit up with raw ADO.NET calls.
In the last couple of weeks I've managed to break a few of the features, but I'll be fixing them soon[3].
You define parameterized queries directly in your data access layer. These get translated into stored procedures whose name and parameters are gleaned from the sameness in your data access layer, e.g. "public UserPref GetUserPreferences(int userId){}" in C# will be used to generate a stored procedure in the database named GetUserPreferences that takes an integer parameter and selects out values that can be mapped to a structure called UserPref.
You define C# classes that map to your query views. This is why it's not an ORM: there is no attempt to resolve foreign key references to build an object graph from a query. This is also why it's fast enough for my needs: it is only a system for executing traditional SQL.
It supports SQL Server, Postgres (in master, will be fixing in dev), and MySQL (ditto). It can query from OLE DB sources like Access database. It is easy to extend to support querying from any database, as long as an ADO.NET driver exists for it. It is only a little more difficult to extend to support code generation for other databases.
At one time, it was able to analyze a database on, say, SQL Server, recreate the database in Postgres, and copy all of the data over. It lacks it now, as I had built it as a propriety extension for a client, but will be getting it back soon.
My immediate goal with the project is to create a type-safe way to manage correct database design across environments. It's all about the DRY principle. I'm very close to that goal, and even right now I think it's far better than using anything else, given the tradeoffs.
My long term goal is to make it into a system for breaking database vendor lockin. Once I have a system for analyzing query structure directly, I believe I'll be able to translate the majority of queries transparently between databases[4].
And it might not happen tomorrow, but I'm fairly certain it will eventually happen. If you told me 7 years ago that I would have made this thing that currently exists, I would have never believed it. But it's all features I need, and I make more and more progress every year, so I feel pretty confident that it will eventually get there.
[0] Which everyone used incorrectly--not disposing ...
Quite a few reasons. Originally, I was stuck on .net 2 (.net 3.5 had only just come out), so LINQ wasn't available. Then, for a long time, LINQ to SQL was not thread safe. It doesn't generate stored procedures, so there is a significant network overhead for complex queries and complex queries can't be shared across language independent projects. And finally, my system provides a ton of metadata that I could then start leveraging for script generation. Entity Framework was too all-or-nothing, and my own system had too much momentum for me by that point. It has evolved over time and it has always just been easier to adapt it than to take on whatever has been popular at the time.
Thanks for taking the time to write this up. I really appreciate it. I have been working on low level database kind of things recently so I am keen to hear about what people are doing in userspace (from a database point of view).
The article referenced by this article lists nine features of which eight are syntactic sugar. (Being able to declare the out parameter in place has a very minor but significant impact: Preventing abuse of a variable intended to be used as the out parameter.)
It's disappointing to see the team spend its time on so many minor features rather than tackling fewer major improvements.
I'm sure we all have our pet features. My wish would be structural typing: Very few of the C# developers I've worked with in the past couple of years have embraced isolation testing. A significant reason is the frustration with "extra" interfaces and the distractions they introduce in code navigation. Anything that eases the the uptake of isolation testing would dramatically improve software quality, which as we know, would dramatically improve our efficiency.
Structural typing would be nice. My wish would be algebraic data types. I'm not sure how that would even work in c# but its what I want :)
I tend to avoid using out parameters. I've written extension methods to replace the typical out param framework methods..
For example, instead of int.parse(string s, out int i), we have "123".TryParse<int>(), which returns a nullable int. instead of TryGetValue on dictionary, we have GetOrDefault(key, optional default val) and GetOrDefaultAsNullable(key).
I think the new out parameter syntax is an improvement, but I'm still on the fence about whether out parameters are even a good idea when we can instead return a single type that encodes the same information.
I'd be interested in hearing other viewpoints on this.
I love F# dearly, and despite having spent several years writing C# code earlier in my career, I still find switching back to C# from F# painful in lots of little ways.
But I think this post is off-base. First, it criticizes C# both for incorporating too many of F#'s features, but also of stagnating. I just don't see how anyone can consider C# to be stagnating... of the heavily-used-in-industry set of languages, is there any that's evolving faster? Java's just now getting lambdas, for instance!
Secondly, I think the lack of promotion of F# by Microsoft is somewhat lamentable (though the community has done a great job of picking up the slack). But I think Microsoft's in a bit of a bind - they've received a lot of criticism for having too much churn in the ecosystem (e.g. ADO -> ADO.NET -> LINQ-to-SQL -> LINQ-to-Entities). So how would the community react to the statement, "you should really be using F# instead of C# going forward" (even if decision makers believed that)? Undoubtedly people would feel that the investment they'd made in learning C# was not worth as much as they thought and they'd start looking into more stable ecosystems (I'm mainly referring here to LOB app developers, who seem to greatly value stability of their platform).
Furthermore, in some ways these changes make the on-ramp from C# to F# even easier, which is a good thing. And C#'s still missing so many great F# features that it doesn't make sense to get too worried about the ones that have been mimicked. And I think it's somewhat true that imitation is the sincerest form of flattery, and having many great features spreading to other languages is a good thing.
30 comments
[ 3.2 ms ] story [ 71.8 ms ] threadhalf assed versions things of F# already had (tuples, async and tasks I’m looking at you)
yes F# has those, but afaik so do a myriad of other languages. Even before F# saw the daylight. I'm also not sure what is half assed about them, the implementation seems quite complete?
a language that is afraid to change anything
coming from a post talking about new features and 'changing into F#' that's quite a contradiction, no?
> yes F# has those, but afaik so do a myriad of other languages. Even before F# saw the daylight. I'm also not sure what is half assed about them, the implementation seems quite complete?
it's true, but c# advocates in microsoft have been quite parasitic in their behavior of pushing the language(inside of microsoft). they have also been averse to competition. i remember it's not too long ago, that we weren't really sure if microsoft was about to pull the plug on f# or not.
there haven't been too many clr languages, and ironpython was suffocated fairly quickly. yes you can use clojure on the clr, but who's using that, and is a meaningful customer to microsoft?
f# has been really smart in it's behavior in my opinion, by fairly quickly targeting the microsoft enterprise stack, stuff like share point, dynamics, and other crap like that.
it's also a hybrid language that is close enough to c# that you can claim c# developers can just pick it up. you could argue that good developers can pick up any language, but we're not talking about good developers here. we're talking about something that is more akin to factory work.
this is just my opinion, but i think the biggest customers of microsoft are government, government contractors, and people that sell to government contractors.
it's not about whether f# is really revolutionary or not. f# is very close to ocaml. f# is revolutionary to the microsoft enterprise stack.
asp.net mvc wasn't revolutionary either, but it was revolutionary to the .net culture.
take a look at some posts describing alt .net http://msdn.microsoft.com/en-us/magazine/cc337902.aspx
Furthermore, in general F# seems to generate far less efficient code than C# does, and for the kind of development I do (games/multimedia) I'm not really willing to sacrifice even more performance just because some FP fanatic thinks C# should go away. Personally, I think the C# compiler and the .NET JIT should have a lot more tuning applied, and get things like SIMD introduced, but MS doesn't seem to care about that.
Writing code in C# also makes it accessible to a much wider set of developers. The overlap and shared heritage with languages like Java is definitely a plus, even if I don't like some of the shitty design baggage that comes with it. It's already a struggle to get the community engaged with my project, JSIL - if it was written in an obscure language like F#, it'd be nearly impossible.
i think that's the minority of c# developers though.
> I'm not really willing to sacrifice even more performance just because some FP fanatic thinks C# should go away
why should that even be question though? now think of a web application. suddenly f# reduces the amount of cruft you have to a great extent. why do people always think it's an either or? why can i not like html5, and still want it to stay outside of my desktop application?
> it's a far more inconvenient language to use for someone that hasn't been living and breathing ML for years.
yes, you may be right. but i think most programming is really copy and paste programming. when they know where they can find what they need to write their program it doesn't really matter what language it is written in.
> even if I don't like some of the shitty design baggage that comes with it
:D
> It's already a struggle to get the community engaged with my project, JSIL - if it was written in an obscure language like F#, it'd be nearly impossible
interesting project. well, i would argue that it's because your project is not really playing to the masses. vsvim for example has more forks and stars than your project, 33% of it (the core) is written in f#. but it has also been around for much longer, and addresses a need people have.
It's not simply a matter of deciding to build software for the masses. It's essential that we have software that aims at small niches because bigger mass market software can be built on top of it.
LLVM is a great example. LLVM is only useful to the tiny subset of programmers who do compiler/JIT engineering, and it requires a lot of domain expertise. Regardless, its existence has enabled a huge set of new software to be built - clang is a great compiler, emscripten is one of the first real options for running native apps in the browser, etc. None of those would exist without LLVM. Imagine how hard it would be for people to contribute to LLVM if it were written in an obscure functional language instead of in a ubiquitous one?
As far as cruft goes, yeah, F# is less verbose, but it's also harder for me to understand and harder for me to debug. A few years of practice might solve that, but it doesn't offer me enough advantages to justify that huge investment, especially since during that time I'll be writing worse-performing software whether I like it or not. The same applies for any new language, really, and I don't think new languages are a bad thing. I just think the idea that a widely-used language should be replaced with a niche one is pretty out of touch.
If you're really just doing copy/paste programming, I don't think the language you use matters, and F# offers no particular advantage for that. It seems most useful in scenarios where you are writing code from scratch, and the more robust type system and expressiveness can let you do that faster with less mistakes.
The RyuJIT project shows that .NET JIT performance is still on the radar, though I haven't seen any indication that SIMD is on the roadmap.
To your final point, it's clearly true that C# is familiar to a wider variety of developers than F# is. However, I've been impressed by the uptake of some F# libraries, like FAKE. F# reads so mush like pseudocode in some cases that it's easy for people to buy in even if they're not especially familiar with the language.
How could you possibly have decided that "parasitic" was the best word? Is C# hanging off the back of F#'s success?
Not really. .NET has succeeded to the degree it has because C# is a credible, robust, general purpose, accessible but powerful language.
This whole submission is a desperate, misled, confused attempt at elitism, and becomes particularly ridiculous when it's talking about what are trivial syntactical sugar changes.
Particularly bizarre is this confused notion that F# is being ripped off, as if there aren't many languages with most of the same rudiments.
In my experience, local inference eliminates a lot of boilerplate and clutter, while global inference isn't so important, because writing types is good documentation as you zoom out from the details of functions.
Global type inference would generate documentation automatically, to some extent.
So I might end up implementing a lot of things as F# libraries glued together by C#. I'd prefer not to have that bit of context switch there, and I've had some trouble getting the F# compiler to work with Visual Studio on all of my machines (my Windows 8 machine was fine, but my two Windows 7 setups are broken).
Okay, that's not the only thing. I really want macros. Lisp-style, not C-style. I don't care if they are "considered dangerous" to lowly corporate developers. They can pass corporate policy against their use. That should be no reason to keep them out of the hands of adults.
The wish for a macro system is a different story entirely.
For the last, ooooh, 7 years or so, I've been building a relational data access system that I have come to realize is an attempt to build a static type checker for SQL queries. It's not quite to that level yet, but right now, for me it's the most convenient way to make type-safe access to a relational database. I also think it is a very convenient way to manage change of schema over time.
I know, every hot-headed developer makes his own "ORM", but I had some specific uses cases that made sense for me to roll my own system. At the time, the only options for data access were ADO.NET [0], NHibernate[1], and a slew of NHibernate clones[2].
I needed the ability to execute fairly arbitrary SQL against a slew of databases whose schema was off limits to me. I could make all the stored procedures I wanted, but i couldn't change any tables. I needed a better way to manage those stored procedures through different environments, for versioning and for regression testing if parameters changed. And I needed it to automatically manage things, so the idiot developers on my team wouldn't screw shit up with raw ADO.NET calls.
So I created SqlSiphon: https://github.com/capnmidnight/SqlSiphon
In the last couple of weeks I've managed to break a few of the features, but I'll be fixing them soon[3].
You define parameterized queries directly in your data access layer. These get translated into stored procedures whose name and parameters are gleaned from the sameness in your data access layer, e.g. "public UserPref GetUserPreferences(int userId){}" in C# will be used to generate a stored procedure in the database named GetUserPreferences that takes an integer parameter and selects out values that can be mapped to a structure called UserPref.
You define C# classes that map to your query views. This is why it's not an ORM: there is no attempt to resolve foreign key references to build an object graph from a query. This is also why it's fast enough for my needs: it is only a system for executing traditional SQL.
It supports SQL Server, Postgres (in master, will be fixing in dev), and MySQL (ditto). It can query from OLE DB sources like Access database. It is easy to extend to support querying from any database, as long as an ADO.NET driver exists for it. It is only a little more difficult to extend to support code generation for other databases.
At one time, it was able to analyze a database on, say, SQL Server, recreate the database in Postgres, and copy all of the data over. It lacks it now, as I had built it as a propriety extension for a client, but will be getting it back soon.
My immediate goal with the project is to create a type-safe way to manage correct database design across environments. It's all about the DRY principle. I'm very close to that goal, and even right now I think it's far better than using anything else, given the tradeoffs.
My long term goal is to make it into a system for breaking database vendor lockin. Once I have a system for analyzing query structure directly, I believe I'll be able to translate the majority of queries transparently between databases[4].
And it might not happen tomorrow, but I'm fairly certain it will eventually happen. If you told me 7 years ago that I would have made this thing that currently exists, I would have never believed it. But it's all features I need, and I make more and more progress every year, so I feel pretty confident that it will eventually get there.
[0] Which everyone used incorrectly--not disposing ...
Plethora of type safe query libraries to choose from as well. No easy interop with .NET, however.
Saying that, why not LINQ-to-SQL or whatever the latest and greatest is from Microsoft, Performance?
It's disappointing to see the team spend its time on so many minor features rather than tackling fewer major improvements.
I'm sure we all have our pet features. My wish would be structural typing: Very few of the C# developers I've worked with in the past couple of years have embraced isolation testing. A significant reason is the frustration with "extra" interfaces and the distractions they introduce in code navigation. Anything that eases the the uptake of isolation testing would dramatically improve software quality, which as we know, would dramatically improve our efficiency.
I tend to avoid using out parameters. I've written extension methods to replace the typical out param framework methods.. For example, instead of int.parse(string s, out int i), we have "123".TryParse<int>(), which returns a nullable int. instead of TryGetValue on dictionary, we have GetOrDefault(key, optional default val) and GetOrDefaultAsNullable(key).
I think the new out parameter syntax is an improvement, but I'm still on the fence about whether out parameters are even a good idea when we can instead return a single type that encodes the same information.
I'd be interested in hearing other viewpoints on this.
But I think this post is off-base. First, it criticizes C# both for incorporating too many of F#'s features, but also of stagnating. I just don't see how anyone can consider C# to be stagnating... of the heavily-used-in-industry set of languages, is there any that's evolving faster? Java's just now getting lambdas, for instance!
Secondly, I think the lack of promotion of F# by Microsoft is somewhat lamentable (though the community has done a great job of picking up the slack). But I think Microsoft's in a bit of a bind - they've received a lot of criticism for having too much churn in the ecosystem (e.g. ADO -> ADO.NET -> LINQ-to-SQL -> LINQ-to-Entities). So how would the community react to the statement, "you should really be using F# instead of C# going forward" (even if decision makers believed that)? Undoubtedly people would feel that the investment they'd made in learning C# was not worth as much as they thought and they'd start looking into more stable ecosystems (I'm mainly referring here to LOB app developers, who seem to greatly value stability of their platform).
Furthermore, in some ways these changes make the on-ramp from C# to F# even easier, which is a good thing. And C#'s still missing so many great F# features that it doesn't make sense to get too worried about the ones that have been mimicked. And I think it's somewhat true that imitation is the sincerest form of flattery, and having many great features spreading to other languages is a good thing.