
A Preview of C# 8 [video] - plurby
https://channel9.msdn.com/Blogs/Seth-Juarez/A-Preview-of-C-8-with-Mads-Torgersen
======
Sir_Cmpwn
Found a text reference:
[https://www.infoq.com/news/2017/08/CSharp-8](https://www.infoq.com/news/2017/08/CSharp-8)

~~~
suzuki
Glad to see this Dart feature appearing in C#:

    
    
      Asynchronous Streams
    

Now you can "yield" Task<T> (~ Future<T> in Dart) and construct LINQ chains in
an asynchronous fashion. I hope it streamlines reactive programming greatly.

[1] Dart - Asynchronous Programming: Streams
[https://www.dartlang.org/tutorials/language/streams](https://www.dartlang.org/tutorials/language/streams)

[2] .NET Futures: Asynchronous Streams
[https://www.infoq.com/news/2017/05/async-
streams](https://www.infoq.com/news/2017/05/async-streams)

------
ajennings
Very excited about the Nullable Reference Types.

Besides that, the feature I want most in C# is enum exhaustion checking. So I
can write:

    
    
      enum Color { red, green, blue };
      public static string SuperheroFromColor(Color c)
      {
        if (c == Color.red)
        {
          return "Superman";
        }
        else if (c == Color.green)
        {
          return "Green Lantern";
        }
        else if (c == Color.blue)
        {
          return "Spiderman";
        }
      }
    

and not get a compiler error (that not all code paths return a value). But if
I added "yellow" as an enum option, then I would get a compiler error. I
realize that Color can be cast from an out-of-range int, so it's a little
complicated. I'm willing to put something extra after the last else:

    
    
      unreachable return null;
    

or use a special switch statement. I just want something so the compiler
checks that I have accounted for all normal enum values.

Is anyone talking about such a feature, or where would I request it? Can I
write it myself as a Roslyn extension?

~~~
UnoriginalGuy
You're asking for a language change to fix poorly written code. The final else
if() is redundant, if you change it to a simple else you remove the "not all
code paths return a value" issue and remove a redundant check. This requires
you to consider the "and others" possibility, rather than the compiler making
assumptions about the type's definition.

Plus what you're asking for is a maintenance nightmare; since changing the
type (Color) in one part of the code can break method definitions in another
part of the code (inc. other assemblies).

I'd hope they would never support what you're asking for.

~~~
chowells
He's asking for exhaustiveness checking of pattern matching algebraic data
types. Many languages have had this for essentially forever.

It does sometimes mean that when you update some code, you have to update a
bunch of other things. But it's rarely spurious. Usually those other things
are broken by failing to consider the new possibility.

In the long term, it's a maintenance win.

~~~
jameshart
But C# enums are a terribly weak data type, not a good implementation for the
semantic you're looking for at all.

Better to ask for a C# union type and matching syntax.

------
_rmt_
This looks great. I just stepped back into java for a one off project, after
not touching it for about 15 years. I was surprised how antiquated it felt
compared to modern C#. Glad to see Microsoft is not letting the language
languish.

~~~
dep_b
Oracle basically destroyed every cool technology they inherited.

~~~
severino
I know everybody hates Oracle here, but Java 7, 8 and the upcoming 9 releases,
all of them under Oracle's control, have had more improvements than Sun did in
the years prior to the acquisition. How's that destroying anything?

~~~
dep_b
* Ugly Oracle DB style contracts

* Scaring potential customers away with said contracts and suing customers

* Google walking out on Java going with Kotlin instead....boom billions of users moving to a different language. Still on the JVM though....but that's not a hard requirement.

~~~
pjmlp
In spite of the lawsuits, Google is actually a big contributor to the OpenJDK
and a common presence at Java Languages Summit.

As for Kotlin, it remains to be seen how much uptake it will actually take.

Despite all attempts from Apple to push Swift, many keep on using Objective-C.

~~~
dep_b
> As for Kotlin, it remains to be seen how much uptake it will actually take.

Kotlin is a language made by JetBrains which happens to be the creator of the
official Android IDE. So yes the push will be strong from both Google and
JetBrains. Java was a bit more modern than Objective-C but if I see what our
junior Android dev has to type and type and type and type in Java to do the
same as I do in Swift....kids get bored quick you know...

> Despite all attempts from Apple to push Swift, many keep on using
> Objective-C.

I don't encounter many during my job as an iOS developer. I encounter people
maintaining an existing Objective-C codebase that isn't worth switching and
adding 10MB of application weight for Swift.

I guess for all green fields projects 80% is Swift. There's just no reason to
use Objective-C anymore since Swift 3 so the only people that choose it are:

a) People interfacing with C / C++ a lot b) People creating a framework that
needs to play nice with both c) People stuck in old ways

~~~
pjmlp
It doesn't matter if kids get bored, rather what the people giving the money
want to get.

So far, I haven't found an enterprise customer that was willing to allow
anything but Java, unless it is required by the tooling.

For example Scala only when making use of Spark.

I am happy that Kotlin is now an approved language on Android, but trying to
kill Java on JVM, C on UNIX, JavaScript on the browser, ....

It is never going to go away, and those that embrace the language of the
platform are in advantage.

------
dep_b
I'll crank up those `null` assignments to non-optional references warnings up
to compiler errors. There's really no reason to ship software that doesn't
explicitly declare something as nullable.

The `!`'s are always code smells. I hope I can turn them into warnings or
build errors.

~~~
taco_emoji
I wouldn't say they're _always_ code smells. Like they say in the video, a
call to the 'myString.IsNullOrEmpty()' extension method is a null check, but
there's no way to prove that to the compiler.

~~~
dep_b
I think that's more of a compiler problem then. Also what's missing is the
unwrap syntax to easily transform between nullable and non-null references.
What you really want is to operate on a non-null version of that reference if
it's proven to be non-null, this is really the Achilles heel of this
particular implementation. You're still checking for null all over the place,
it's just better checked.

    
    
        // Unholy mix of Swift and C# syntax ahead!
        if var unwrappedString = wrappedString && unwrappedString != "" {
             unwrappedString.Length();
        }
    

Where the `if var unwrappedString = wrappedString` part would unwrap the var
_and_ return a `bool` at the same time which is `true` if it wasn't `nil`.

Swift's nil-checking / unwrapping syntax is really short and with some clever
usage of `map` or `flatMap` you can still have one-liners albeit a bit more
verbose - but much more secure.

Example of using map:

    
    
        let myTitle = myObject?.title.map { "Item \($0)" } ?? "No title"
    

This code can't even _theoretically_ crash anymore and doesn't force
unwrapping with `!` as a traditional approach would do:

    
    
        let myTitle = myObject?.title != nil ? "Item \(myObject!.title!)" : "No title"

~~~
int_19h
You can totally do this in C#, since it has lambdas, and you can use the
extension method to add "map" to nullable references of arbitrary types. It
also has ??.

The problem is that lambdas aren't free. For something as simple as a null
check, the overhead of a lambda is excessive. Zero-cost lambdas are possible,
but require a new type of lambda that cannot escape the enclosing scope, all
reflected in the type system.

------
bouke
Great to see these Swift features[1] appearing in C#:

* Nullable Reference Types This makes it so much easier to reason about references. I always found it strange that C# had nullability on value types, but not on reference types.

* Default Interface Implementations Inherit an interface, and get an implementation "for free". This makes for a very powerful way to define interfaces and default implementations.

* Extension Everything As noted in the video/text, the current syntax feels a bit weird -- having to use a static class.

[1]: Not saying these are exclusive to Swift, or Swift was the first to
implement them.

~~~
bernadus_edwin
Nullable reference without "if let" keyword is disaster

~~~
MadsTorgersen
"If let" could be easily mirrored by a pattern in C#, and we are starting to
discuss that.

However, that's a _new_ way to check for null in the language, where what we
need is to recognize the ways people are _already_ checking for null in
billions of lines of code. Therefore, the priority is to do a good flow
analysis that will just understand when a nullable variable can be assumed to
not be null (e.g. after a check, a non-null assignment, etc.), and then let
you dereference without challenge.

~~~
bernadus_edwin
If c# 8 has good flow for checking null, then no need "if let". If let also
has disadvantage, backward compartibility. For example, maybe i want change my
logic class to c# 2

------
joostdevries
Interesting, the new type IAsyncEnumerable is like an Observable. But it's
pull instead of push. Ie it supports backpressure like the Reactive Streams
[1] standard in the JVM world. I seem to recall that Erik Meijer had some
strong opinions when that standard was forming on backpressure and anything
that's not purely push based.

Personally as a developer I really like having the choice whether to buffer in
one place in my system (using a persistent queue f.i.) and have the rest of
the system cooperate in tandem without running out of memory f.i. Or to choose
to ignore elements when stuff is just going to fast. Etc. I feel more in
control of the behaviour under load of my system.

I guess Lightbend was onto something when they took the old EAI notion of
backpressure (as f.i. described in Gregor Hohpes book) and implemented it in
stream processing and started an interoperability standard around it.

