Hacker News new | past | comments | ask | show | jobs | submit login

I'm seeing a lot of interest in pattern matching as users that have discovered it via rust's `match` or similar want to benefit from it in $dayjob language.

C# has seen a similar push to implement pattern matching, down to the use of `_` as discard. The first iteration of this feature in C# 7 is feature light, but it's a good start, and they've promised more to come. The team behind C# has become really good at getting over NIH and embracing new technologies and techniques while somehow preserving backwards compatibility and ergonomics. Anders Hejlsberg doesn't kid around.

Here's an example cribbed from an official MSFT blog [0]:

    public static int Count<T>(this IEnumerable<T> e)
    {
        switch (e)
        {
            case ICollection<T> c: return c.Count;
            case IReadOnlyCollection<T> c: return c.Count;
            // Matches concurrent collections
            case IProducerConsumerCollection<T> pc: return pc.Count;
            // Matches if e is not null
            case IEnumerable<T> _: return e.Count();
            // Default case is handled when e is null
            default: return 0;
        }
    }
A lot of people have lamented this as the death of F#, but I think MSFT is making the right calls here.

EDIT:

Little-known fact: C# actually does have discriminated unions, and has had for a long time (from the start?) in the form of the `Exception` base class. In fact, pattern matching in C# can be "pulled off" (read: hacked together as a proof-of-concept) without the changes from C# 7 by simply using the extended catch syntax:

    class MyType1 : System.Exception
    { /* ... */ }

    class MyType2 : System.Exception
    { /* ... */ }

    void foo()
    {
        throw something ? new MyType1() : new MyType2();
    }

    void bar()
    {
        try
        {
            foo()
        }
        catch (MyType1 mtype)
        {
            //take type-specific action here
        }
        catch (MyType2 mtype)
        {
            //take type-specific action here
        }
        catch (Exception _)
        {
            //the _ was optional, but this is the `default` block
        }
    }


[0]: https://blogs.msdn.microsoft.com/seteplia/2017/10/16/dissect...



I might be wrong, but I'd say that the interest in switch expressions and pattern matching from the Java community most likely comes from Scala (a JVM language) rather than Rust. Here's an example from the Scala docs:

  def showNotification(notification: Notification): String = {
    notification match {
      case Email(email, title, _) =>
        s"You got an email from $email with title: $title"
      case SMS(number, message) =>
        s"You got an SMS from $number! Message: $message"
      case VoiceRecording(name, link) =>
        s"you received a Voice Recording from $name! Click the link to hear it: $link"
    }
}


No need for the '{' after "String = ". It'll make your code less crowded.


My interest in pattern matching goes back to Caml Light and Standard ML, learned in 1996.

Rust is not the source of all innovations.

> Anders Hejlsberg doesn't kid around.

Except he doesn't do much C# nowadays, Mads Torgersen is the actual C# chief architect.

While Anders still advises on C#, he has switched focus to Typescript.


Hejlsberg isn't involved with C# any more.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: