Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 05.01.12 07:59
Оценка: 99 (1) +1
Подумал что не очень удобно матчить классы с ключевым словом where, особенно когда классы вложенные, решил посмотреть что мешает в компиляторе реализовать эту функцию, оказывается все очень просто, эта функция включается добавлением одной строчки. Старый синтаксис останется тоже для совместимости, остается лишь вопрос что думает сообщество на это изменение, нет ли возражений и аргументов против этого?



class Test
{
  public field : int;
}

// старый синтаксис:
def func1(obj : Test)
{
 match (obj)
 {
   | Test where (field = f) => f
 }
}

// новый синтаксис (не отличается от вариантов):
def func2(obj : Test)
{
 match (obj)
 {
   | Test(field = f) => f
 }
}
Re: Паттерн матчинг классов без where
От: _NN_ www.nemerleweb.com
Дата: 05.01.12 08:22
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Подумал что не очень удобно матчить классы с ключевым словом where, особенно когда классы вложенные, решил посмотреть что мешает в компиляторе реализовать эту функцию, оказывается все очень просто, эта функция включается добавлением одной строчки. Старый синтаксис останется тоже для совместимости, остается лишь вопрос что думает сообщество на это изменение, нет ли возражений и аргументов против этого?


А не будет неоднозначности понимания ?
public class A
{
  public this(field : int) { this.field = field; }
  
  public field : int;
}

def a = A(10);

// Сопоставляется не конструктор, а поле. Это видно из "where"
def oldf = 
 match (a)
 {
   | A where (field = f) => f
 };

// Сопоставляется не конструктор, но с первого взгляда не ясно.
def newf = 
 match (a)
 {
   | A (field = f) => f
 };
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Паттерн матчинг классов без where
От: _Claus_  
Дата: 05.01.12 11:14
Оценка:
CodingUnit, предложение отличное. унификация в программинге — вещь архиважная.

_NN>def newf =

_NN> match (a)
_NN> {
_NN> | A (field = f) => f
_NN> };
_NN>[/nemerle]

_NN>// Сопоставляется не конструктор, но с первого взгляда не ясно.


с вариантами та же "проблема"
Re[2]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 05.01.12 13:40
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>А не будет неоднозначности понимания ?


_NN>// Сопоставляется не конструктор, а поле. Это видно из "where"

_NN>def oldf =
_NN> match (a)
_NN> {
_NN> | A where (field = f) => f
_NN> };

_NN>// Сопоставляется не конструктор, но с первого взгляда не ясно.

_NN>def newf =
_NN> match (a)
_NN> {
_NN> | A (field = f) => f
_NN> };
_NN>[/nemerle]

Неоднозначность устраняется если человек однажды увидел как это работает или прочитал в статье, просто надо понять что record паттерн, это всегда сопоставление полей, как и есть в определении. По мне слово where избыточно и хоть и дает по началу какое то понимание, но когда программируешь долго на практике и уже знаешь смысл всего, а это основное время, оно очень разрастает код, хотя какие то вещи проще написать быстро и ясно. Много натыкался что забыв записать слово where получал ошибку, что это не вариант, хотя было бы проще написать один паттерн. Действительно и варианты могут иметь свои конструкторы, которые не соответствуют полям, и такая запись игнорирует конструкторы потому что сопоставляет поля, такие вещи кроме как опытом не узнаются, а вот если человек указал A(f, f2, f3) то это очень похоже на конструирование объекта, но такой синтаксис для классов неуместен.
Re[3]: Паттерн матчинг классов без where
От: _NN_ www.nemerleweb.com
Дата: 05.01.12 13:52
Оценка:
Здравствуйте, _Claus_, Вы писали:


_C_>CodingUnit, предложение отличное. унификация в программинге — вещь архиважная.


_NN>>def newf =

_NN>> match (a)
_NN>> {
_NN>> | A (field = f) => f
_NN>> };
_NN>>[/nemerle]

_NN>>// Сопоставляется не конструктор, но с первого взгляда не ясно.


_C_>с вариантами та же "проблема"


Действительно, все 4 строки означают одно и тоже:
variant A
{
    | X { p : int; q : int }
}

def aa = A.X(1,1); 
match (aa)
{
    | A.X       (    pp,     qq) => ()
    | A.X       (p = pp, q = qq) => ()
    | A.X where (    pp,     qq) => ()
    | A.X where (p = pp, q = qq) => ()
    | _ => ()
}


