Комментарии 19
1. Зачем
var v = expr as Type;   
if (v != null) {
    // Используем v
}

Когда expr is Type возвращает bool?

2. Обязательно ли record type будет ссылочным? Возможно ли наследование?

3. Является ли знак " * " литералом, который транслируется в default(T) или тут применено более сильное колдунство?
1) потому что expr имеет тип Expr, а v — тип Type. чтобы пользоваться возможностями типа Type и не делать лишних преобразований.

2) пример class Const(double Value): Expr; показывает, что наследование возможно.

3) нет, скорее он транслируется в var $temp, где переменная $temp нигде не используется.
3) Да, с реализации пока не понятно. Функционал еще не написан.
2. Дополнение: судя по оригиналу, record struct тоже возможно. Так что не обязательно ссылочный.
А откуда в выражении
if (c is Polar(5, *)) Console.WriteLine( R );
берется R?
Похоже, что опечатка. Интересно другое:
— верно ли, что «s is Polar(5,*)» полностью эквивалентно «s is Polar(var $R,*) && $R==5»;
— можно ли использовать такой же трюк в других вызовах с out
— можно ли в других вызовах с out использовать var и *;
— можно ли переопределить matching с входным параметром, чтобы вставить свою функцию проверки истинности (например, Math.Abs(R-5)<eps)
1) Мне кажется нет. Судя по всему определение перемененной будет в следующем блоке.
2) Вряд ли, это фишка оператора is
3) Это вроде как новая фишка C# общая.
4) Не понял, что вы имеете ввиду.
4) Что-нибудь такое:
public static class Polar
{
    public static bool operator is(Cartesian c, out double R, out double Theta)
    {
        R = Math.Sqrt(c.X*c.X + c.Y*c.Y);
        Theta = Math.Atan2(c.Y, c.X);
        return c.X != 0 || c.Y != 0;
    }
    public static bool operator is(Cartesian c, double R, out double Theta)
    {
        if(Math.Abs(Math.Sqrt(c.X*c.X + c.Y*c.Y)-R)>R*1e-6) return false;
        Theta = Math.Atan2(c.Y, c.X);
        return c.X != 0 || c.Y != 0;
    }
}

Потому что иначе приведённый пример сработает только на 12 точках, а для остальной окружности скажет false.
Вряд ли так можно, компилятор не будет знать какой метод вызвать. А два подряд метода вызывать, мне кажется лишним усложнением.
Да вы правы, плохо изучил ваш пример, информации об этом в спецификации, я не нашел. Но судя по общей логике это не учли, хотя все может изменится в любой момент
Да вы правы, плохо изучил ваш пример, информации об этом в спецификации, я не нашел. Но судя по общей логике это не учли, хотя все может изменится в любой момент.
Пришел он к нам из таких языков как Python и F#.
Вроде они называют другой список языков, откуда позаимствовали: github.com/dotnet/roslyn/issues/1572#issue-64339348
Sources of Inspiration: Scala, F#, Swift, Rust, Erlang, Nemerle

Ещё бы discriminated union добавили, стало бы совсем хорошо.
Ещё бы discriminated union добавили, стало бы совсем хорошо


То что они называют записями и есть «discriminated union», точнее алгебраические типы.
Разве?
public class Cartesian(double x: X, double y: Y);
Это совсем не discriminated union.
Алгебраические типы подразумевают два способа конструирования типов из уже имеющихся:
1. Произведение — есть почти во всех языках — структуры, кортежи (tuples), и, в данном случае, record type.
2. Сумма — это как раз тот самый discriminated union.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.