[1] [http://www.reactive-streams.org/](http://www.reactive-streams.org/)

------
SimonPStevens
I feel like I've been waiting for non-nullable reference types for forever.

What they talk about here, with explicit nullable reference types is so close
but stumbles at the last hurdle. Having some kind of opt in on the compiler
that makes regular references non-nullable is great for new projects (and
arguably the best thing for the language itself), but leaves all legacy code
out in the dark. You can't switch on a compiler option like this on any big
existing project without massive effort. (And massive effort means management
approval and planning and justification)

They got the case by case opt on the wrong part of the feature. It's really
the non-nullability of a reference that's most important to be able to be
opted in to on a case by case basis. (And case by case opt in means low
effort, so it doesn't need big up front approval or planning, you just get on
and write better code with fewer bugs.)

What's really needed is something like this

    
    
        String! s = null;
    

Where the ! makes the s reference non-nullable, so any attempt to assign null
(or anything that could be null) to it is a compiler error.

And it's so disappointing because he comes so so close to that at the end with
his talk of s!. as a way to say that you know something is not null, but it
just doesnt quite get the benefit right.

It's non-nullability of reference types that should be the central feature
here.

I'm just really hoping that these guys know what they are doing, and it's just
he couldn't explain the subtleties in a short video, and this is going to turn
out working the right way in the end.

~~~
int_19h
The problem with that approach is that if you have it there, people will
forget to use it, and still end up with tons of nullable references that
really should be non-nullable. In order to be effective at catching bugs, non-
nullability _has_ to be opt-out rather than opt-in.

Yes, this sucks for existing code. I suspect that we'll get some kind of file-
level switch, so that you can port things one class at a time - there's no
reason why that switch has to have the same value for all files in the
project.

~~~
SimonPStevens
No reason why there can't be both. Syntax to opt in one at a time for old
projects, and a compiler option for new projects.

Yeah, or a file level switch would do, that would be fine. As long as there is
some way of transitioning a project little bit at a time.

I hope we get one of those options

------
zwieback
Why is default interface implementation controversial? I get it for moving
existing .Net functionality around but for development of new code, what's the
downside.

Coming from C++ it seemed like C# interfaces (and Java at the time) felt like
a punishment. Now I'm sort of used to them.

~~~
int_19h
It requires runtime (VM) support. That's always a much higher bar to clear
than pure language features.

------
eighthnate
C# 7 was release a few months ago. The video is just a prototype of what C# 8
could have.

~~~
pjmlp
The current version is 7.1 already.

------
nxc18
There's some interesting and controversial stuff in here. I am very excited
about extension everything. I also like the new extension method syntax; much
cleaner and a much clearer expression of intent.

~~~
bpicolo
Feels like extensions tend to make it hard to find out what you need to import
to make things work as intended. Maybe visual studio proper is better at
inference for it? Will only autocomplete methods that are actually in scope as
far as I can tell.

~~~
wvenable
It will only auto-complete methods that are in scope (the alternative would be
a bit crazy) however Visual Studio is smart: if you type in a method you know
exists you can press CTRL-. to get it to add the correct using statement to
bring that extension method into scope.

~~~
nickspag
You can turn on an Intelisense option to show methods that would be in scope,
if you had the using statement, and it will auto add the using statement if
you select that. Really helpful.

~~~
wvenable
Is this a Resharper thing?

~~~
nickspag
No, but after looking at VS 2017 on my pc and VS for Mac, apparently it's only
a feature in VS for Mac- at least from what I could find. I imagine that gets
changed soon but yea.

If you use VS for Mac its under Preferences > Text Editor > Intellisense >
Show Import Items

~~~
int_19h
In VS 2017, if you use a method that's an extension method, and don't have the
namespace imported, it'll show the auto-correction bulb with an offer to
import it.

Better yet, if it's from a NuGet package, it'll offer to install one (or
several, if there are multiple candidates).

------
daxfohl
Would "extension interfaces" be equivalent to "type classes" in Haskell and/or
"traits" in Scala or Rust?

~~~
joostdevries
Being able to take an instance Person and make it be an Employee without
changes to the Person class definitely sounds like ad hoc polymorphism. In
Scala the equivalent of Haskells type classes is implicits though. Not traits.
I do wonder if this 'extension interface implementation' feature would support
the same inferencing that type classes in Haskell and implicits in Scala do.
So that might be a difference.

~~~
daxfohl
> In Scala the equivalent of Haskells type classes is implicits though. Not
> traits.

Really? I'm not an expert but everything I've read until this implies the
opposite. Besides, C# already has implicit conversions, and they're different
from type classes in that they _convert_ , not _extend_. Once an int is
implicitly converted to a double, it's always a double from within the
function that converted it, not just "representing" a double. So strictly less
powerful than polymorphism. My understanding that type classes were the way
out of that, and traits were Scala's equivalent. Is that not correct?

~~~
lkitching
It's implicit arguments, not implicit conversions that enable type classes in
Scala, although the class is usually represented by a trait e.g.

    
    
        trait Show[T] { def show(v : T): String }
        implicit object ShowInt extends Show[Int] {
    	def show(i: Int) = i.toString
        }
        def showLine[T](v : T)(implicit show: Show[T]): Unit = {
            println(show.show(v))
        }

~~~
daxfohl
Nice, that makes it more clear. Thanks!