В любом случае сопоставляется не конструктор, а поля/свойства.



Кстати почему есть различия между полями и свойствами тут:
class HasFields
{
    public this() {}
    
    public q : int;
    public p : int;
}

class HasProperties
{
    public this() {}
    
    public p : int{get;set;}
    public q : int{get;set;}
}

module PP
{
    Main() : void
    {
        // OK
        def hasFields = HasFields();
        match (hasFields)
        {
            | HasFields where (p = 1, q = 2) => ()
            | HasFields where (    1,     2) => ()
            | _ => ()
        }
        
        def hasProperties = HasProperties();
        match (hasProperties)
        {
            | HasProperties where (p = 1, q = 2) => ()
            | HasProperties where (    1,     2) => () // error : pattern matches 2 values, while the type `HasProperties' has 0 fields
            | _ => ()
        }
    }
}


Почему для свойств нельзя использовать "where (1, 2)" ?
Недоработка ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 05.01.12 14:09
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Кстати почему есть различия между полями и свойствами тут:

_NN>
_NN>class HasFields
_NN>{
_NN>    public this() {}
    
_NN>    public q : int;
_NN>    public p : int;
_NN>}

_NN>class HasProperties
_NN>{
_NN>    public this() {}
    
_NN>    public p : int{get;set;}
_NN>    public q : int{get;set;}
_NN>}

_NN>module PP
_NN>{
_NN>    Main() : void
_NN>    {
_NN>        // OK
_NN>        def hasFields = HasFields();
_NN>        match (hasFields)
_NN>        {
_NN>            | HasFields where (p = 1, q = 2) => ()
_NN>            | HasFields where (    1,     2) => ()
_NN>            | _ => ()
_NN>        }
        
_NN>        def hasProperties = HasProperties();
_NN>        match (hasProperties)
_NN>        {
_NN>            | HasProperties where (p = 1, q = 2) => ()
_NN>            | HasProperties where (    1,     2) => () // error : pattern matches 2 values, while the type `HasProperties' has 0 fields
_NN>            | _ => ()
_NN>        }
_NN>    }
_NN>}
_NN>


_NN>Почему для свойств нельзя использовать "where (1, 2)" ?

_NN>Недоработка ?

Нет это видимо идет из того определения типов, что они конструируются значением полей, как это обычно в record и вариантах, к свойствам это не относится потому что они могут представлять что угодно, паттерн конструктор (второй вариант) учитывает только поля, а паттерн record A(p = 1, q = 2) это уже значения внутренностей, это классика ПМ. Но в принципе это не особо и напрягает писать f = 1, для проверки значения, сначала надо подумать как избавиться от слова where, а потом посмотрим что еще можно улучшить.
Re: Паттерн матчинг классов без where
От: IT Россия linq2db.com
Дата: 05.01.12 14:18
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Подумал что не очень удобно матчить классы с ключевым словом where


А чем ExtensionPattern не устраивает? Или Влад держит его в страшной тайне?
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 05.01.12 17:22
Оценка:
Здравствуйте, IT, Вы писали:

IT>А чем ExtensionPattern не устраивает? Или Влад держит его в страшной тайне?


И чем же он поможет, помечать каждый класс со всеми группами возможных полей и свойств, чтобы получить замену слова where, не усложнение ли это? Когда все можно сделать изначально проще. Непонятно зачем нужно еще одно ключевое слово в такой часто используемой фиче.
Re[3]: Паттерн матчинг классов без where
От: IT Россия linq2db.com
Дата: 05.01.12 17:32
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>И чем же он поможет, помечать каждый класс со всеми группами возможных полей и свойств, чтобы получить замену слова where, не усложнение ли это? Когда все можно сделать изначально проще. Непонятно зачем нужно еще одно ключевое слово в такой часто используемой фиче.


Это зависит от того насколько часто используется один и тот же класс в PM. Если один раз, то можно и с where написать, если часто, то ExtensionPattern может оказаться очень удобной альтернативой, в том числе, кстати, и для вариантов тоже.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 05.01.12 18:03
Оценка:
Здравствуйте, IT, Вы писали:

