
C# 8: Switch expressions - azhenley
https://alexatnet.com/cs8-switch-statement/
======
moogly
More and better examples here
[https://blogs.msdn.microsoft.com/dotnet/2019/01/24/do-
more-w...](https://blogs.msdn.microsoft.com/dotnet/2019/01/24/do-more-with-
patterns-in-c-8-0/)

------
jakear
To me, all these IIFE’s make a good case for adding a block-as-expression
construct. Either take from Scala, where every block evaluates to the last
expression executed in that block (and every statement is an expression); or
maybe introduce some new syntax (‘do { .... }’ maybe?) if the prior would be a
breaking change.

~~~
zmj
There's a bytecode representation already - you can use it when compiling to
IL: [https://docs.microsoft.com/en-
us/dotnet/api/system.linq.expr...](https://docs.microsoft.com/en-
us/dotnet/api/system.linq.expressions.blockexpression?view=netframework-4.7.2)

What's missing is a way to express an anonymous block expression in C#. I'm
not sure that's a gap worth filling, though - if the logic is worth a block,
isn't it worth a name?

~~~
twhb
“If” statements and loops already make use of anonymous blocks, and I think
serve as ample demonstration that, no, not all blocks are better off named.
What’s missing is the ability to use those blocks wherever an expression is
expected.

------
rattray
This might be better titled "C# 8: switch expressions" (edit: it was
previously "statement", as the author's post is titled).

Or actually, to bait a few more hn clicks (and provide a fuller description):
"Pattern matching in C# 8 with switch expressions"

~~~
jmnicolas
This might be better titled "changing things for the sake of changing things
and appealing to the programming language geeks".

The new syntax is not intuitive, not more readable, just a bit more terse.

~~~
chrismeller
This actually seems to be somewhat of a trend in C# as of late. Ever since
they introduced lambdas, really.

While I use them every day, my favorite is still “replacing” String.Format
with string literals. Shorter, sure, but less intuitive particularly for
people coming from another language. You can do roughly the same thing in PHP
with backticks, but most people avoid them for the same reasons.

I’m not sure how I feel about the trend as a whole. As long as I can continue
using the old methods as well I suppose I don’t have much room to complain,
but sometimes it does feel like we’re just changing for the sake of change and
that’s usually a bad indicator.

~~~
Someone1234
string interpolation isn't simply a wrapper around String.Format(); it also
offers compile time checking which solved a real limitation of String.Format()
while offering better performance than concatenation.

For example:

    
    
         var h = "Hello ";  
         var w = "world";     
         var output = String.Format("{1} {2}", h, w);    
         output = $"{h} {w}";   
    

Would compile fine but throw on the String.Format() line due to the typo.

~~~
chrismeller
I wasn’t necessarily saying it doesn’t offer any benefit, more that it’s not
really a benefit that seems to benefit a lot of people. Between code
intelligence tools and actually running the code you write (not even in an
actual QA process, but simply executing each line) that just doesn’t seem like
a big deal to me.

There are also instances where, such as with Console.Write you are now
formatting a string in order to pass it into... a method that formats strings.
Yes, the same benefit is still provided, but with a fairly obvious decrease in
clarity and increase in redundancy.

~~~
Someone1234
> fairly obvious decrease in clarity

You feel that "{0} {1} {2}" provides better clarity than $"{FirstName}
{MiddleInitial} {LastName}"?

------
azhenley

        "+" => ((Func<int>)(() => {
            Log("addition");
            return a + b;
        }))(),
    

This is incredibly ugly. Why couldn’t it be “+” => {stuff}

~~~
LandR
That is ugly.

What he's doing is creating an anonymous function which takes no parameters
and returns an int. That's what a Func<int> is, and then he is executing that
function, that's the () bit after }))

He could write it nicer as:

    
    
       "+" => Add(),
     

Where he defines add as

    
    
       int Add() => a + b;
    

He's just doing too much inline, 99% of C# developers would not write code as
he has done there.

Its' the bloggers code style that is the problem here, not the new switch
syntax. Although he probably did it to make the example more self contained
and terse.

~~~
rattray
I agree with your conclusion, but let's keep the conversation civil.

~~~
kayamon
The conversation is quite civil already.

~~~
rattray
Ah, too late to edit/delete my comment. They edited their post, perhaps in
response, which is now much more considerate.

------
danielovichdk
I am not sure I like the path c# is going down.

For years the language has been trying to evolve from being aesthetic and easy
to understand and read.

With the functional implementations and patterns I believe the language is
trying to embrace too much.

This is not specific to the swith expression in this context but in general.

You can write C# in too many forms and I don't believe that's really good.

~~~
dgritsko
> You can write C# in too many forms and I don't believe that's really good.

Why not? And what, exactly, defines "too many"?

~~~
kminehart
I know people meme a lot about Go and "not having generics," but I really feel
that a lot of the things left out of Go have benefitted it. I've never really
been able to jump into a project without a lot of mental overhead. With Go,
most code everywhere is written pretty idiomatically, making it easy to
approach and read. I've heard similar things about C#, but my experience
hasn't been as great.

This is a big problem in the JavaScript world in my opinion. So many different
ways to solve common problems that it's difficult to approach. OP might be
worried this could be happening to C#.

~~~
BoiledCabbage
We could go with a language with just if statements, while statements,
function calls and "return" and be extremely easy to jump into. :)

