Live data from Hacker News

What’s New in C# 7.0

blogs.msdn.microsoft.com

211–220 of 278 posts

Re: What’s New in C# 7.0

#211
post #94

Earlier quoted context omitted.

> C#, is every bit a form of pattern matching as matching on a particular case of a union type. I'm afraid that is not the case, because in the current C# version, the compiler does nothing help you determine if you've matched all the possibilities. (it is not exhaustive) Exhaustiveness is important because it gives warning or an error to help you refactor and modify code without fear of breaking other code. Why enga…

Yes, and because of the lack of record and union types in C#, it's (probably) nigh-impossible to pull off exhaustive pattern matching. However, this is still pattern matching - you can define tuple patterns which decompose the data, much like you can in F#; just with some different syntax. I agree with you that exhaustiveness is incredibly important, and I really hope that it can be done in C# some day. However, reco…

You can achieve something similar via a library: https://github.com/mcintyre321/OneOf

I also think language level support for this would be a killer feature, it turns OOP and the requirement to use polymorphism to guarantee strategy-per-type on it's head.

Re: What’s New in C# 7.0

#212

I still lack some kind of sum type that is always checked for exhaustiveness. When I'm creating a class hierarchy for a domain, 9 times out of 10 I'd rather have a simple sum type. When I have to make a class hierarchy in C# anyway (because there are no simple sum types). I'd like to be able to write something like this, and have this match/switch fail to compile if I add a new type of shape. match(shape) { case Rect…

I'm just going to pimp my library (github.com/mcintyre321/OneOf) which lets you pull this off in c#. I'm quite sad it's needed though, it would be great to have it in the language.

Re: What’s New in C# 7.0

#213
post #106

Earlier quoted context omitted.

Can you give an example of how C# would be different with anonymous classes? Googling that term just gives a whole lot of references to inner classes in Java.

One I've come across is binding a command to a button. With anonymous inner classes you can have something like: myButton.AddListener(new Command { bool enabled() { return false; //more logic goes here } void onClick() { //do something } });

much much better to use DelegateCommand:

    SubmitCommand = new DelegateCommand(()=> DoSomething(), ()=> IsSubmitEnabled);
Edit: and obviously the Command DependencyProperty on the Button will be bound to the SubmitCommand property, instead of accessing directly the button from the ViewModel, that is the worst possible thing that you can possibly do.

Re: What’s New in C# 7.0

#214
post #82

Earlier quoted context omitted.

Hey there, C# language designer here. > Out variables seem like a mis-feature, especially when they are adding a better alternative (Tuples) in the same release. Out variables are really great when working with existing code that predates Tuples (for example, the entire BCL). We don't just introduce language features that will only work well for new code. We also want to make the experience of coding against existing…

Did you guys look into alternative syntax for return types? It really is a huge eyesore, and impediment to reading, when you have more than just a typename and a couple of modifiers like * and [] attached to it. With tuples especially, it's even worse, because the method name gets squished between two very similarly looking ()s, which is very different from how methods have historically looked in code. If I were scan…

What would you suggest?

public TResult SomeMethod() where TResult : (string name, int id)

Re: What’s New in C# 7.0

#215
post #205
post #118

Earlier quoted context omitted.

VB.net development is not that different from VB6. It is a way more sophisticated language and therefore can do more complex things. But the basic things take pretty much the same syntax than they were in VB6.

It is and it isn't. VB.Net is basically everything from C# with an syntax heavily inspired by VB6. But the similarity ends there. The RAD IDE of VB6 or Delphi are unmatched, and the compatibility is gone. As WinForms is legacy as well, the whole experience is different anyway. People would like to run their Win32 apps on their smartphone, nowadays you have more luck with Android than what Redmond comes up.

> People would like to run their Win32 apps on their smartphone