IT>Это зависит от того насколько часто используется один и тот же класс в PM. Если один раз, то можно и с where написать, если часто, то ExtensionPattern может оказаться очень удобной альтернативой, в том числе, кстати, и для вариантов тоже.


Не знаю мне кажется это усложнение, если есть возможность ввести синтаксис проще, почему нет, главный вопрос в этом что противоречит в использовании ПМ классов без where, если никаких конфликтов не возникает, то надо однозначно использовать его, жду именно аргументов какие могут быть конфликты если используем без where, пока аргументы не существенные.
Re[5]: Паттерн матчинг классов без where
От: IT Россия linq2db.com
Дата: 05.01.12 18:51
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Не знаю мне кажется это усложнение, если есть возможность ввести синтаксис проще, почему нет, главный вопрос в этом что противоречит в использовании ПМ классов без where, если никаких конфликтов не возникает, то надо однозначно использовать его, жду именно аргументов какие могут быть конфликты если используем без where, пока аргументы не существенные.


Синтаксис с where отличается от предложенного тобой тремя символами. Стоит ли ради этого городить огород?
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 05.01.12 18:58
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, CodingUnit, Вы писали:


CU>>Не знаю мне кажется это усложнение, если есть возможность ввести синтаксис проще, почему нет, главный вопрос в этом что противоречит в использовании ПМ классов без where, если никаких конфликтов не возникает, то надо однозначно использовать его, жду именно аргументов какие могут быть конфликты если используем без where, пока аргументы не существенные.


IT>Синтаксис с where отличается от предложенного тобой тремя символами. Стоит ли ради этого городить огород?


Не вижу как он может различаться тремя символами, если вложенные классы то там таких связок where может быть сколько угодно и текст уедет на две и более строки или за экран, у меня такое бывало. ЭкстеншонПаттерн не спасает, поскольку это глобальная задача паттерна для нужного слова, каждый раз идти переписывать аттрибут если мне нужно всего лишь декларативно описать задачу в текущей строке не упрощает задачу. Тем более что я сказал реализация огорода без where это всего лишь добавление в компиляторе 1 строки.
Re[3]: Паттерн матчинг классов без where
От: _Claus_  
Дата: 06.01.12 09:27
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Здравствуйте, _NN_, Вы писали:


_NN>>А не будет неоднозначности понимания ?


_NN>>// Сопоставляется не конструктор, а поле. Это видно из "where"

_NN>>def oldf =
_NN>> match (a)
_NN>> {
_NN>> | A where (field = f) => f
_NN>> };

_NN>>// Сопоставляется не конструктор, но с первого взгляда не ясно.

_NN>>def newf =
_NN>> match (a)
_NN>> {
_NN>> | A (field = f) => f
_NN>> };
_NN>>[/nemerle]

CU> если человек указал A(f, f2, f3) то это очень похоже на конструирование объекта, но такой синтаксис для классов неуместен.

а вообще бывают ситуации в ПМ, когда необходимо конструировать объект? если нет, тогда парится не стоит и
A(f, f2, f3) есть сокращенный вариант A(f = f, f2 = f2, f3 = f3) хоть для вариантов, хоть для классов.
для совместимости с написанным кодом для явных вариантов при несовпадении f, f2, f3 с полями они инициализируются согласно порядку.

стереть разницу между вариантами и классами — дорогого стоит. тянет на среднюю по размерам сенсацию.
Re: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 06.01.12 09:37
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Подумал что не очень удобно матчить классы с ключевым словом where, особенно когда классы вложенные, решил посмотреть что мешает в компиляторе реализовать эту функцию, оказывается все очень просто, эта функция включается добавлением одной строчки. Старый синтаксис останется тоже для совместимости, остается лишь вопрос что думает сообщество на это изменение, нет ли возражений и аргументов против этого?



Еще столкнулся со следующей проблемой, не матчаться без слова where сами варианты, то есть абстрактный тип варианта, например:


variant A
{
 | A1
 | A2

 field : int;
}

def test = A.A1();
match (test)
{
 | A where (field = f) => f
}

это старый синтаксис и работает

у меня в проекте часто используется именно базовый вариант и его поля, думаю правильно ли распознавать его так:

match (test)
{
 | A(field = f) => f
}


