118 comments

[ 3.2 ms ] story [ 176 ms ] thread
Minor nitpick: the title is (edit: was) missing a leading dot.
So, lets say someone had never worked with C# or .net before and works on a mac - where would you go to get started building a small server application? I assume you would use the .net core stuff? and visual studio code? Any good tutorials for noob-to-the-ecosystem but someone that has programming experience?
Get Xamarin. You can start doing OS X apps with C# right away. They have a lot of tutorials on their website.
This is what I've run through: https://docs.microsoft.com/en-us/aspnet/core/tutorials/your-...

It's nice. I went on to modify and hack with what I created to form it into a back end for a mobile app I'm playing around with. There are still some warts in the process (Namely just figuring out how everything fits together and which packages to import) but I've been pleasantly surprised.

It looks like the new Visual Studio for Mac (ie An updated Xamarin Studio) has an ASP.Net Core template. At least I thought I saw that on the live stream earlier today. Might want to check that out!

Are we back to the 90-ties with no code highlights in text?
Yeah, it's particularly bad on mobile too as the code is auto-wrap so the code 's utterly illegible.

Nice blog post, shame about the bloody awful presentation.

The markup actually does have coloring. However, there's a CSS rule that's overriding them all back to black. How strange.
Throw expressions are particularly welcome. I'd previously dealt with that issue by creating a static method that returned the expected type, but just threw an exception [1][2]

I'm not sure it's explicit in the blog, but it seems the deconstructor will be useful for pattern-matching using 'is'.

Tuples. Yay! Finally!

Pattern-matching-switch-statement: Not an expression. That's a bad call. We have expression based ternary, throws, method bodies, and LINQ; switches are the last and most painful omission.

Local functions: Fantastic for libraries like mine, which is trying to bring functional programming to the C# world, but takes a hit with the allocation of delegates for common operations [3] It should be a boon for anything LINQ based (implementations, rather than usage).

Return by ref and out parameters: I'd be happy if they just removed them from the language. Ugly, error magnets.

All in all, good progress. Hopefully they can make more progress on facilitating expression-based programming, and bring in record types for the next release. The pain of creating immutable types is truly tedious. And I'd desperately like to see partial generic parameter specifying (for when one of the generic arguments can't be inferred by the type-system, so you then end up having to specify them all).

[1] https://github.com/louthy/language-ext/blob/master/LanguageE...

[2] https://github.com/louthy/language-ext/blob/master/LanguageE...

[3] https://github.com/louthy/language-ext/blob/type-classes/Lan...

