Re[8]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 12.01.12 15:35
Оценка:
Здравствуйте, calc.exe, Вы писали:

CE>А сколько людей на данный момент вообще знают о pattern matching? Через некоторое время — да, синтаксис станет "естественным". А пока может быть самое время сделать его оптимально удобным. (А where в ПМ, насколько я помню, вообще ввел VladD2 — тут говорить о "традициях" вообще смешно.)


Знают или узнают изучающие все функциональные языки, начиная от МЛ до хаскеля. Насколько я знаю where ввел не Влад, это появилось раньше, по крайней мере он рад был вообще от него отказаться, чем я и помог. Все же вы не ответили на вопрос что вам мешает использовать единый синтаксис для вариантов и классов:


def a : object = GetObject();
match (a)
{
| A.B(f)                      => // матч если переменная имеет подвариант A.B и получаем поле f
| A(field = f)                => // совпало если просто A, получаем значение поля field в переменную f
| MyClass(field = f)          => // получаем также поле f из класса типа MyClass если переменная этого типа, аналогично варианту
//| MyClass where (field = f) => // старый синтаксис довольно громоздкий, по типу класса
| MyClass @ (field = f)       => // совсем не упрощает синтаксис
}


Вроде я предложил вариант короче, и он уже принят Владом, изменения в мастере, что мешает пользоваться единообразным синтаксисом, конструктор как у варианта в паттерне конструктор, попробуйте и оцените, может не так уж неудобно и выразите ваше мнение.
Re[9]: Паттерн матчинг классов без where
От: IT Россия linq2db.com
Дата: 12.01.12 18:22
Оценка: 2 (1)
Здравствуйте, CodingUnit, Вы писали:

CU>Вроде я предложил вариант короче, и он уже принят Владом, изменения в мастере, что мешает пользоваться единообразным синтаксисом, конструктор как у варианта в паттерне конструктор, попробуйте и оцените, может не так уж неудобно и выразите ваше мнение.


Попробовал, выглядит прикольно.
Было:

internal IsDefaultValuePlaceHolder(expr : Expression) : bool
{
    | Member(null, member) when
        member.DeclaringType.IsGenericType &&
        member.Name == "Value" &&
        member.DeclaringType.GetGenericTypeDefinition() == typeof(DefaultValue[_])

    | _ is DefaultValueExpression => true
    | _ => false
}

стало:

internal IsDefaultValuePlaceHolder(expr : Expression) : bool
{
    | Member(null, (DeclaringType = (IsGenericType = true) as dt, Name = "Value")) when
        dt.GetGenericTypeDefinition() == typeof(DefaultValue[_])

    | _ is DefaultValueExpression => true
    | _ => false
}

А с таким ExtensionPattern:

[assembly: ExtensionPattern(Expression, Member2(expr, name, dectype) = MemberExpression where (Expression = expr, Member = (Name = name, DeclaringType = dectype)))]

даже так пропёрло:


internal IsDefaultValuePlaceHolder(expr : Expression) : bool
{
    | Member2(null, "Value", (IsGenericType = true) as dt) when
        dt.GetGenericTypeDefinition() == typeof(DefaultValue[_])

    | _ is DefaultValueExpression => true
    | _ => false
}
Если нам не помогут, то мы тоже никого не пощадим.
Re: Паттерн матчинг классов без where
От: _Claus_  
Дата: 12.01.12 18:27
Оценка:
выложенный билд немного потестил. ошибок не обнаружил.
Re[10]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 12.01.12 18:41
Оценка:
Здравствуйте, IT, Вы писали:

IT>Попробовал, выглядит прикольно.


IT>
IT>internal IsDefaultValuePlaceHolder(expr : Expression) : bool
IT>{
IT>    | Member(null, (DeclaringType = (IsGenericType = true) as dt, Name = "Value")) when
IT>        dt.GetGenericTypeDefinition() == typeof(DefaultValue[_])

IT>    | _ is DefaultValueExpression => true
IT>    | _ => false
IT>}
IT>


отлично!
Смею предложить возможное укорочение кода:

internal IsDefaultValuePlaceHolder(expr : Expression) : bool
{
| Member(null, (DeclaringType = (IsGenericType = true) as dt, Name = "Value")) => dt.GetGenericTypeDefinition() == typeof(DefaultValue[_])
| x => x is DefaultValueExpression
}


IT>А с таким ExtensionPattern:


IT>
IT>[assembly: ExtensionPattern(Expression, Member2(expr, name, dectype) = MemberExpression where (Expression = expr, Member = (Name = name, DeclaringType = dectype)))]
IT>

IT>даже так пропёрло:

IT>[nemerle]


да это тоже штука мощная в свое время.
Re[2]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 12.01.12 18:42
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>выложенный билд немного потестил. ошибок не обнаружил.


Спасибо. Вот и здорово.
Re[3]: Паттерн матчинг классов без where
От: Аноним  
Дата: 12.01.12 19:28
Оценка:
а вот это правильно? f можно привести к выставленному типу?

public variant V
    | A 
        r : string
        s : double
    | B 
        z : int
        
    
  class C    
    
    public this()  
      
     mutable f: V
      
      match(f)
        | V.A => _ = f.r
Re[4]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 12.01.12 19:50
Оценка:
Здравствуйте, Аноним, Вы писали:

А>а вот это правильно? f можно привести к выставленному типу?

А>

А>public variant V
А>    | A 
А>        r : string
А>        s : double
А>    | B 
А>        z : int
        
    
А>  class C    
    
А>    public this()  
      
А>     mutable f: V
      
А>      match(f)
А>        | V.A => _ = f.r


А>


здесь обычные правила действуют, свое намерение компилятору надо указать явно, иначе он будет смотреть за переменной f в области видимости, которая есть f : V. Откуда он знает что вы хотите работать с экземпляром V или V.A это все таки приведение и оно требует накладных расходов. Для этого делается обычно:

public this()  
{     
 def f : V;
 match (f)
 {
  | V.A as f => _ = f.r
 }
}



так делается во всех мне известных функциональных языках, это as pattern, как видите здесь могут быть очень сложные паттерны, в языке нет распознавания простой или сложный просто каждый паттерн обрабатывается по какому то принципу, например:


def tuple = (V.A("", 1), V.B(0))
match (tupl)
{
| (V.A, V.B) => // непонятно нужно ли что то приводить здесь фигурирует такой же паттерн что и выше
}

match (obj)
{
 | ComplexType(Part(0), Part2(Some(a))) => // тот же паттерн и что тут приводить не ясно, надо указать явно
 | ComplexType(Part(0), Part2(Some(a) as p)) as t => //
}


Вообщем автоматическое приведение тут не очень хорошо.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.