в принципе с реализацией нет проблем, надо добавить еще одну строчку для поддержки варианта, а не класса (они различаются), но думаю правильно ли это с общей функциональной точки зрения, как паттерн конструктор абстрактного типа? Мне кажется если это класс то его также можно матчить без where, но могут быть неоднозначности с его подвариантами, хотя это чисто логическая ошибка. Что думает народ?
Re[2]: Паттерн матчинг классов без where
От: _Claus_  
Дата: 06.01.12 09:50
Оценка:
CU>но думаю правильно ли это с общей функциональной точки зрения, как паттерн конструктор абстрактного типа?
если понятие "паттерн конструктор абстрактного типа" заменить на "паттерн абстрактного типа" тогда все правильно.

CU>Мне кажется если это класс то его также можно матчить без where, но могут быть неоднозначности с его подвариантами

какие?
Re[3]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 06.01.12 13:24
Оценка:
Здравствуйте, _Claus_, Вы писали:


CU>>но думаю правильно ли это с общей функциональной точки зрения, как паттерн конструктор абстрактного типа?

_C_>если понятие "паттерн конструктор абстрактного типа" заменить на "паттерн абстрактного типа" тогда все правильно.

ну в принципе само понятие паттерн конструктор, это чистая абстракщина, сам объект не конструируется но как бы собирается в обратном порядке для получения его содержимого, наверное это применимо концептуально и к абстрактному типу. Так вроде все удобно и интуитивно получается.

CU>>Мне кажется если это класс то его также можно матчить без where, но могут быть неоднозначности с его подвариантами

_C_>какие?

Ну просто кто то захочет матчить подвариант A1, а напишет A, раньше он бы получил ошибку компиляции что типа это не вариант опция, а теперь компилятор сьест и может матчить и конструктором и как рекорд паттерн, даже может совпасть паттерн, или логическую или ошибку компиляции получит, пока догадается.
Re[4]: Паттерн матчинг классов без where
От: _Claus_  
Дата: 06.01.12 13:30
Оценка: -1
CU>Ну просто кто то захочет матчить подвариант A1, а напишет A, раньше он бы получил ошибку компиляции что типа это не вариант опция, а теперь компилятор сьест и может матчить и конструктором и как рекорд паттерн, даже может совпасть паттерн, или логическую или ошибку компиляции получит, пока догадается.

от ошибок в голове ничем не застрахуешь. если же писать правильно — проблем не будет.
Re[4]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 06.01.12 13:33
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>а вообще бывают ситуации в ПМ, когда необходимо конструировать объект? если нет, тогда парится не стоит и

ну сам объект не конструируется в ПМ, а деконструируется или декомпозируется.

_C_>A(f, f2, f3) есть сокращенный вариант A(f = f, f2 = f2, f3 = f3) хоть для вариантов, хоть для классов.

_C_>для совместимости с написанным кодом для явных вариантов при несовпадении f, f2, f3 с полями они инициализируются согласно порядку.
вообще все именно так и есть, и компилятор паттерн (f, f2, f3) вручную переписывает в (f = f, f2 = f2, f3 = f3), и они инициализируются согласно порядку

_C_>стереть разницу между вариантами и классами — дорогого стоит. тянет на среднюю по размерам сенсацию.

ну в чем то она уже стерта, потому что варианты это всего лишь иерархии классов с одним родителем, ну теперь можно одинаково матчить и то и другое. Я попробовал в своем проекте провести такую модернизацию, где то это сильно сократило код, правда от большой вложенности без слова where уже не видно где начинаются вложенные классы, в принципе проблема привычки, при это в каких то местах также для удобства понимания можно применять синтаксис с where.
Re: Паттерн матчинг классов без where
От: Ziaw Россия  
Дата: 08.01.12 11:56
Оценка:
Здравствуйте, CodingUnit, Вы писали:

Не использовать ли для этого оператор инициализации? Всем, кто им пользуется код будет понятен.

CU>
CU> match (obj)
CU> {
CU>   | Test() <- { field = f } => f
CU> }
CU>


Хотя, конечно, две стрелки в разные стороны совсем не радуют мое чувство прекрасного.
Re[2]: Паттерн матчинг классов без where
От: Аноним  
Дата: 08.01.12 13:37
Оценка:
Z>Не использовать ли для этого оператор инициализации? Всем, кто им пользуется код будет понятен.
это получится "шило на мыло".
Z>Хотя, конечно, две стрелки в разные стороны совсем не радуют мое чувство прекрасного.
мое тоже
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.