Fully agreed on pattern matching not being an expression. I really dislike that syntax overall. I get the reluctance to introduce new keywords (though this did introduce 'when', but I suppose it's contexual at least), but trying to shoehorn pattern matching into the, um, let's be nice and call it "venerable", old switch/case does not look very ergonomic at all.

And I don't know about you, but I rarely switch over polymorphic types these days, I mostly switch over values, so the pattern matching overall is way less useful to me without records/discriminated unions.

I guess you can't really remove 'ref' and 'out' due to interop. Maybe the ref returns stuff will be nice if we get more performant string/array views in the next version, and I do like the inline 'var out'.

I also want type inference for field declaration+initialization, but I think Eric Lippert once explained why that was a difficult problem to solve, albeit I can't remember the reason.

I think switch could have been made into an expression very easily by following the lead of lambdas and method-body expressions, namely the => arrow.

    var area = switch 
    (
        case Line l      => 0;
        case Rectangle r => r.Width * r.Height;
        case Circle c    => Math.PI * c.Radius * c.Radius;

        default: throw new ApplicationException();
    )
That 'feels' to me to be consistent with the expression approach taken elsewhere, whilst making it clear to anybody used to seeing the statement based switch that it's different.

> so the pattern matching overall is way less useful to me without records/discriminated unions.

I agree partially. I think it's possible (I'll investigate tomorrow) to provide an 'is' operator override. So for example in my implementation of Option<T> [1] (which would usually be a sum-type of Some(x) and None, I instead use a struct (to remove a 3rd state of null).

With the 'is' operator I'm hoping to do this:

    public static class Some
    {
        public static bool operator is(Option<T> option, out T value)
        {
            value = option.Value; // Value is internal
            return option.IsSome;
        }
    }

    switch(option)
    {
        case Some x: ...; break;
        default: ...; break;
    }
I'm not sure if I can do this:

    public static class None
    {
        public static bool operator is(Option<T> option)
        {
            return option.IsNone;
        }
    }

    switch(option)
    {
        case Some x: ...; break;
        case None: ...; break;
    }
So although it doesn't solve the general need for sum-types and record-types, it should hopefully facilitate some of the common use cases.

Agreed about ref and out; I understand their purpose, I just despise them with a passion. Their whole syntax and ickyness makes me feel queesy. The inline var out feels like an imbalanced expression. They're clearly more useful now, but they still feel odd.

[1] https://github.com/louthy/language-ext/blob/master/LanguageE...

Regarding switch-as-expression -- the semantics of pattern matching as an expression can be subtle, especially when paired with nullability, so I think there's more support for introducing a new "match" expression that does what you describe.

Switch is more of an effort to integrate patterns in the way C# is used right now.

> the semantics of pattern matching as an expression can be subtle, especially when paired with nullability

Could you expand upon that? If I can do this:

    var area = shape is Line l      ? 0
             : shape is Rectangle r ? r.Width * r.Height
             : shape is Circle c    ? Math.PI * c.Radius * c.Radius
             : throw new ApplicationException();
How is this, a collection of predicates and expressions, not the same?

    var area = switch(shape)
    {
        case Line l      => 0;
        case Rectangle r => r.Width * r.Height;
        case Circle c    => Math.PI * c.Radius * c.Radius;
        default          => throw new ApplicationException();
    }
I realise you work on Roslyn (and you said semantics, so my example may be a bit off), so I'd love the detail on why the above is problematic.
Well, let's say Line, Rectangle, and Circle are reference types.

Which case does null match?

If you match the first type, that's somewhat unsatisfying. But if you only match with default, that's also unsatisfying because now we would have a problem with completeness -- if the match doesn't succeed then you have a potentially unassigned variable.

So now every match expression would have to have a default case just to handle null, but you also don't gain the advantages of static matching because everything matches default, so if you do legitimately forget a case you get no warning.

Existing switch statements are much more resilient to these matters simply because they aren't expected to be exhaustive right now. People are used to the fact that they have to deal with unassigned variables or completeness failures.

The match expression, however, I want to be more like ML where you can get strong guarantees on the "irrefutability" of a match.

> Well, let's say Line, Rectangle, and Circle are reference types.

> Which case does null match?

None of them, it should be a case on its own:

    var area = switch(shape)
    {
        case Line l      => 0;
        case Rectangle r => r.Width * r.Height;
        case Circle c    => Math.PI * c.Radius * c.Radius;
        case null        => throw new ArgumentNullException();
    }
That would allow for completeness checking, and if you do want a catch-all then you'd add a default clause.

I have since looked at the proposal for the expression based switch. TBH, I'll just be happy when it's in the language, the syntax is less important to me; but I am not quite sure it needed such a drastic change - it does feel a touch awkward.

> The match expression, however, I want to be more like ML where you can get strong guarantees on the "irrefutability" of a match.

Music to my ears.

Of all the new features, ref return leaves me scratching my head. I agree ref and out should go away. Adding more support for ref will only increase its usage when it should be deprecated.
Why not support more safe ref/out uses? I don't see any need for them to go away. You're already disincentivized from using them due to the syntactic annotations required and they aren't compatible with standard delegate parameter types. So if you are using ref/out, you actually need them for some reason (likely performance-related).
It shouldn't be deprecated any more so than "unsafe" and "stackalloc". It's a great advanced tool for perf-sensitive code - not something you should reach by default, but something to keep in mind when firing up that profiler.

CLR supported the concept since 1.0. Surfacing it in C# has been long overdue, and makes it possible to write more low-level stuff without having to go to C++.

> Return by ref and out parameters: I'd be happy if they just removed them from the language. Ugly, error magnets.

I disagree. Firstly, more high-performance non-allocating code can now be written safely instead of dropping down into unsafe languages.

Secondly, ref and out parameters are address types, which the CLR and C# need to properly handle to support value types/structs.

Kinda surprised me Microsoft doesn't have better syntax highlighting on msdn.

The lack of coloration and gray background gave me a little bit of a headache.

Coupled with the wrapping, paucity of line breaks, and (near lack of) indentation, the examples are damn near unreadable.
The markup actually does have coloring. However, there's a CSS rule that's overriding them all back to black. How strange.
It is rather baffling. They have an amazing online code browsing tool they use for the reference source of the .NET Framework (enormously useful for figuring out all the details they don't bother to document and the type system can't express), but they aren't applying that tech more universally.

The blog platform particularly suffers for it.

MSDN (web version, maybe desktop app still exists, I don't know) still has very poor usability. Recently I decided to try .NET and was surprised how painful MSDN is (compared to almost any other documentation website). Page load times of 5-10 seconds, poor navigation (2-3 link clicks just to get to list of class methods).

Does anyone know any alternative .NET documentation viewers (usable without Visual Studio and Windows)?

Can someone give an example of a use case for a Deconstructor?
var (r, g, b, a) = pixel
Looks a lot like Elixir's pattern matching to extract values from maps.

    someMap = {1, 2}
    {foo, bar} = someMap
    foo # 1
    bar # 2
This is destructuring assignment, as practiced by many languages before. Pretty much anything in the ML family, for example.

    var (ret, err) = Foo();
    if (err != null) {
      ...
    }
So Foo() has to return a class which has a destructor? Seems like just returning a Tuple would be better in that case.
Tuple in C# is a class IIRC. Without destructor, you will have to pull out individual members separately. For example for a tuple of form <Int, Int, Int>, you will do something like `var r = c.getFirst(); var g = c.getSecond();`. With deconstructor, you can do the same via `var (r, g, b) = color;`. In other words, you can say that tuples are way to combine data, while deconstructors tell how to explode it. Since these deconstructors are themselves functions, you can do computation each time, and get different results due to side-effects (probably not good idea).

EDIT: I don't know C#, so syntax is definitely not right.

You would just check t.Item2, no need to assign to variables I'm this example. However, the deconstructor syntax is nice, and now tour functions don't all return Tuple with vaguely named members.
Right. Not great example. What I wanted to say was deconstructor is all about creating new bindings with nicer syntax. You could just do that by calling getters / accessing fields, but you have to write more when you doing that.
Well, it allows you to return multiple objects without using an opaque Tuple or creating your own class. Sure, the other options work, this is just a nicer syntax. I mean, I can all of what C# does in C if I want to, but I appreciate the syntactical sugar.
Basically yes. Except, with the new tuple syntax support in C# it's using a value type internally instead of the old Tuple class (I'm pretty sure Tuple's going to be gaining a set of deconstructors to allow it to participate though). And the pure tuple path apparently doesn't use the deconstructors, there's something fancier going on under the hood which is presumably faster.

But yes you can write a deconstructor for anything you like so it can participate in deconstructing assignment. And yes it can have side effects. And that would be VERY BAD.

OK, but that's not what the TFA describes as a deconstructor.
It's linked to providing these tuple types out of a method call.

So instead of having to declare that Foo returns a FooReturn, it can be declared as (say)

    public (int ret, string err) Foo() { return (5, "something"); }
That's not a deconstructor though, which is what the GP was asking about.

EDIT: Looks like there's confusion... Yes, you can deconstruct a Tuple like this, but C# 7 also introduces a specific Deconstructor pattern in which ANY class can be deconstructed as though it were a Tuple.

I was just going to say.

The other new features seem like very welcome additions but the deconstructor seems a bit contrived and a rare use-case which does not directly solve an existing problem (also makes it easy to confuse desctructor/deconstructor for newbies).

So ignoring all the confused replies you got from people who didn't read TFA, it looks like Deconstructors allow a concrete class to participate in multiple assignment (aka deconstruction) just like a Tuple. Like with Tuple, you can deconstruct like this:

    var pix = (int R = 255, int G = 255, int B = 255);
    var (r1, g1, b1) = pix;
Except what if you're also working with 3D location data? E.g.:

    var pos = (int X = 100, int Y = 100, int Z = 100);
    var (x1, y1, z1) = pos;
Both pos and pix have the same underlying type of Tuple<int,int,int>, which could lead to confusion. Better to have concrete Pixel and Position classes. You can then give those classes a Deconstruct method and then use them the same way:

    var pix = new Pixel(255, 255, 255);
    var (r1, g1, b1) = pix;
    var pos = new Position(100, 100, 100);
    var (x, y, z) = pos;
I'm a little disappointed that pattern matching doesn't simply narrow the variable, and instead requires a new variable name to hold the narrowed type. Even TypeScript narrows the variable in-place!
You may want to deconstruct the value and use the original base value. This seems entirely logical, and consistent with most implementations in functional languages (and I'd say makes TypeScript's implementation the poor one - although I haven't seen it myself to have an opinion on).
> You may want to deconstruct the value and use the original base value.

I think this is exactly right. Members can be declared visible only when viewing an object through a particular supertype, and you may simultaneously need to invoke methods from the supertype and the subtype.

Thing is, in most cases, you don't want to do that. You just want to narrow the type.

It's unfortunate that this isn't readily possible even by explicitly reusing the name - C# shadowing rules for locals preclude it. So you can't do something like `if (x is int x) { ... }`.

I believe this would cause a change in the CLR as opposed to just syntax sugar. It's less of an issue for typescript since all type information is erased at runtime.
The CLR doesn't care, it doesn't see the C# code and the compiler could just as well emit another local for the narrowed variable. The language semantics here don't really depend on what the CLR does.
That would apply only if you were switching on a variable and not a more general expression. Scala does the same thing, I think.
Is it just me, or is C# basically becoming Scala (or, insert your favorite functional language here). Don't get me wrong, this is awesome, .net on Linux, dockerized, is all good, but these moves definitely show Microsoft responding to market changes in a way they didn't used to.
C# first introduced lambdas and LINQ in v3, back in 2007. It was the first mainstream OO language to really push a more functional/mixed-paradigm approach.

This is definitely an area where Microsoft has lead the market, not followed it.

They may have been the first, and LINQ was (and is) a truly great feature (I'd love it if they'd expand the grammar, or allow computation expressions like F#); but the problem I've found with trying to do functional programming in C# is that there's no BCL support. Whereas F# has its functional prelude.

I haven't spent much time with Scala, but I get the impression that a lot of the functional stuff is there by default (or at least easily accessibly via Scalaz) and therefore less inertia is needed to write functionally in Scala. Even with LINQ most C# programmers think it's just for querying databases or XML files, they don't realise they have built in monad semantics.

I found that I'd have an immutable collections library over there, that wasn't aware of the Option type in that library over there. (So Map.Find(key) couldn't return an Option<V> for example - this makes composition more difficult).

So although the language has been steadily going in the right direction, there has been less of a concerted effort on the library front. And therefore C# is still behind IMHO.

This is something I've been trying to rectify, by essentially building a functional BCL [1]. I welcome the increased pace of functional features recently. Although sometimes it's frustrating seeing the direction they're going and wishing they'd get there much quicker (expressions everywhere, sum-types, record-types, better type inference).

It's interesting that often C# is held up for its inability to do type-classes or ad-hoc polymorphism. But it is in fact possible with C# today [2] [3], and with zero cost (i.e. no reflection, additional memory allocations, or side-stepping of the type-system). It just causes a massive head-ache of manually provided generic arguments... [4] [5] I'd love it if the Roslyn team took some time to deal with the generic parameters inference story. It would help bring ad-hoc polymorphic types to C#, but it would just be awesome in general.

[1] https://github.com/louthy/language-ext

[2] https://github.com/louthy/language-ext/blob/type-classes/Lan...

[3] https://github.com/louthy/language-ext/blob/type-classes/Lan...

[4] https://github.com/louthy/language-ext/blob/type-classes/Lan...

[5] https://github.com/louthy/language-ext/blob/type-classes/Lan...

That is really cool. I'm definitely going to try it out.
Arguably, that doesn't count as type classes because it REQUIRES call-site awareness of the implementation. This makes it fully ad-hoc and fully impractical as a useful abstraction.

At that point you might as well call a static method without polymorphic parameter types, because it's just as (in)convenient and 100% more readable to the developer maintaining the project after you move on to a better programming language.

> Arguably, that doesn't count as type classes because it REQUIRES call-site awareness of the implementation

Yes. I should have stated it's not real type-classes, but it is real ad-hoc polymorphism, which does get you much of the way there. The type-system won't infer the instance, you need to specify it manually. That doesn't make the solution less powerful from a generic programming point-of-view (if anything it makes it more powerful, because you can provide the instance you want to use); however it does make it more awkward to use.

> and fully impractical as a useful abstraction.

I disagree with this though. Finally being able to define a numeric type, or make types into real monads where a function can declare a constraint that requires an argument to be a monad is a good thing.

> At that point you might as well call a static method without polymorphic parameter types

From what I can tell, you're thinking of just the call site, but a whole call stack can carry through the constraint, and therefore the call site doesn't need the concrete implementation, it just needs a type that is constrained to the 'type class' (interface). The call site wouldn't know the type of the static method to call in your case.

For example with a numeric type:

    public static T Add<T>(T lhs, T rhs) =>
        //  what static method can you call here?
If you don't use polymorphic types, then you're not writing generic code, which is what this is for:

    public static class Math
    {
        public int Add(int lhs, int rhs) => lhs + rhs;
        public double Add(double lhs, double rhs) => lhs + rhs;
        public float Add(float lhs, float rhs) => lhs + rhs;
        public decimal Add(decimal lhs, decimal rhs) => lhs + rhs;
    }
What about when you forget: BigInteger, short, byte, long, etc.

But with the method I explained above:

    public interface Num<A>
    {
        A Add(A lhs, A rhs);
    }

    public struct NumInt : Num<int>
    {
        public int Add(int lhs, int rhs) => lhs + rhs;
    }

    public struct NumBigInt : Num<BigInteger>
    {
        public BigInteger Add(BigInteger lhs, BigInteger rhs) => lhs + rhs;
    }

    etc.
Any code that works with numeric values can then be written once. I'm sure many C# programmers over the years have cursed over having to write N variants of something that should work with IArithmetic, or INumber, or something similar. This gets around that problem (and without causing any boxing either). So, personally, I think it has value. Even if it's only needed rarely.

> because it's just as (in)convenient and 100% more readable to the developer maintaining the project after you move on to a better programming language.

My library isn't about the mindset of programmers who are stuck in OO-land with all the conservative nonsense that goes along with it. So although I agree there's a learning curve, I don't think this is too problematic for those who want to write truly generic code.

By the way, Microsoft are experimenting with this technique[1] (and new grammar) for future versions of C#. Whether it makes it or not, who knows, but I think it would be a super valuable feature for C#.

[1] https://github.com/CaptainHayashi/roslyn/blob/master/concept...

A big problem wrt speed of evolution of NET historically has been the legacy design of the BCL, and the fact that it's updated as one monolithic thing when a new .NET version is released.

The new model used by .NET Core is to make everything a NuGet package; and not a single big one, but small packages comprising one particular bit of functionality, each of which can then be versioned separately. For example, collections are a NuGet package:

https://www.nuget.org/packages/System.Collections/

With this model, it's possible to iterate on the API much faster, so my expectation would be to see functional APIs in the standard library spread much faster from now on.

Interestingly they thus have effectively an equivalent of Java's long-awaited and long-postponed Project Jigsaw. It seems to not have been such a roadblock for MS, maybe also because of a somewhat shorter history of the platform (no idea how comparable the code inside is regarding spaghetti-ness and interdependencies).
I think it's more due to Sun dropping the ball and Oracle not putting the same amount of resources behind Java as Microsoft puts behind .NET.
I agree that the BCL is better off as separate packages (even if it's caused many headaches getting my NETCore build right); but my main point was that the BCL is pretty much 100% stuck in OO-land. Aside from a few types and interfaces (DateTime, string, IEnumerable, IObservable, ...), there's no coherent functional base for C#: no Option type, by default the collections are all mutable (the immutable versions have terribly awkward names like ImmutableDictionary, etc.), lots of void returning methods, etc.

I could go on, but there's not a huge point to moaning about it, which is why I decided to do something about it. I'm not sure if it's even possible for there to be an official functional BCL without it being a totally new set of packages. It's something that F# would benefit from too.

MS's Scala equivalent would be F# which was out in 2005.

This is just adding more functional programming aspects to their dominant language.

Pedantic comment incoming; F# is more of an ML implementation.
Pedant; you're missing the compare for the contrast.
Scala is more OO than F# or even C#, in that it has very advanced OO features that are not seen in other OO languages. OO in F# is more about interop.
What sort of advanced OO features are you referring to?
Traits as full fledged mixins (including state!) are my favorite feature. No other language has this with static typing.
(comment deleted)
all modern languages are basically becoming functional languages, slowly. C# is essentially riding the mainstream wave, trickling down features as the average developer gets familiar with the existing ones.
I think you've got it backwards. C# was one of the principle drivers of this wave.
Plus it was the first truly mainstream language to have async/await.
To be fair, I think VB.NET got async and await at the same time C# did. Lambdas, too.
async/await are ways to take functional constructs and make them imperative. So not really relevant in this case (and are actually the reverse)
No, not backward, maybe my wording was simply ambiguous.

When I say "riding the wave", what I mean is that they are adding functional features as the regular OOP/imperative programmers in the mainstream are done "accepting" the previous ones they added, as opposed to adding everything in one shot and have people get overwhelmed.

I didn't mean they were following a wave or anything. Analogies are hard.

C# progress is strongly driven by Microsoft Research. Microsoft Research contains a lot of functional programming fans. I'm quite happy to watch MSR slowly convert the hoard of C# programmers from Java++ devs to Haskell|OCaml devs.
This is actually not the case -- none of the members of the language design team are MSR employees.
But they have the F# and Haskell teams, who are nearby, to talk to. In particular, F# seems to have had a great influence lately.
It's much easier to change the compiler now that it's implemented in C#. The C++ implementation was much harder to add features to.
I don't think it was so much a problem of the implementation language, but rather that every feature needed to be present in both the compiler and VS (for syntax highlighting and IntelliSense) and those have been completely different implementations (I think highlighting and IntelliSense even were different parts). So you had to touch two or three completely different codebases whereas now you only have one.
The C# LDM takes inspiration from good ideas from everywhere, including Scala.
The C# team are very lucky to have F# as a reference implementation on how to implement ML style features on the .NET platform. I'm certain many more features from F#/OCaml will be added in forthcoming releases.
It was clear that ms won't stop adding features aftwr version 3 or 4.i guess c# will be the: does all, can do all and includes all patterns, functions, methods from all other languages you can think of.

There seems to be no control, no feature lock, no "our language will be like language x" or definition they follow. It seems more like they listen to the whole community of developers.

All of them.

Which is funny, because I still remember their "every new feature request starts with -100 points and has to prove real benefits before even being considered for the language" speech
If you follow the language design process (which now is public on Github), they still very carefully consider new features for the language and don't just throw everything in there that people request.
Every language falls victim to the functional paradigm over time, because functional language community is very vocal and promises riches if you use their paradigms. But when you do implement them, they turn out to be hard to use or not viable for big applications and people stick to their old languages anyway.
The .NET CLR has advantages over the JVM, especially when comparing C# / F# -> Scala / Java. At a language level, the use of type erasure for generics (which is done at compile-time in Scala/Java) allows you to do things that the .NET CLR wouldn't allow you to do because Generics is part of IL. C# isn't becoming Scala but functional paradigms are coming through into languages as an evolution, rather than stagnating (this is great, in my opinion). These languages are a part of the .NET eco-system and are fantastic, I'm pleased with the path they're going down, albeit maybe they could improve certain syntax in C# 7.0 ;)
'goto case' is a thing? I'm so going to have fun with that
It has always been a thing. The original C# design was to take the C switch statement as is, but tighten it up to avoid crazy stuff like Duff's device, and to make non-obvious implicit things explicit.

Consequently, C# requires that control flow provably cannot reach the end of any non-empty case block (to avoid implicit fallthrough that normally happens in C, Java etc). Normally this means that you must use `break` (or something else that transfers control, like `continue`, `throw` or `return`). But fallthrough is actually useful sometimes, and `goto case` provides you with a way to request it explicitly - and then ramps it power up a notch, because why not?

Amusingly, this is something that C doesn't have, even though its case labels are true labels (allowing for Duff's device and similar tricks). If you want to goto them, you need to add an explicit named label there.

I was a die-hard python guy and now I'm a die-hard python guy who appreciates .Net. (Forced to because I work in a .Net shop, but it has chops)
Possible to use variable placeholders on the left side of a deconstructor assignment?
There's a plan to allow wildcards in deconstruction patterns, but it doesn't look like it's ready in time for C# 7. So hopefully that will appear in C# 8.

It would look something like:

var (first, second, *) = ReturnsFourThings(foo);

more improvements that allows more concise code and that looks functional in nature. Which is great, I have to do a lot in C# and really like it as a OO / with functional abilities type language.

But I keep wondering why F# doesn't really take off given a lot of peoples fascination with the functional world. It does functional nicely while still being able to bridge back to the OO world which allows you to easily leverage a LARGE amount of libraries in the .net world. It has a really good community, and F# specific frameworks for various things as well. It's like a hidden gem that people pass over as they look at functional languages with much much smaller ecosystems.

I only played with F#, but my day job is writing FP code in Scala, so let me answer this:

> I keep wondering why F# doesn't really take off given a lot of peoples fascination with the functional world

As a matter of fact there aren't that many people interested in FP, mostly due to a lack of education on the matter. Even many people talking about FP are confused about what FP is. And the problem with the FP ecosystem are the abstractions, which tend to be extremely high level and very productive, however these aren't taught in school and the cost of entry is high.

So let me throw this question right back at you: why F# and not Haskell? And note that the answer you give is going to be applicable to C# versus F# and at the same time flawed ;-)

And you see, raising the abstraction is one way humanity has always tackled complexity, however this is essentially about vertical scalability of talent - or in other words enabling the same people to handle more challenging problems by giving them better tools. But the trouble is that this is incompatible with horizontal scalability, which is about growing by hiring more and more people, i.e. building assembly lines.

So going back to your question, the reason for why not FP is actually simple, but hard to swallow: the software industry is growing due to huge demand, as a consequence a majority of people working in this field are beginners and when the industry has a choice between quality and quantity, it will go for quantity at the expense of quality.

On the other hand the good news is that with the proper education, mindset and tools, as a small team, you can still build products that compete with big companies having virtually unlimited resources.

why F# and not Haskell? Now we are leaving the .NET world. We are leaving a lot of libraries behind that bridge to many many things. For instance, my latest F# project was to make a REST service that bridged to a Digital I/O board, the DIO board manufacturer has .net libraries for their devices, I simply wrapped those, used Suave.io, 50 lines of code later I have a webservice for control of DIOs. The point about why F# is really good is the huge amount of libraries you get for free that very few other functional languages enjoy ( JVM based languages would enjoy this advantage too ), you can make bridges to other languages / environments, but that's not quite as straightforward. So to me, it's not the same argument.... F# -> Haskell (lose the libs) C# -> F# (don't lose the libs). Not only that, you can sprinkle it into your projects before fully committing to it.
Most of Microsoft technologies customers are orthodox enterprise companies. They're still using VB and SourceSafe and will not be attracted by ML-like language. So Microsoft is marketing F# cautiously.

But unlike Java world where J2EE suits and Scala/Clojure hipsters coexist (but hugely separated), .NET is in just beginning of transition from Windows-only Visual Studio-only. It's hard to convince people outside of old Windows Server .NET camp to even try these technologies. Recently I tried F#: build process is still painful, involving msbuild files designed for IDE first, build system second, based on XML, with reverse slashes and absolute paths, reminded me of mix between Windows Registry and Apache Ant. MSDN is painful and enterprisey, with 5-10 second page load times.

F# is quite nice (much cleaner and simplier than Scala for example) but still not feels really great. I can't figure out how to do basic polymorphism in it: someone recommended to use classes and interfaces but I don't want OOP at all. Standard library has few polymorphism too: Seq.map, List.map, Set.map. Records are great but type inference behaves strangely.

I'm interested to see what the production story is for some of these language features. I usually get left a festering minidump with a number of threads, a pile of stacks and some line numbers if I'm lucky these days. It's quite hard determining which dereference or call is the one that triggered the problem in a method body with so many things now compacted into a tight expression.

Granted there should be assertions to prevent these conditions occurring but not everyone on the team is perfect 100% of the time. Sometimes an edge case slides in as well and you have to heavily assert everything and push to test/production to reproduce which isn't ideal.

I'm very disappointed that ref returns were not implemented as syntactic sugar for out params.

A bit of history: game developers have been crying for a solution to the matrix operator problem. A 4x4 matrix is 64 bytes of data. Implement the mathematical operators using C# operators and you're looking at 192 bytes copied per invocation. The workaround is the fake ref operator: void Add(ref Matrix, ref Matrix, out Matrix). The problem is that this results in code smell at the call sites. The ref return was the first compromise, allowing that method to become: ref Matrix Add(...). The ultimate solution would be to allow ref returns and ref parameters on operators, but you need ref returns first.

This feature misses all of that. Maybe we'll get out returns, but the argument against it would be language bloat, and even I'd agree. Sigh.

/rant

(comment deleted)
The Add method signature could be simplified from void Add(ref Matrix, ref Matrix, out Matrix) to Matrix Add(ref Matrix, ref Matrix).

Also, could you elaborate what you mean by out returns? Normal returns could be considered "out returns", no?

If Matrix is a value type, then no, that's not the same thing, because with "out Matrix" it is passing it by reference, instead of by value.
Isn't it in this case just an implementation detail without any meaningful consequences (apart from interop)? - I'm trying to find a way to benefit from it. I wrote some code to compare the two approaches and see what's going on underneath.[0] I'm not familiar with IL, but it seems like the memory usage is the same and the simple return function requires less ops.

[0] http://tryroslyn.azurewebsites.net/#f:>ilr/A4VwRgNglgxgBDCBD...

This is no implementation detail and has nothing to do with overall memory use. It has to do with how much memory is copied (an operation that consumes time) per invocation. IL is the wrong level to look at this.

In the by-value case: a stack frame of 192 bytes is allocated (+ space for other locals). The values of the matrices are copied into it from the parent stack frame (128 bytes). The method does its work and then calls "new Matrix". This occupies the final 64 bytes. Immediately this value is copied out of the method to the parent stack frame.

In the by-ref case: a stack frame of 0 bytes is copied (+ space for other locals). The pointers to the two matrices are passed in, as well as a pointer to the memory for the result. The method does its work and then calls "new Matrix". The result of the .ctor is stored directly in the calling stack frame.

You might consider that this is nit-picking, but consider that this has to happen 60 times per second. Calculating an MVP matrix for 1000 objects 60 times per second, results in 32MB of memory copied around per second. That assumes you are doing no additional math (which is definitely not the case). The performance benefit is substantial enough that even XNA had these overloads (which is where I think the workaround originated)[1].

[1]: https://msdn.microsoft.com/en-us/library/bb194950.aspx

A return means copying that value on the stack and depending on its size, it can be expensive. In this case we're talking about a matrix, so that's not just one 32 or 64 bytes pointer.
It sounds like what you want there is RVMO?
Pattern Matching with Is Expressions

Awesome! Greatly reduces "ugly" boilerplate code like this:

    if (control is TextBox)
    {
        var textBox = (TextBox)control;
        textBox...
    }
Also, it would be great if Microsoft could make full properties in another way so that you do not have to write a backing field for it. Something like this:

    public string LastName
    {
        get;
        set 
        {
            if (value == "Batina")
                RaisePropertyChanged();
        }
    }
It would make code more cleaner.
For your second example: just use Fody.PropertyChanged and forget about writing boilerplate.
I know about Fody but I don't think it would help with custom logic inside setter (not just PropertyChanged call).
I think if you're writing property accessors manually then there should be an explicit private backing field. Otherwise there is just too much magic going on.

Normal auto-implemented properties are fine:

  public string LastName {get; set;}
As are read-only ones:

  public string LastName {get; private set;}
Yet, I feel that if you are writing logic in there then you should fully control it. Or else there is too much being done that is non-obvious and could cause problems down the line (for others or your future self).

However, they might be able to achieve something with data annotations that wouldn't be too magic. For example:

  [RaisePropertyChanged("Batina")]
  public string LastName {get; set;}
Tip: In VS you can just type "prop" then press tab to auto-generate the code for a class property. You can then easily auto-change this to a fully implemented version. This also works for "for" and "foreach" loops etc.

I haven't done much Java in a while but do you still have to write out all of your property accessors fully? Might not be too bad if the IDE can generate this code.

I don't think its possible with data annotations because there will me more complex logic in setter then I described.

I would just like to see get working like in auto-implemented property (without backing field) but setter to be manually implemented (with value keyword).

Also you can use propfull snippet for full property implementation.

It puts a smile on my beak that I am a budding (sort of) .Net and C# developer. Microsoft seems to be really jacked up and introducing some very forward thinking functionality into their ecosystem. Been playing with Azure Service Fabric. It is super impressive.
Yeah, Service Fabric is super awesome! I'm refactoring out company's infrastructure to run on it currently - the older stuff runs on MVC 5 on Azure Cloud Service.

I'm refactoring it to ASP.NET Core on Service Fabric. Getting about 50x better real-world performance. Yes, that much. It's insane. Currently on Windows as Service Fabric on Linux is in preview (not comfortable using it in production), but I imagine I'll move it over once that's stable ️

A great time to be a .NET developer! Makes me happy I stuck with it.

major part of these new features are very cool but i'm afraid they could compromise future evolution of the Language. some implementation details scares me, maybe i'll become used to them, i only hope that these doesn't result in a boomerang for future versions.

Deconstruction implementation is scary, i would prefer to have a special symbol (like the desctrutor) and duples that ignores names are ok but sounds very error prone, maybe i just have to try them to understand, also order sensitive case makes my dev sense tingle...

removal of pre-declaration of out parameters = win!
Just a note: This article published yesterday refers to VS 15 Preview 5 as unreleased but VS 2017 RC (the next Preview on) was also released yesterday.