While a bit snarky I do think it is one of the fundamental problems with
programming language innovation. No matter how smart we are, learning is
effortful. And we frequently judge languages not by how productive it is, but
by how quickly we can start feeling productive in it. Which often preferences
familiar concepts over more powerful concepts.

There is a _very_ long feedback loop in properly evaluating a language. At
least 1-2 years. You need not just figure out how to do what you already know
in the language, you need to learn the new way to think in the language. And
that takes time and solving lots of problems. This is only sped up if the
language's concepts are kept very similar to a language you already know.

We are the bottleneck that slows down language improvement. There is no way
anyone can convince me that the hodgepodge of Algol derived languages is one
of the best ways out there of writing code. But most new languages will be
similar because the hurdles of trying to teach people anything else alongside
the actual new interesting concepts of your language are too much of a blocker
for any reasonable adoption.

------
pron
Java is also getting switch expressions next month (as a preview feature in
JDK 12):
[https://openjdk.java.net/jeps/325](https://openjdk.java.net/jeps/325)

~~~
chvid
It is exactly the same isn't it?

~~~
dmitriid
It's not. C#'s switch can pattern match on value _and_ type:
[https://blogs.msdn.microsoft.com/dotnet/2019/01/24/do-
more-w...](https://blogs.msdn.microsoft.com/dotnet/2019/01/24/do-more-with-
patterns-in-c-8-0/)

Java's switch still operates only on String, int, short, byte, char, and their
wrapper types: [https://blog.codefx.org/java/switch-
expressions/](https://blog.codefx.org/java/switch-expressions/)

------
platz

        // now you kind of enforced to
        // handle all values, otherwise
        // it will not compile
    

I fail to see how it will not compile if all values are not handled. C# switch
is not traditional pattern matching, because you don't get compile time
feedback.

Claiming that is does is disingenuous.

~~~
dgritsko
This page[1] (which was linked elsewhere in the thread) provides the following
info:

> Since an expression needs to either have a value or throw an exception, a
> switch expression that reaches the end without a match will throw an
> exception. The compiler does a great job of warning you when this may be the
> case, but will not force you to end all switch expressions with a catch-all:
> you may know better!

I haven't used the feature yet myself, so I can't say it definitively - but it
sounds like it does provide compile time feedback while still allowing you to
compile.

[1]: [https://blogs.msdn.microsoft.com/dotnet/2019/01/24/do-
more-w...](https://blogs.msdn.microsoft.com/dotnet/2019/01/24/do-more-with-
patterns-in-c-8-0/)

~~~
Mindless2112
Specifically, it will throw SwitchExpressionException[1]

[1]
[https://github.com/dotnet/corefx/issues/33284#issuecomment-4...](https://github.com/dotnet/corefx/issues/33284#issuecomment-448332714)

------
mal10c
In my opinion, I find the Tuple patterns the most interesting way to use
Switch Expressions. But (and maybe I'm stuck in my ways), I'm kind of on the
fence in terms of using this. On the one hand, it shortens some code, but on
the other, it's more difficult to read than an if statement (in the case of
tuples). I guess I'm not completely sold on this yet. I know the big argument
in the article was that this is a way to ensure your variable has a value when
you go to use it. When I hear things like that, my first reaction is "then
write better code if you're running into that problem."

------
ken
This is perhaps the most obvious example yet of what PG described as "taking
features from Lisp and gluing them to C". That's not necessarily a bad thing
-- this is a great and useful feature, and one I frequently miss when using
C-family languages.

I wonder, though, at what point a programming language collapses on itself,
from too much syntax. I haven't used C# since the 4.x days, and I recall back
then it was already on the verge of being too complex for me to fully
understand. Admittedly my personal threshold of complexity is lower than most
programmers', but this is a really big language. Do they plan to keep adding
syntax indefinitely?

At some point, it's going to have to get eclipsed by something else. The next
generation will be as effective a tool, for the kinds of things most people
want to make, and not too complex for most people to understand. Perhaps part
of that would consist of just using expressions for everything from the start.

~~~
ramenmeal
This is my feeling as well. I suggested that a c# lite or a rethinking of c#
would be awesome. I got downvoted to oblivion though. But I do think that
there's too much mental capacity used just reading c# if the code really uses
all the features of it. I like go lang cause of this, but go is a bit too far
on the other side of the spectrum for me.

~~~
zamalek
> I like go lang cause of this

I'm a huge fan of C#, but the lack of features makes Go so damned pleasant to
read. As an extreme example, the new C# record type really breaks the neurons
I have dedicated to the language:

    
    
        public struct Pair(object First, object Second);
    

As soon as I see parenthesis, it's a method. I want record types, but that
syntax is foreign. I wish Anders would spend a few months back on the C# team,
he has a great knack for keeping things as consistent and minimal as possible.

~~~
apta

        public struct Pair(object First, object Second);
    
    

Scala, Kotlin, Rust among others use the same or similar syntax.

------
kentosi
Though I'm sad that a lot of developers dislike scala, I'm certainly glad to
see some of it's* good parts being incorporated into current and new
languages: Pattern matching to various degrees in Kotlin, now C#, and soon
Java 12.

* I acknowledge my ignorance in thinking that scala was the first one to the table with this.

~~~
pjmlp
If you are curious about where it came from look into Caml Light, ML and
Miranda.

------
jermaustin1
I'm not sure what this accomplishes over a normal ugly switch.

~~~
doodpants
The new switch expression is to the old switch statement what the ?: operator
is to the if/else statement.

Sometimes you want to provide one of two different values based on a
condition. If you use if/else, then each statement body has to contain either
an assignment (if the value is to be used later in the same function), or a
return (if the value is to be immediately returned from the enclosing
function). It is often more clear and concise to use a ?: expression at the
site where the value is to be used.

Now consider the case where you need to choose among three or more different
values. You can use chained if/else statements, which have the same drawback
of needing to contain either assignments or returns. Or you can use chained ?:
expressions, but there's really no good way to format this in a way that
remains clean and easy to understand.

The new switch expression provides a cleaner alternative to chained ?:
expressions.

------
gambiting
"The new switch expression is quite simple. Anyone familiar with the switch
statement can say what the following code is doing"

Uhmmmm....I'm a professional C++ programmer who uses switch statements quite a
lot and no, I couldn't instinctively tell what it was doing straight away. Am
I being dumb?

~~~
kiliancs
This is clearly referring to C# switch statements. Not that they are very
different from switch statements in most languages anyway.

------
xiphias2
This makes sense together with algebraic data types, but I'm not sure if
that's implemented.

~~~
eckza
They’re saving ADTs for 9.0, at which point they’ll beat their chests and
loudly proclaim them to be the Best Thing Ever of All Time.

~~~
xiphias2
It's OK, it's good direction, so I won't complain.

~~~
eckza
I wouldn’t hate it. Especially since my day job has me doing a bunch of C#,
anyway.