And they did actually. Windows Mobile - the original Windows Mobile, 2000-2012 - had 42% smartphone market share in 2007, a native Win32 API (and .Net Compact Framework for C# and VB.Net too), had WinCE kernel and worked on x86, MIPS, ARM and SuperH CPUs.

Re: What’s New in C# 7.0

#216
post #2

Out variables seem like a mis-feature, especially when they are adding a better alternative (Tuples) in the same release. It's great to finally have tuples, but the c/java style syntax is showing it's age compared to something like scala which has return type declarations at the end, which I find much more readable. Literal improvements will be a godsend for writing database migrations. Ref returns and locals look li…

>c/java style syntax is showing it's age compared to something like scala which has return type declarations at the end, which I find much more readable

I hope there are better examples of Scala's syntactical advantages than this one, because it seems like the 'egyptian-style' vs 'next line style' brace bracket debate...

Re: What’s New in C# 7.0

#217
post #2

Out variables seem like a mis-feature, especially when they are adding a better alternative (Tuples) in the same release. It's great to finally have tuples, but the c/java style syntax is showing it's age compared to something like scala which has return type declarations at the end, which I find much more readable. Literal improvements will be a godsend for writing database migrations. Ref returns and locals look li…

Hey there, C# language designer here. > Out variables seem like a mis-feature, especially when they are adding a better alternative (Tuples) in the same release. Out variables are really great when working with existing code that predates Tuples (for example, the entire BCL). We don't just introduce language features that will only work well for new code. We also want to make the experience of coding against existing…

> Out variables are really great when working with existing code that predates Tuples (for example, the entire BCL). We don't just introduce language features that will only work well for new code. We also want to make the experience of coding against existing APIs feel better.

I disagree on this point. If there is a language feature that has been superseded by a better alternative, continuing to add sugar to the old feature only serves to perpetuate its use.

It embiggens the language while providing relatively little value in return. Furthermore, it adds confusion as to what should be considered idiomatic.

Tuples and deconstruction are so clearly better than out variables, I would have thought it would make more sense to deprecate the "out" feature entirely. Or, at the very least, not make it easier to use them.

Awkward and outdated features should be painful to use.

I also felt that this was a very odd addition. Even odder, the article doesn't even list tuples and deconstruction first.

Re: What’s New in C# 7.0

#218
post #4
post #2

Out variables seem like a mis-feature, especially when they are adding a better alternative (Tuples) in the same release. It's great to finally have tuples, but the c/java style syntax is showing it's age compared to something like scala which has return type declarations at the end, which I find much more readable. Literal improvements will be a godsend for writing database migrations. Ref returns and locals look li…

>Out variables seem like a mis-feature, especially when they are adding a better alternative (Tuples) in the same release. You can't retro-fit multiple-returns (via Tuples) onto existing library functions, so for places where you're forced into using out parameters, this is a slight improvement.

Sure you can - you can introduce a new overload resolution rule that lets you treat trailing out params on a method as tuple members, so a method

    TReturn Foo(T1 param1, out T2 param2) 
can be called as if it were

    (TReturn, T2) Foo(T1 param1)
You'd need a keyword to trigger this kind of overload resolution at the call site to ensure back compatibility - maybe you'd have to call

   (var x, var y) = out Foo(param); 
or something. That way all that legacy library code gets a free upgrade to your new language feature.

Since the C# team decided not to do that, you can actually implement a version of this at a library level, by static importing a family of generic methods like this:

   Func Tuplify(Func outFunc) {...}
for every pattern of out params you want to convert, then you can just call

   (var x, var y) = Tuplify(Foo)(param);

Re: What’s New in C# 7.0

#219

Earlier quoted context omitted.

C# has (had? I'm still a couple of versions behind) so much syntactical overhead that writing code without a visual studio seems painful at the very least. The var keyword was the first time it was even possible to write C# without tooling. It has definitely made it possible for me to use Vim for editing C# code. Newer features, such as lambda expressions, and some of the much nicer property syntax makes me feel that…

Compared to what languages ? I always thought of C# as the improved, less verbous Java. I wouldn't compare it with Python or other dynamic languages, but I prefer it to most compiled languages (especially at the times it was created)

When I read their comment I thought of how much annotation of static types you have to do that compilers in other languages are smart enough to figure out on their own. Consider the following snippet in C#:

    public static IList FindEphraimitesToKill(IList ephraimites)
    {
        IList ephraimitesToKill = new List();

        foreach (Ephraimite ephraimite in ephraimites) 
        {
            if (ephraimite.Speak("shibboleth") == "sibboleth")
            {
                ephraimitesToKill.Add(ephraimite);
            }
        }

        return ephraimitesToKill;
    }
Now, the same in (imperative-style) OCaml:

    let findEphraimitesToKill ephraimites =
      let ephraimitesToKill = ref [] in
      List.iter (fun (ephraimite) -> begin
        if speak(ephraimite, "shibboleth") = "sibboleth" then
          ephraimitesToKill := !ephraimitesToKill @ [ephraimite] 
      end) ephraimites ;
      ephraimitesToKill;;
See how much less we had to specify the type of what we're handling here? And things would have gotten easier if we used functional-style OCaml, but that's not entirely a fair comparison.

So hypothetically it should be possible to write a C# compiler that would, if type annotations were omitted in some places, be confident enough to assign a sensible default, which is why we call the current version verbose. Although I suppose it's slightly more complicated than that. (Interfaces, if we want to have them, need to be explicitly declared as there are potentially many interfaces that could be used for a given object, and the rigidity imposed by redundant type declarations could help with the health of large and long-lived codebases.)

Re: What’s New in C# 7.0

#220
post #121

Having done a lot of python recently, this looks great (and familiar). But some things feel a little bit rushed: - In the example "(o is int i || (o is string s && int.TryParse(s, out i))": When reading this statement as a human, o is obviously not an int when it comes down to the TryParse function. But if the 1st part was removed, the 2nd part wouldn't be valid either. I know this is technically how declarations wor…

I was thrown by the first one you pointed out too, I'm still not sure I understand it. The page said for type patterns it will "test that the input has type T, and if so, extracts the value of the input into a fresh variable x of type T", so if o is an int it'll be extracted to a fresh int i with that value But the out syntax in TryParse isn't the new one they mentioned, it's the current one that requires predeclared…

The expression

    o is int i
is effectively:

    int i; // in the nearest enclosing scope
    (o is int && (i = (int)o)) // in place of an expression
The "fresh" variable `i` is available for use elsewhere. If an `i` already exists in that scope (the block the `if` statement is in), that is a redeclaration of a variable which is a compile-time error.

If the "is" expression evaluates to `false`, the variable `i` will not be assigned, however, it will still be declared. Attempting to use `i` if it is not definitely assigned is a compile-time error. However, you have the opportunity to re-assign it.

Some examples:

    {
      if (!o is int i) throw Exception();
      use(i); // works: i is declared and always assigned
    }

    {
      if (o is int i) { do_something(i); }
      use(i); // compile-error: i declared but might not be assigned
    }

    {
      if (o is int i) { do_something(i); }
      else { i = 0; }
      use(i); // works -- definitely assigned
    }
Thus the example pointed out in the post boils down to this in C# 6:

    int i;
    if (o is int) { 
      i = (int)o;
    } else {
      string s = o as string;
      if (s != null && !int.TryParse(s, out i)) {
        throw Exception();
      }
    }
    // i is definitely assigned here.
Post reply on HN