I'm not usually one for causal dismissals but that made me cringe. What on earth is the use case for getting rid of that tiny bit of boilerplate, relative to the complexity it adds to the language definition, that makes it worthwhile?
I agree. The only advantage I can think of is smaller hello world programs. And that seems to be important from a marketing perspective: people new to the language won't perceive it as a verbose language.
Does seem a bit of a pointless feature, especially as that very minimal boilerplate is auto-generated by any decent IDE anyway.
And I used to primarily work in scripting languages like Ruby where you'd get this 'feature' out of the box (although usually ended up writing a 'Program' class and a constructor/main method anyway for the scoping)
There is already a scripting dialect of c#, that seems mostly used in some web apps and for learning purposes. So they want to "streamline" this aspect, because currently this dialect requires a lot of custom handling. https://github.com/dotnet/csharplang/issues/2765
I'm actually a strong proponent of .NET core nowadays but I do agree some of the features being added don't seem to justify additional complexity OR just seem to overlap something you can already do in the language. I would prefer if they were a bit more cautious adding some of the features that are purely sugar.
Can you open a text editor and get going with C#? Now you easily can. iPython and python notebooks gained lots of traction from just this type of simplicity.
If you were to write a "script" using the language, doing some things just top level is simple. Very pragmatic. I ALSO like that it's an error to call to any top level functions outside of this, so it keeps this from exploding complexity everywhere.
- declare a namespace for the file (no indentation)
- declare that the file is a class and can only contain one (top level) class (still no indentation)
- `using` statements that don't import every symbol into my namespace :
using System.Console;
...
Console.WriteLine();
instead of :
using Sytem;
...
Console.WriteLine(); // where does "Console" come from ? god/IDE only knows
But yes, no to top-level programs.
But alreay with these few changes, I've saved 10% of the 80 columns width. I've made it easy to read a file without an IDE. You can start to write actual code at indentation level 0. I've made it easy to have one class per file and hard to have two class per file, in the spirit of making good pratice easy and bad practice hard.
Totally agreed on all these, though I've personally gotten around the last one by making use of `using static System.Console;` -- then you can just do `WriteLine(...);`
It doesn't solve the fundamental issue, but it definitely makes things clearer for me.
The point is : the C# namespaces, default behaviors and general usage, are only half of a good idea. Effectively importing every symbol in a namespace into the local namespace by default is so obviously bad.
Yes you can do `using Whatever = System.Console;`, fantastic, that's not the common idiom and it is harder to do (longer to write) than the usual idiom.
I don't think there is much of a use case, it's more of a marketing thing: 'Functional programming is trendy! Now you don't need that pesky class in your program!'
There’s basically no downside to adding the feature. But it really helps for playpens and notebooks and teaching. Playpens and notebooks want to focus on the example code in question and it’s good to hide the boilerplate. Teaching is vastly improved because the `main` boilerplate in hello world contains about four lessons worth of material (functions, classes, arrays, and namespaces) that needs to be handwaved to a class of beginners and if they screw up the magic incantations they get scarey error messages.
There is some benefits for the Lambda scenarios. You pick a library and then have a 3 line integration code which can be hacked on a management portal. Personally, also not in favor of this, but heck, there is worse.
I spend so long at work when working on tests making stubs of objects with private setters etc (e.g. DTOs). That work is essentially gone now, awesome!
Newtonsoft (and the new Microsoft .NET framework JSON (de)serializer) only uses the setters once too to set the properties after processing the JSON, I can't see it causing an issue.
This seems similar to the joke where after Brexit, the Germans are angry that english is still the official EU language and they change the english language until it sounds a lot like german.
In a few years, C# 20.0 will have only one release note: Changed the name from C# to F#
With Kotlin and Scala in existence, that ain’t going to happen. C# is as verbose as it was years ago. After years of Scala collections, eithers, options, why would anybody consider C#.
Just look at plumbing with init, data records and with. That is what a case class with val properties in Scala gives.
Because Scala takes mind-boggingly long to compile. Because Scala has so many features that anything has at least 3 different ways to implement it. Because it’s very easy to write unreadable code in scala, not so much in C#. Because Scala uses JVM, while C# has access to .NET (yes this is an advantage for many developers).
It's certainly slower than javac (which is pretty freaking fast - maybe not in comparison to go, but it's no slouch), but it certainly mops the floor with scalac.
What are the last Scala/sbt versions you’ve used? Scala compilation times (and sbt startup times) have improved dramatically over time, it’s reasonably fast now. In the past 3 years, the Scala compiler has gotten literally twice as fast. I don’t have hard numbers for sbt, but it feels like it has improved by much more than that.
For a mid-sized web service (tens of thousands of LOC), a clean compile might take ~30-40 seconds, but you rarely do those. Incremental compiles take more like single-digit seconds, and for most projects you can have a solid “compile on save” type setup that makes it pretty unnoticeable. And sbt itself, which used to be very slow to startup (sometimes 10-20 seconds), now starts up in a couple seconds.
It’s not lightning fast like Go, but it’s way faster than it used to be. Not much of a pain point anymore unless you’re dealing with truly huge projects.
I think it's broader than C# -> F# though. Java also has closures and higher-order functions, and in many debates on this forum it seems like OOP proponents aren't aware that these features are grafts from functional programming. OOP programmers also seem to have (finally) come around to the consensus that composition is preferable to inheritance.
So if there is a long con, I think it is about turning OOP programmers into ML or functional programmers. :p
The delegation is better than inheritance because you don't get all the methods from the base class if you don't need them.
At my company, we have banned it, because if you add a method to Bar the method is automatically added to Foo which makes the delegation as fragile as the inheritance.
Go has a similar feature, and while I don't know that I would say it's especially controversial or frowned upon, it's good form to only use it sparingly if at all. I still wouldn't say that it is anywhere near as fragile as inheritance; however--I think inheritance's fragility comes from its polymorphism (not sure about Kotlin, but in Go, the wrapper class/struct can't be passed into a function that expects the component's type).
> At my company, we have banned it, because if you add a method to Bar the method is automatically added to Foo which makes the delegation as fragile as the inheritance.
Delegation does not remove the need for interfaces.
Well, we're getting closer to F#. Still waiting on discriminated unions and expression blocks. (Yes, I know, discriminated unions in F# are just implemented in the class hierarchy. But it's awfully nice syntactic sugar.)
> Point p = new (3, 5);
At first glance, not impressive, since you could just do:
> graphics.DrawRectangle(RedBrush, new Point(3, 5, 2, 2))
what's the advantage of the first example? i prefer the second, because i don't have to look at the definition of DrawRectangle in order to know that the second argument is a 'Point' object.
That's not obvious from the function name though. The function definition could easily be `DrawRectangle(SolidColor, CornerRadii, Point)` and you wouldn't know by seeing a bunch of `DrawRectangle(RedBrush, new(1,2,4,5), Point(4,5,2,2))` would you?
It's still nice to have the option in cases where it improves readability (maybe with named args or sth)
I would love for C# to get rid of "new" as F# does -- why do we need it?
var p = Point(3,5).
For cases like this it's no big deal, but deep/complex initalizers (like expression trees, etc.) look horrible in C# unless you create static helper fn's to init objects.
How does the .NET ecosystem fare these days compared to Java's? Whatever the differences between the languages, on the surface of things it looks like one must be insane not to use Java: https://projects.apache.org/projects.html?language
Apache is somewhat Java centric. I wouldn't use that as a measure of a language's ecosystem. For example, JavaScript has an enormous ecosystem but only 17 Apache projects.
Apache is Java centric, but as a developer in both Java and .NET it's impossible to not notice that Java ecosystem has much more independently developed projects while .NET world is still largely defined what MS provides as libraries.
You'd be insane because a major Java project maintainer contains a lot of Java..? That's like pointing at Microsoft's github repo and saying you'd be insane to use anything but C# and TypeScript.
The number of repository is not the important metric that apache has.
What matter is to have at least one industry grade™ open source library for anything™
Most of apache libs are each ~20000 commits
This amount of human resources is unmatched in any other platform.
.NET ecosystem is large, but still windows-centric. If I was choosing between java and C# for a startup, I'd definitely consider C# because it does seem to be a better java (properties and LINQ are the first 2 things that come to mind).
But realistically if you're not doing .NET on windows, you're still an early adopter who's going to run into weird issues that you won't have to deal with on java.
I was referring to the ecosystem (libraries that are commonly used that might only work on windows). I've had trouble for instance finding cross-platform GUI toolkits that support linux. Microsoft's newly released toolkit doesn't.
Any of the otherlang-linq projects miss the forest for the trees, the whole point of LINQ is that it's not a set of chain-able methods on IEnumerable - providers get access to the expression tree and can use them to do all sorts of crazy things (see: EntityFramework, Linq2Sql).
I love Kotlin and I don't really get a hankering for LINQ when I'm using it, but I wish people would stop trying to say "but we can do that too!" when they really can't.
Why don't people understand that LINQ isn't just a C#-ish way to write SQL-like statements? So many people are comparing their libraries to LINQ without understanding what it actually does.
LINQ brought System.Linq.Expressions and IQueryable to .NET which allows so much more than just filtering and grouping data. You can write entire data providers with LINQ and parse arbitrary expression trees in any way you like.
Entity Framework (Core) utilizes this very well. It doesn't just query an SQL database and then use LINQ's Where, Select etc. to manipulate the data but parses everything the developer has written to an expression tree and then generates an SQL statement at runtime.
And the Mongo Linq library is often. For $reasons I worked on an implementation that had to support Sql Server and Mongo. The models and the Linq expressions worked across both and were translated appropriately. We just passed around a bunch of
> But realistically if you're not doing .NET on windows, you're still an early adopter who's going to run into weird issues that you won't have to deal with on java.
As someone with background from Java but who has worked a lot with .Net Core lately, I guess it might depend on what part of .Net you talk about.
.Net Core worked extremely well on Linux for all use cases I saw, mostly web applications, cli tooling and batch/queue processing. I cannot remember a single case where we had actual problems because of Linux.
In fact, FWIW for small console applications it ran extremely much faster on Linux than on Windows, on the same hardware.
Probably, haven't tried really on .Net but Java is awesome.
Another point where it is really hard to get people to actually understand the magnitude of the difference is in IDE support, what exists and what you get out of the box.
I mostly enjoy programming in .Net Core a lot but there are times when the difference becomes extremely visible.
Agreed. I'm very happy with it as well. MS seems very keen on this so at least for now it feels like everything is progressing even if its not currently perfect.
I think this is a valid point, two projects I'm making heavy use of are both ScyllaDB and Apache Beam. Neither have C# as a supported language.
Many big projects roll out drivers for the JVM (Java/Scala/Kotlin compatible), Python, and Go first. I agree that C# is a 'nicer language' than Java, but at this point, that doesn't make up for the lack of ecosystem.
There is nothing insane here. All depends on context. Games are known to be developed in C# and the amount of those dwarfs Java's counterpart. There are other areas with the affinity of "insanity" leaning either way.
Ignoring the flawed comparison, the Java ecosystem is better. However, recently, I see first class providers for .NET popping up with most project and the ecosystem growing dramatically. It is no longer a showstopper, it is more a reduced choice situation.
What .NET still is not really good in, is first party apps. There is no Kafka or Kubernetes programmed in .NET.
Note: you can't use C# 9 with .NET 5 preview 4; you'll have to wait until .NET 5 preview 5 is released. You can use it with the latest VS preview, though.
I still think C# is one of, if not the best of designed languages exist. Even it moves in much smaller steps than it was before I think it's for good.
I left .NET land at 6.0 and .NET 4.x versions mostly because of Windows eco-system (small open source community, almost no alternatives to out of the MS things, bad linux support). Since that I've been working with Java, Swift,JS, Python, Golang and I still think that C# is one of the best-designed languages. Very few of them keep evolving through the decades, hopefully it can become the language of the year at some point, always liked to see how new features got implemented under the hood and what kind of features get into next release.
To me C# is the second best designed language, the first being IMHO Kotlin.
I'm very interested in what you think would make C# more well designed than the latter :}
I think kotlin is ugly hack, if you take away the superficial syntax (?) it will start showing ugly side. I think it only gotten popular because of Googles push due to Oracle Java lawsuit.
I don't think Kotlin is being pushed because of the Oracle lawsuit. Most of Oracle's complaints were at the VM and standard library level, which Kotlin doesn't help with.
Kotlin allows Google to hang out in Java 8 forever. If they want new features they can just add them at the Kotlin layer. Insulates them from OpenJDK and any changes Oracle wants to make. All great opportunities to fragment the Java ecosystem
OpenJDK was always fine for them to pull in, being GPLed. They got in trouble because they based their class library on Apache Harmony originally, and Sun pulled the TCK rug out from under Harmony.
As an example, during this time the development community figured out that using immutability as the default brings benefits.
Kotlin is designed with this in mind, but C# isn't - e.g. C# has this cool feature for object initialization which is so handy and all developers use it. Except for - it doesn't work with immutable classes (the ones with readonly fields). As an effect developers dislike to use immutable classes since it's not ergonomic in C# and instead use standard POCO.
Another example is that C# still in this age does not support readonly parameters and local variables (which even Java and JavaScript (!) support). In Kotlin "readonly" local variables is the idiomatic code practice which doesn't make code any more verbose. And in the case they decide to add it to C#, it will have to be at the cost of verbosity (similarly to how Java does it) because of backwards compatibility.
I mean... if you go that route then I would say Kotlin isn't really ready to be used as a production language in most places due to the severe lack of tooling, especially when it comes to things like static analysis. Sure ktlint is there, but the rules library is lacking.
So from that perspective, Kotlin is playing catch-up.
Static analysis is the only weak point of kotlin that I'm aware of..
Intellij Idea has by default something that might be considered as static analysis.
I've answered a jetbrains survey recently and they revealed they are working on a new product that would be a full fledged static analyser, maybe this would solve the issue?
Overall I find the syntax to be a little too inconsistent for the sake of conciseness but its a well designed language. It might just be my lack of experience and the amount of features in Kotlin.
Code examples have a lot of what looks like lambda callback hell and I find it hard to read but again, I might just need more practice.
Interestingly, both are done by companies who care about developer productivity. When you here Anders Hejlsberg talking it is all about productivity (C# and TypeScript). I do not know the kotlin designers, but I bet they talk similar.
It's about trade off. A language that keep getting new features every year, will make some users happy, but will lose compiler speed and it will be harder to learn.
I love C# and have used it since the beginning (my online handles are often VisualCSharp), but I do worry about the cognitive burden of remembering idioms and dealing with multiple ways to do the same thing. This is already a huge issue with C++, and now it's slowly happening to C#. I work with many, many developers--some overseas--that are still in the string.Format era. The language is starting to show some warts due to inheriting bad decisions from former language maintainers (e.g., nullable value types and nullable reference types being treated completely differently).
I hope for C#'s sake that at some point it can metamorphize--not just evolve--into a new language that can leave some of the crufty decisions behind.
> The language is starting to show some warts due to inheriting bad decisions from former language maintainers (nullable value types and nullable reference types being treated completely differently).
That's being a little too harsh, in my opinion. Even if you were designing both kinds of nullable types right now, it'd be difficult to have them behave the same way without adding runtime support for keeping track of nullability of reference types. And that's quite a big task.
> I do worry about the cognitive burden of remembering idioms and dealing with multiple ways to do the same thing
To me, VS 2019 refactoring suggestions and Roslynator extensions helped a lot to learn and use new syntax capabilities and idioms: you write code in "the same old way" and then often roslyn is able to convert this code using new features, often in a concise, readable but undebuggable way :)
Perhaps it's gotten better - TBH I haven't checked in years - but it used to be a horrible bug ridden mess for doing things aimed at Linux (i.e. via mono).
Yeah I remember the days of subtle mono bugs and segfaults, but the new(-ish, its been out for years) .NET Core brings official support to linux. ASP.NET Core is definitely a solid platform for web apps on Linux now too.
To answer your question first: It's faster on Linux than Windows now (marginally) and completly stable on Linux. I've been running a .net core systemd service for 9 months with 0 downtime (not using the new HostedService class though). It hasn't leaked any memory at all, it's still running perfectly even though it opens thousands of files and thousands of connections to a web service every hour.
It's just a process that picks zip files from the local SFTP service, sends each entry in the zip to an external web service, and writes the result of the file to a new zip in the SFTP directory. Extremely simple, but also the kind of application in which resource leaks become apparent very fast, and it's been far more stable than anything we had on Windows where we had to reboot servers once a month just as a precaution.
A few years ago I was playing with Kotlin when it had been recently released, and I remember thinking that eventually it would be a likely candidate as a default language for new enterprise projects. My reasoning was based mostly on it being a better Java, it solved just the right problems but wasn't too different and thus easy to learn. And at the time the JVM had too many advantages over .NET (multi plataform, open source, supported every technology under the sun)
Fast forward a few years, and .net now supports Linux natively, and is even faster on Linux than Windows. Microsoft has or is open sourcing pretty much everything, and with the rise of Nuget the third party library ecosystem has grown by leaps and bounds. C# has become an amazing language, considering that back in 2000 it was basically Java. While Oracle has regressed and is oppressing the ecosystem in its typical ways.
Even though I still like Kotlin better (purely from a language design standpoint), C# has evolved so much it nearly matches it, while Java is just a kitchen sink of non-cohesive features and libraries. C# in 2020 almost seems as it was designed from the ground up to be a semi-functional asynchronous OOP language with reifed generics, linq, async / await, null safety, and many more features.
That is absolutely mind boggling, because it is a language that made nearly all the mistakes that the originally Java did back in the days (save checked exceptions), and now a days I think it should pretty much be the default plataform for any app that needs to interact with enterprise technologies, and should honestly be considered in all green field projects if the team has development expertise in it. We've stopped being a mix shop and are now pretty much .net exclusively.
> While Oracle has regressed and is oppressing the ecosystem in its typical ways.
Not sure what you're referring to here. Java/JVM has been open sourced for a while as well.
> while Java is just a kitchen sink of non-cohesive features and libraries
I disagree. If you look at the new features coming out (pattern matching, records, green threads/fibers, value types, etc.) the Java designers are taking a very principled approach. Everything fits very well with the language design.
Right now there is Xamarin Forms which has a community maintained Linux layer.
You can use that today if you write a Xamarin forms app.
From the Microsoft side of things, no, you can't just write a winforms app and use it in Linux.
However, they have announced MAUI which basically lets you write XML/XAML UI Declarations that are platform agnostic and can be translated into the various layers (such as Xamarin Forms.) I believe that's supposed to be a thing sometime late this year or early next (don't quote me on that!)
Other projects to look into are AvaloniaUI and Uno. Those are community projects that try to give you cross platform UI today.
C# is a very good language. I like it a lot, and Visual Studio is a fine IDE, but the tools pale in comparison to the JVM tools (Maven, Gradle, IntelliJ, Eclipse, Spring Boot, GraalVM, etc)
I am curious why you think this. This may have been true like 10 year ago, but in my experience modern .NET and especially .NET Core has great tooling. What in particular do you find lacking?
It's funny, the languages I ended up using the most throughout the years are Delphi, C# and most recently Typescript (where Anders is also a lead architect). And my very first lines of code could very well have been written in Turbo Pascal (also by him), if I remember correctly.
As an aside, although common, I dislike the term "poaching" when it comes to hiring. It's negative connotations are inescapable, but also inappropriate when talking about hiring.
I’ve been using Delphi before and it looks like a grown/better Pascal. C# is a c-family language which seems weird right after the switch, however you start appreciate C syntax a bit later.
I think C# was an attempt to design MS Java which is better than Java
Your both right, C# was MS Java-but-better designed by the designer of Delphi, who had recently (perhaps specifically for that project) been hired by MS.
It really is wonderful. Used it at work years ago and still miss it dearly.
The only thing I don't miss is the lack of community. Many things you can get for free in Java/Python cost money in Microsoft land. Even common stuff like decent excel and PDF support. Its getting better but was still the case last time I looked.
What C# needs is Java interop. The VM and bytecode structures are similar enough for it to work. There was a guy maintaining a library for this until recently :(
Official CLR Java interop would kill Java. Within a few years every new project would be in C#.
The only other places I'm aware Java has a big advantage is GC and monitoring. C#'s GC is old school, has long pause times. Makes C# a no-go for many uses. Java also has better monitoring and profiling support.
there's free libraries, I used a bunch of them. I guess I'm just asking you to trust me that's its not nearly as good as in Java. C# is a better language, there's no question. But I jumped off the MS bandwagon years ago because there just wasn't the community support that Java has, for better (or probably) worse
I wouldn't expect that to change any time soon. The Microsoft/Sun lawsuit still stings inside the company and has legal impact decades later (https://www.cnet.com/news/sun-microsoft-settle-java-suit/). It's the reason why, for instance, you can't download Windows 98 or Visual Studio 6 on MSDN/Visual Studio subscriptions. Microsoft is now friendlier to open source than it has been, but I would be shocked if they ever got friendlier with Java. (Disclaimer: I haven't worked at MS in several years)
And I'm sure that the Google/Oracle lawsuit hasn't exactly improved things, either. Not to mention the recent licensing changes. Java is such a can of worms legally that it's surprising that anyone sensible would want to touch it with a ten-foot pole.
There -are- still a couple sore points, PDF comes to mind. But there are at least a couple different good projects out there for working with Excel at this point.
Bigger problem is a larger portion of C# developers and their managers are frightened of shifting away from the Microsoft blessed stack. That's what creates this chicken-egg situation where good projects don't have enough community behind them because there aren't enough people using them.
GC in C# isn't perfect but works fairly well if you understand it. There's plenty of ways to write minimal or zero-allocation code and it's gotten a lot easier with the newer Span types.
Monitoring though... yeah The first time I learned about Blackbox and the like I got a bit jealous :)
Feeling the same here. It's elegant, and imo easier to read than most languages. There aren't many choices of libraries in C#, but they cover most use cases. Still I found myself happy to publish to NuGet my own package because I love exploring the language and its features.
Now developing in Python at work, I can find a multitude of packages for every need I have to meet, which is perfect for productivity, but I feel I can never understand the language enough because all I do is to import some packages and get work done.
I really hope C# gets more popular among devs. Where I live only large non-tech companies use it internally, which might explain why there are not many open source libraries in C# compared to other languages.
Though, with all the comments here saying C# is turning into F#, I'm tempted to try out F# as my first functional programming language now.
> It's amazing how the language advances over years
I think that with the latest improvements (from v7 to now) Microsoft is trying to "fill the gap" between F# and C#, and let C# developers embrace functional paradigms (at least, some of) without switching to F# itself.
This look so very prone to cause bugs. Why would you even "return if not null"? I don't think I've been in this situation before. What I do see is if x is null then return something else, but this never
What is the winforms simple (ie, drag and drop form designer, click through for code) current windows development recommendation. I've seriously lost all track of how to just get up and going. I've tried UWP/WPF etc - they felt like a bit of nightmare for quick and go, but the tooling now seems to have dropped winforms? I couldn't get the form designer to actually show up even on a WinForms project?
Sadly only in Visual Studio and not Visual Studio Code. And yes, there is probably no one who used winforms that wouldn't be shocked by WPFs steep learning curve.
Wow - GREAT news. This was EXACTLY my issue, no forms designer.
I'm mostly developing server on linux so I'm not enough of designer to even begin to wrap my head around XAML / MVVM / WPF / UPF (?) new world order on windows.
SO glad they are going to allow for some simpler approaches - and no, I don't want to build skinnable apps for business - I actually LIKED that all the apps looked / worked basically the same in the old world even though that's no longer cool.
We now have some silverlight apps, some IE only apps, some WPF / UPF apps. But the old winforms apps still get lots of use and still work. I've found the "better" WPF / UPF stuff to kind of lag and stutter even sometimes - I've got no idea why. The winforms apps on new machines are snappy.
Please don’t, if I happen to work on it I’ll burn it to the ground. I’ve worked on plenty of WPF applications written like it was winforms and they all sucks.
For quick one offs I still prefer WPF over Winforms even without MVVM and thereby avoiding the learning curve. In the long run MVVM is probably better (although I am not so sure on that either. I have seen plenty of nightmarish “proper” WPF apps too)
I still love Windows Forms and the designer. Sometimes some solutions are a bit hacky and the designer can do really weird stuff, but I can manage. I think, the standardized look and feel really works well for complex business applications.
WPF is nice for fully customized UI where you want your application to look modern, but xaml can really be daunting. And it's not only xaml, but that whole MVVM thing can be a nightmare to teach and stick to in a large team and project. Moreover you probably need some designers or an external company to design your UI's to really shine.
I would keep a close eye on MAUI [1] and where it will go. The Model-View-Update (MVU) pattern looks interesting and the cross platform aspect could be really nice.
I think that it's unfortunate they stuck with that example instead of the classic point class example for positional args. In general the positional destructuring is not great, but there are some cases where it is nice and readable. Because of that I'm glad it's not the default that all record classes get it.
I disagree. Automatic destructuring like this can be fantastic. Sure, if you're just destructuring a variable there's not much gain. But this is much smoother:
var (f, l) = SomeMethodReturningAPerson();
than:
var person = SomeMethodReturningAPerson();
var (f, l) = (person.FirstName, person.LastName);
or:
foreach(var (f, l) in enumerationOfPersons) { ... }
compared to:
foreach(var person in enumerationOfPersons)
{
var (f, l) = (person.FirstName, person.LastName);
...
}
When you know what you want to compute, but have to throw in extra temporary variables it becomes tedious and error prone. Cut straight to the thing you want (the names themselves in this case), eliminate middlemen.
You are aproaching this from the mindset of the code author, but consider a new contributor to a project reading for the first time, with positional destructuring
foreach(var (f, l) in enumerationOfPersons) { ... }
tells him absolutely nothing about what's going or even that there are names involved
foreach(var (firstName, lastName) in enumerationOfPersons) { ... }
is better but doesn't give him an object to inspect to see where they come from and what else is available.
(the "Person" type would have to implement a "Deconstruct" method with two string out parameters, or alternatively someone could write an equivalent extension method)
I'm VERY excited for Record types. Automatically having automatically deep equality in data types is going to really help maintainability- no more "developer adds a field to the type but not to the equals function" type errors.
Look - I don't have anything deep to say here. I can only say that between 'records' and 'with-expressions' now in C#, I as a hobbyist F# developer feel like I'm being shaken down by the mafia.
C# designers: "Hey, nice language features you have there. I'll just borrow them for a bit ok, it'll be fine..."
Later, C# programmers: "why would I learn F#, C# does all the same stuff!" (even though it doesn't)
Edit: I admit being both glad that C# is gradually migrating to the ML-style coding which will make F# more mainstream, and nervous that C# will get close enough to kill F# adoption yet too far away to actually get all the benefits of F#.
Some examples of this include the Hindley-Milner type system, partial application, discriminated unions, and all of the compile-time goodness the F# compiler gives and the C# compiler ignores.
Well F# obviosly never gained enough momentum and C# has to grow somewhere so why not in this direction. All "big" languages are gaining more and more functional and declarative features each version. I always remember this chat by Simon PJ, the "father" of Haskell about convergence of languages in features https://m.youtube.com/watch?v=iSmkqocn0oQ
As a member of the F# Evangelism Strike Force (to use an n-gate ism), I want to argue this point but there is not enough info to determine what 'enough momentum' means.
I can produce, without leaving F#: libraries, cli apps, windows services, windows desktop apps, websites (asp.net core + giraffe), web apps, SPAs (SAFE stack), and more. If I target .NET Core, I can run my F# in windows land, linux land, and anywhere else .net core has been ported. What features does C# offer that F# doesn't, aside from being more familiar to lots of MS devs? Even I started my dev journey with C# on Windows Mobile 5 via .Net Compact Framework.
Cons: The F# tooling is just worse than C# tooling. Compare the 20-year old language with support since Visual Studio 2003 .NET to the one that has for some reason focused on the VSCode + Ionide plugins rather than the tooling that VS users run into and even I can't really argue that C# has better tooling. Biggest weakness of F# is all the wonkiness when it comes to common tasks like making, running, building, publishing codebases. The use case of something common like 'make me a new blank app, I want it to use paket for dependencies and to spit out an alpine docker image with .net core sdk at the end' should be 1 command, then triggerable from the VS Debug/F5 button. It just isn't that yet.
> C# has to grow somewhere why not this direction
I'd rather C# lean more FP than lean more OOP, sure, but _does_ C# have to grow somewhere? Can't a language spec be declared good enough / maintenance mode at some point so the programmers can focus their learnings on fuller understanding of the spec itself, as well as improving the implementations and tooling around a language?
A language could be declaered good enough but none of the popular languages are there. They all had plenty of "bad but popular" design decisions at the beginning and now they are trying to compensate. What I hate is the constant repeating of everything. I'd rather one language have everything crammed in and we get to choose what we want and what we don't want. No "good" (my opinion) language will ever have only "one way of doing things" so why not just add everything and get over with it. In any case, all the "big" languages seem to be racing to "add everything" anyways.
IMHO my biggest issue with languages like F# and Haskell is like you mentioned the lack of tooling. I can even get over the fact that the ecosystem is smaller but the lack of ergonomics (things are harder to do, there's more friction in the dev process) always sends me back to C#. I wish F# tried to get into Roslyn instead of having their own compiler. I get the prestige and practicality of doing your own thing but I think it costed them a lot of missed out features and polish. I'm not that familiar with F#. It very well could be the language is too different to reuse almost anything from the semantic part of Roslyn but there's still so much else there they could get for free
F#'s strengths are also some of its weaknesses.
Re: H-M type system (a) the lack of decls makes code nice to look at when writing, but coming back to it a year later or w/someone else's code, it can be hard to follow. (b) Sometimes the errors are still quite baroque! And the tooling (esp. 3rd party) isn't as prevalent.
Partial application can be one of those write-only code constructs unless used in very simple/canonical patterns. I'd also like to have a Scala like "hole" syntax with positional args -- this is also need to alleviate the need to write a (fun -> ...) when calling methods on object in a |> pipeline. And speaking of pipeline, they look nice, until you want to debug through them. (Need something like Ozcode's LINQ debugger for pipelines.)
F# also (last I checked) doesn't do the level of optimizations I'd like to see, such as removal of tuple creation between fn's when there never actually stored, etc.
Although I understand the rational for the Curried form for fn types, it seems a bit pedantic to present things this way by default -- seeing (int -> string) -> Foo -> (bar list -> baz -> qux) is IMHO harder to look at than the standard presentation. Although C# really needs seq and post-fix types -- "IEnumerable<Foo>" is an eye-sore compared to "Foo seq".
If anything, these new things added to C# only make me want to use F# to a greater degree. The reasoning is simple: clearly these things are good (or at least acceptable) ideas since C# adopts them, but C# makes it more complicated to use them.
Put another way: if I'm going to use these features anyway (hint: now that they're in C#, I am) why wouldn't I do it in the language designed around them, rather than the one where they are bolted on?
When C# didn't have these features, there was ironically more reason to use C# because then these idioms could be argued to not be accepted by the community to the same degree.
It seems using toplevel programs could make it harder to find the entry point to a program. Is there an easy way, given a built assembly, to know which source file the entry point is?
What is an example of a really good codebase written in modern C#?
There are quite a few appealing things about the language, but I'm having trouble shaking the feeling that it's kind of like Java. I know both languages have evolved a lot, but some codebases might get stuck in some old patterns.
Honestly it seems like just a lot of code and very little meaning. I can't help but think that there's a better way of expressing the solution.
I could have picked the wrong file, but I was poking around in lots of directories before I found any significant C# code at all. It seems like there's a whole 'nother level of boilerplate in the directory structure.
Looking at object getter/setters in any OOP is likely to be pretty uninspiring :)
There's no logic there, this is basically just boilerplate for some other code to set properties on an object. Something that actually has some business logic will be much more interesting to read, eg.
Yeah, clearly there's some code somewhere that does something. I just don't understand why there are so many files and so much code that does nothing and means nothing.
I'm fine with verbosity. I'm fine with lots of data type declarations, annotations, things that make the compiler happy, etc.
But a file full of getters and setters? I can put up with it, but I don't understand why.
since c# 3 (2008) this would normally be expressed as
public string TypeName { get; set; }
not sure why it's not here, could just be older code. The [Parameter] etc stuff is all powershell-specific metadata that defines how to use it from the powershell language.
Powershell is itself a language, a kind of ide (consider completion/help/etc). It is not a representive code base. The .NET runtime either. Its pure scale is beyond beauty.
I would point to https://github.com/dotnet/roslyn itself as an example of a modern codebase. We try to adopt and use all of the new language features there as we write them to try and determine if the ergonomics are good.
This is like reading through a list of Christmas presents I didn't even know I wanted.
Relational/Logical patterns are going to revolutionize our ability to make high-level business logic even more accessible to non-wizards. The switch expressions introduced in 8.0 were already very nice for building out our complex in-line mapping code. This takes things to a completely different dimension.
I will say that I am a little confused on the role of Record vs Class vs Struct. Do we not already have the ability to declare immutable value types with structs? How does the Record improve on the struct which already exists in the language?
> Structs override this to have “value-based equality”, comparing each field of the struct by calling Equals on them recursively. Records do the same.
I’m also confused on the relationship between records and structs. I’m guessing in practice it has some of the properties of classes and some of the properties of structures, but I worry it’s just going to complicate things. It’s not like all the old structs in the BCL will just go away.
Isn't a big distinction of structs the fact that they are value types (and thus allocated on the stack) rather than reference types allocated on the heap?
I asked the .NET Core team this yesterday during one of the Build talks, appearently data records can be defined as either class or struct and take on the same heap/stack allocation semantics as a regular class or struct.
My understanding is that structs are not always a good choice depending on the size of the data contained within because they are put on the stack, so having an immutable class record does not necessarily overlap with the use cases for structs.
It seems like records are more of a syntactic sugar which gives you a number of pre-defined behaviours such as value comparison and immutability by default (vs. regular classes).
Well, Mono is now one of the two .NET runtimes shipped with .NET 5+. Like you mentioned, it is better for embedded and porting. That the reason they I integrate it.
Mono as a project is a dead man walking. And honestly, that is good. Unity as the major other user is surely heading for .NET 5.
I would suggest to learn to embed .NET Core 3.1 and later .NET 5. Surely possible (see Unity, interop with WinRT etc, ..).
Mono was never usable for server workloads. Its niche was the same as it is today: being portable and embeddable. .NET 5 gains that by integrating Mono. The benefits for that use case is the better tooling and ecosystem of .NET 5. With Xamarin, .NET Core and Unity doing one agenda every. NET dev wins. Mono and the .NET Framework are dead.
.NET 5 is MIT licensed and even gets attention for source focused builds (like needed by Linux distros). Redhat officially ships is own version. Summary: that is exactly not EEE.
I have worked with C# since the early beginning
I have used it daily since then.
I do know the ins and outs of the different
up until C# 8 (latest released) and now .Net core.
because I work with it every day.
This probably an unpopular opinion but
I wish they would make fewer changes to the language.
A codebase from C# 2 will look entirely different
than something written in C# 9.
If you get a developer who has great experience writing 2.0
and bring him into a project in 9 it will look to him or her like
a completely different language.
I pretty much wish they created a new .net language D#?
(or just put all the effort into changing F# (which I also like).
I also do not like the terseness. Yes I get to type a few less charcters
but it makes the language much harder to read:
Pretty much all examples here make some sense if you come from
earlier versions or other classical languages including javascript
I would not want to miss the many things in between. My argument is more: I am extremely happy I am bound to a language which actively evolves, taking me along the ride.
As much as I love F#, C# now has enough of F#'s core features that I'll probably use F# less due to the better tooling for C# code. (Resharper, Ozcode, etc.)
C# still needs DU's though...
Meta-programming support is kinda better if F#, but isn't great in either language unfortunately - you could argue the as C# is based on Rosyln that it is actually better.
I'm viewing it exactly the other way around: if my co-workers have to learn this stuff anyway, I can just as well just use F#, which implements these things in more convenient ways.
As usual a beautiful, beautiful language.
As expected, they start with something simple and build layers upon layers all connected via simple concepts.
Add init to a property, make its class a data class, and boom you have immutable beautiful class. Kudos to these designers.
(This is similar to AutoValue in Java / data class in Kotlin, but it feels a lot more elegant and connected and simple than what these other languages offer)
195 comments
[ 1.7 ms ] story [ 307 ms ] threadI'm not usually one for causal dismissals but that made me cringe. What on earth is the use case for getting rid of that tiny bit of boilerplate, relative to the complexity it adds to the language definition, that makes it worthwhile?
And I used to primarily work in scripting languages like Ruby where you'd get this 'feature' out of the box (although usually ended up writing a 'Program' class and a constructor/main method anyway for the scoping)
Can you open a text editor and get going with C#? Now you easily can. iPython and python notebooks gained lots of traction from just this type of simplicity.
If you were to write a "script" using the language, doing some things just top level is simple. Very pragmatic. I ALSO like that it's an error to call to any top level functions outside of this, so it keeps this from exploding complexity everywhere.
- declare a namespace for the file (no indentation)
- declare that the file is a class and can only contain one (top level) class (still no indentation)
- `using` statements that don't import every symbol into my namespace :
instead of : But yes, no to top-level programs.But alreay with these few changes, I've saved 10% of the 80 columns width. I've made it easy to read a file without an IDE. You can start to write actual code at indentation level 0. I've made it easy to have one class per file and hard to have two class per file, in the spirit of making good pratice easy and bad practice hard.
It doesn't solve the fundamental issue, but it definitely makes things clearer for me.
Yes you can do `using Whatever = System.Console;`, fantastic, that's not the common idiom and it is harder to do (longer to write) than the usual idiom.
I spend so long at work when working on tests making stubs of objects with private setters etc (e.g. DTOs). That work is essentially gone now, awesome!
In a few years, C# 20.0 will have only one release note: Changed the name from C# to F#
Just look at plumbing with init, data records and with. That is what a case class with val properties in Scala gives.
But congratulations to the team on shipping v9.
Thankfully that problem doesn't exist with C# /s
For a mid-sized web service (tens of thousands of LOC), a clean compile might take ~30-40 seconds, but you rarely do those. Incremental compiles take more like single-digit seconds, and for most projects you can have a solid “compile on save” type setup that makes it pretty unnoticeable. And sbt itself, which used to be very slow to startup (sometimes 10-20 seconds), now starts up in a couple seconds.
It’s not lightning fast like Go, but it’s way faster than it used to be. Not much of a pain point anymore unless you’re dealing with truly huge projects.
It isn't. Pretty much every release (including C# 9.0) adds some features that make your code more concise.
I think it's broader than C# -> F# though. Java also has closures and higher-order functions, and in many debates on this forum it seems like OOP proponents aren't aware that these features are grafts from functional programming. OOP programmers also seem to have (finally) come around to the consensus that composition is preferable to inheritance.
So if there is a long con, I think it is about turning OOP programmers into ML or functional programmers. :p
The delegation is better than inheritance because you don't get all the methods from the base class if you don't need them.
At my company, we have banned it, because if you add a method to Bar the method is automatically added to Foo which makes the delegation as fragile as the inheritance.
Delegation does not remove the need for interfaces.
Except that Smalltalk -for which the term "object oriented" was invented - had them.
https://www.infoq.com/presentations/functional-pros-cons/
> Point p = new (3, 5);
At first glance, not impressive, since you could just do:
> var p = new Point(3,5);
However, it would clean up code like:
> graphics.DrawRectangle(RedBrush, new(3, 5, 2, 2))
> graphics.DrawRectangle(RedBrush, new Point(3, 5, 2, 2))
what's the advantage of the first example? i prefer the second, because i don't have to look at the definition of DrawRectangle in order to know that the second argument is a 'Point' object.
It's still nice to have the option in cases where it improves readability (maybe with named args or sth)
new List<KeyValuePair<string,int>> { new (“a”, 1), new (“b”, 2) }
versus having to barf out the type name for every element will be REALLY nice.
Saves some typing but it also has refactor implications too. If you change the parameter type, it would change the object being constructed.
var p = Point(3,5).
For cases like this it's no big deal, but deep/complex initalizers (like expression trees, etc.) look horrible in C# unless you create static helper fn's to init objects.
Personally I think this is a better source: https://octoverse.github.com#top-languages
Or this: https://insights.stackoverflow.com/survey/2019#technology
But realistically if you're not doing .NET on windows, you're still an early adopter who's going to run into weird issues that you won't have to deal with on java.
.NET 5 is going to change this completely. .NET Core has already changed.
I love Kotlin and I don't really get a hankering for LINQ when I'm using it, but I wish people would stop trying to say "but we can do that too!" when they really can't.
LINQ brought System.Linq.Expressions and IQueryable to .NET which allows so much more than just filtering and grouping data. You can write entire data providers with LINQ and parse arbitrary expression trees in any way you like.
Entity Framework (Core) utilizes this very well. It doesn't just query an SQL database and then use LINQ's Where, Select etc. to manipulate the data but parses everything the developer has written to an expression tree and then generates an SQL statement at runtime.
As someone with background from Java but who has worked a lot with .Net Core lately, I guess it might depend on what part of .Net you talk about.
.Net Core worked extremely well on Linux for all use cases I saw, mostly web applications, cli tooling and batch/queue processing. I cannot remember a single case where we had actual problems because of Linux.
In fact, FWIW for small console applications it ran extremely much faster on Linux than on Windows, on the same hardware.
Another point where it is really hard to get people to actually understand the magnitude of the difference is in IDE support, what exists and what you get out of the box.
I mostly enjoy programming in .Net Core a lot but there are times when the difference becomes extremely visible.
Many big projects roll out drivers for the JVM (Java/Scala/Kotlin compatible), Python, and Go first. I agree that C# is a 'nicer language' than Java, but at this point, that doesn't make up for the lack of ecosystem.
What .NET still is not really good in, is first party apps. There is no Kafka or Kubernetes programmed in .NET.
I left .NET land at 6.0 and .NET 4.x versions mostly because of Windows eco-system (small open source community, almost no alternatives to out of the MS things, bad linux support). Since that I've been working with Java, Swift,JS, Python, Golang and I still think that C# is one of the best-designed languages. Very few of them keep evolving through the decades, hopefully it can become the language of the year at some point, always liked to see how new features got implemented under the hood and what kind of features get into next release.
Well done C# team
It's amazing how the language advances over years
As an example, during this time the development community figured out that using immutability as the default brings benefits.
Kotlin is designed with this in mind, but C# isn't - e.g. C# has this cool feature for object initialization which is so handy and all developers use it. Except for - it doesn't work with immutable classes (the ones with readonly fields). As an effect developers dislike to use immutable classes since it's not ergonomic in C# and instead use standard POCO.
Another example is that C# still in this age does not support readonly parameters and local variables (which even Java and JavaScript (!) support). In Kotlin "readonly" local variables is the idiomatic code practice which doesn't make code any more verbose. And in the case they decide to add it to C#, it will have to be at the cost of verbosity (similarly to how Java does it) because of backwards compatibility.
Well good thing they're adding that in C# 9 then
Still, they are playing catch-up here.
So from that perspective, Kotlin is playing catch-up.
There is also detekt but it's true it is inferior to solution that Java has. https://github.com/detekt/detekt
PMD is targeting kotlin initial support for their next major release https://github.com/pmd/pmd/issues/419
I've answered a jetbrains survey recently and they revealed they are working on a new product that would be a full fledged static analyser, maybe this would solve the issue?
Code examples have a lot of what looks like lambda callback hell and I find it hard to read but again, I might just need more practice.
I hope for C#'s sake that at some point it can metamorphize--not just evolve--into a new language that can leave some of the crufty decisions behind.
That's being a little too harsh, in my opinion. Even if you were designing both kinds of nullable types right now, it'd be difficult to have them behave the same way without adding runtime support for keeping track of nullability of reference types. And that's quite a big task.
To me, VS 2019 refactoring suggestions and Roslynator extensions helped a lot to learn and use new syntax capabilities and idioms: you write code in "the same old way" and then often roslyn is able to convert this code using new features, often in a concise, readable but undebuggable way :)
Perhaps it's gotten better - TBH I haven't checked in years - but it used to be a horrible bug ridden mess for doing things aimed at Linux (i.e. via mono).
Even the newly announced MAUI is only "community supported" on linux.
It's just a process that picks zip files from the local SFTP service, sends each entry in the zip to an external web service, and writes the result of the file to a new zip in the SFTP directory. Extremely simple, but also the kind of application in which resource leaks become apparent very fast, and it's been far more stable than anything we had on Windows where we had to reboot servers once a month just as a precaution.
A few years ago I was playing with Kotlin when it had been recently released, and I remember thinking that eventually it would be a likely candidate as a default language for new enterprise projects. My reasoning was based mostly on it being a better Java, it solved just the right problems but wasn't too different and thus easy to learn. And at the time the JVM had too many advantages over .NET (multi plataform, open source, supported every technology under the sun)
Fast forward a few years, and .net now supports Linux natively, and is even faster on Linux than Windows. Microsoft has or is open sourcing pretty much everything, and with the rise of Nuget the third party library ecosystem has grown by leaps and bounds. C# has become an amazing language, considering that back in 2000 it was basically Java. While Oracle has regressed and is oppressing the ecosystem in its typical ways.
Even though I still like Kotlin better (purely from a language design standpoint), C# has evolved so much it nearly matches it, while Java is just a kitchen sink of non-cohesive features and libraries. C# in 2020 almost seems as it was designed from the ground up to be a semi-functional asynchronous OOP language with reifed generics, linq, async / await, null safety, and many more features.
That is absolutely mind boggling, because it is a language that made nearly all the mistakes that the originally Java did back in the days (save checked exceptions), and now a days I think it should pretty much be the default plataform for any app that needs to interact with enterprise technologies, and should honestly be considered in all green field projects if the team has development expertise in it. We've stopped being a mix shop and are now pretty much .net exclusively.
Not sure what you're referring to here. Java/JVM has been open sourced for a while as well.
> while Java is just a kitchen sink of non-cohesive features and libraries
I disagree. If you look at the new features coming out (pattern matching, records, green threads/fibers, value types, etc.) the Java designers are taking a very principled approach. Everything fits very well with the language design.
Right now there is Xamarin Forms which has a community maintained Linux layer.
You can use that today if you write a Xamarin forms app.
From the Microsoft side of things, no, you can't just write a winforms app and use it in Linux.
However, they have announced MAUI which basically lets you write XML/XAML UI Declarations that are platform agnostic and can be translated into the various layers (such as Xamarin Forms.) I believe that's supposed to be a thing sometime late this year or early next (don't quote me on that!)
Other projects to look into are AvaloniaUI and Uno. Those are community projects that try to give you cross platform UI today.
As an aside, although common, I dislike the term "poaching" when it comes to hiring. It's negative connotations are inescapable, but also inappropriate when talking about hiring.
I think C# was an attempt to design MS Java which is better than Java
The only thing I don't miss is the lack of community. Many things you can get for free in Java/Python cost money in Microsoft land. Even common stuff like decent excel and PDF support. Its getting better but was still the case last time I looked.
What C# needs is Java interop. The VM and bytecode structures are similar enough for it to work. There was a guy maintaining a library for this until recently :(
Official CLR Java interop would kill Java. Within a few years every new project would be in C#.
The only other places I'm aware Java has a big advantage is GC and monitoring. C#'s GC is old school, has long pause times. Makes C# a no-go for many uses. Java also has better monitoring and profiling support.
There -are- still a couple sore points, PDF comes to mind. But there are at least a couple different good projects out there for working with Excel at this point.
Bigger problem is a larger portion of C# developers and their managers are frightened of shifting away from the Microsoft blessed stack. That's what creates this chicken-egg situation where good projects don't have enough community behind them because there aren't enough people using them.
GC in C# isn't perfect but works fairly well if you understand it. There's plenty of ways to write minimal or zero-allocation code and it's gotten a lot easier with the newer Span types.
Monitoring though... yeah The first time I learned about Blackbox and the like I got a bit jealous :)
Now developing in Python at work, I can find a multitude of packages for every need I have to meet, which is perfect for productivity, but I feel I can never understand the language enough because all I do is to import some packages and get work done.
I really hope C# gets more popular among devs. Where I live only large non-tech companies use it internally, which might explain why there are not many open source libraries in C# compared to other languages.
Though, with all the comments here saying C# is turning into F#, I'm tempted to try out F# as my first functional programming language now.
I think that with the latest improvements (from v7 to now) Microsoft is trying to "fill the gap" between F# and C#, and let C# developers embrace functional paradigms (at least, some of) without switching to F# itself.
If it returns null, what's the difference between:
>return foo;
and
>return? foo;
?
if(?foo){return null}
https://devblogs.microsoft.com/dotnet/windows-forms-designer...
Sadly only in Visual Studio and not Visual Studio Code. And yes, there is probably no one who used winforms that wouldn't be shocked by WPFs steep learning curve.
I'm mostly developing server on linux so I'm not enough of designer to even begin to wrap my head around XAML / MVVM / WPF / UPF (?) new world order on windows.
SO glad they are going to allow for some simpler approaches - and no, I don't want to build skinnable apps for business - I actually LIKED that all the apps looked / worked basically the same in the old world even though that's no longer cool.
We now have some silverlight apps, some IE only apps, some WPF / UPF apps. But the old winforms apps still get lots of use and still work. I've found the "better" WPF / UPF stuff to kind of lag and stutter even sometimes - I've got no idea why. The winforms apps on new machines are snappy.
WPF is nice for fully customized UI where you want your application to look modern, but xaml can really be daunting. And it's not only xaml, but that whole MVVM thing can be a nightmare to teach and stick to in a large team and project. Moreover you probably need some designers or an external company to design your UI's to really shine.
I would keep a close eye on MAUI [1] and where it will go. The Model-View-Update (MVU) pattern looks interesting and the cross platform aspect could be really nice.
[1] https://devblogs.microsoft.com/dotnet/introducing-net-multi-...
var (f, l) = person;
is so much worse than
var (f, l) = (person.FirstName, person.LastName);
I don't want to have to refer to documentation or class implementation to understand what a destructuring expression does.
foreach(var (f, l) in enumerationOfPersons) { ... }
tells him absolutely nothing about what's going or even that there are names involved
foreach(var (firstName, lastName) in enumerationOfPersons) { ... }
is better but doesn't give him an object to inspect to see where they come from and what else is available.
(the "Person" type would have to implement a "Deconstruct" method with two string out parameters, or alternatively someone could write an equivalent extension method)
C# designers: "Hey, nice language features you have there. I'll just borrow them for a bit ok, it'll be fine..."
Later, C# programmers: "why would I learn F#, C# does all the same stuff!" (even though it doesn't)
Edit: I admit being both glad that C# is gradually migrating to the ML-style coding which will make F# more mainstream, and nervous that C# will get close enough to kill F# adoption yet too far away to actually get all the benefits of F#.
Some examples of this include the Hindley-Milner type system, partial application, discriminated unions, and all of the compile-time goodness the F# compiler gives and the C# compiler ignores.
As a member of the F# Evangelism Strike Force (to use an n-gate ism), I want to argue this point but there is not enough info to determine what 'enough momentum' means.
I can produce, without leaving F#: libraries, cli apps, windows services, windows desktop apps, websites (asp.net core + giraffe), web apps, SPAs (SAFE stack), and more. If I target .NET Core, I can run my F# in windows land, linux land, and anywhere else .net core has been ported. What features does C# offer that F# doesn't, aside from being more familiar to lots of MS devs? Even I started my dev journey with C# on Windows Mobile 5 via .Net Compact Framework.
Cons: The F# tooling is just worse than C# tooling. Compare the 20-year old language with support since Visual Studio 2003 .NET to the one that has for some reason focused on the VSCode + Ionide plugins rather than the tooling that VS users run into and even I can't really argue that C# has better tooling. Biggest weakness of F# is all the wonkiness when it comes to common tasks like making, running, building, publishing codebases. The use case of something common like 'make me a new blank app, I want it to use paket for dependencies and to spit out an alpine docker image with .net core sdk at the end' should be 1 command, then triggerable from the VS Debug/F5 button. It just isn't that yet.
> C# has to grow somewhere why not this direction
I'd rather C# lean more FP than lean more OOP, sure, but _does_ C# have to grow somewhere? Can't a language spec be declared good enough / maintenance mode at some point so the programmers can focus their learnings on fuller understanding of the spec itself, as well as improving the implementations and tooling around a language?
IMHO my biggest issue with languages like F# and Haskell is like you mentioned the lack of tooling. I can even get over the fact that the ecosystem is smaller but the lack of ergonomics (things are harder to do, there's more friction in the dev process) always sends me back to C#. I wish F# tried to get into Roslyn instead of having their own compiler. I get the prestige and practicality of doing your own thing but I think it costed them a lot of missed out features and polish. I'm not that familiar with F#. It very well could be the language is too different to reuse almost anything from the semantic part of Roslyn but there's still so much else there they could get for free
Partial application can be one of those write-only code constructs unless used in very simple/canonical patterns. I'd also like to have a Scala like "hole" syntax with positional args -- this is also need to alleviate the need to write a (fun -> ...) when calling methods on object in a |> pipeline. And speaking of pipeline, they look nice, until you want to debug through them. (Need something like Ozcode's LINQ debugger for pipelines.)
F# also (last I checked) doesn't do the level of optimizations I'd like to see, such as removal of tuple creation between fn's when there never actually stored, etc.
Although I understand the rational for the Curried form for fn types, it seems a bit pedantic to present things this way by default -- seeing (int -> string) -> Foo -> (bar list -> baz -> qux) is IMHO harder to look at than the standard presentation. Although C# really needs seq and post-fix types -- "IEnumerable<Foo>" is an eye-sore compared to "Foo seq".
But it's hard to go back to any lang w/o DU's...
Put another way: if I'm going to use these features anyway (hint: now that they're in C#, I am) why wouldn't I do it in the language designed around them, rather than the one where they are bolted on?
When C# didn't have these features, there was ironically more reason to use C# because then these idioms could be argued to not be accepted by the community to the same degree.
There are quite a few appealing things about the language, but I'm having trouble shaking the feeling that it's kind of like Java. I know both languages have evolved a lot, but some codebases might get stuck in some old patterns.
https://github.com/dotnet/runtime
https://github.com/PowerShell/PowerShell
Honestly it seems like just a lot of code and very little meaning. I can't help but think that there's a better way of expressing the solution.
I could have picked the wrong file, but I was poking around in lots of directories before I found any significant C# code at all. It seems like there's a whole 'nother level of boilerplate in the directory structure.
There's no logic there, this is basically just boilerplate for some other code to set properties on an object. Something that actually has some business logic will be much more interesting to read, eg.
https://github.com/PowerShell/PowerShell/blob/15c2245af97486...
I'm fine with verbosity. I'm fine with lots of data type declarations, annotations, things that make the compiler happy, etc.
But a file full of getters and setters? I can put up with it, but I don't understand why.
public string TypeName { get; set; }
not sure why it's not here, could just be older code. The [Parameter] etc stuff is all powershell-specific metadata that defines how to use it from the powershell language.
It would be nice to see if some other codebases managed to free themselves from some of this cruft and make something more approachable.
Relational/Logical patterns are going to revolutionize our ability to make high-level business logic even more accessible to non-wizards. The switch expressions introduced in 8.0 were already very nice for building out our complex in-line mapping code. This takes things to a completely different dimension.
I will say that I am a little confused on the role of Record vs Class vs Struct. Do we not already have the ability to declare immutable value types with structs? How does the Record improve on the struct which already exists in the language?
> Structs override this to have “value-based equality”, comparing each field of the struct by calling Equals on them recursively. Records do the same.
Seems like we might be splitting hairs here?
My understanding is that structs are not always a good choice depending on the size of the data contained within because they are put on the stack, so having an immutable class record does not necessarily overlap with the use cases for structs.
It seems like records are more of a syntactic sugar which gives you a number of pre-defined behaviours such as value comparison and immutability by default (vs. regular classes).
Mono remains the best (only?) solution to call C# from C++ in a crossplatform way using embedding.
Mono as a project is a dead man walking. And honestly, that is good. Unity as the major other user is surely heading for .NET 5.
I would suggest to learn to embed .NET Core 3.1 and later .NET 5. Surely possible (see Unity, interop with WinRT etc, ..).
.NET 5 is MIT licensed and even gets attention for source focused builds (like needed by Linux distros). Redhat officially ships is own version. Summary: that is exactly not EEE.
This probably an unpopular opinion but I wish they would make fewer changes to the language.
A codebase from C# 2 will look entirely different than something written in C# 9.
If you get a developer who has great experience writing 2.0 and bring him into a project in 9 it will look to him or her like a completely different language.
I pretty much wish they created a new .net language D#? (or just put all the effort into changing F# (which I also like).
I also do not like the terseness. Yes I get to type a few less charcters but it makes the language much harder to read:
Pretty much all examples here make some sense if you come from earlier versions or other classical languages including javascript
https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...
Add init to a property, make its class a data class, and boom you have immutable beautiful class. Kudos to these designers.
(This is similar to AutoValue in Java / data class in Kotlin, but it feels a lot more elegant and connected and simple than what these other languages offer)