Паттерн матчинг классов без 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[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[5]: Паттерн матчинг классов без where
От: Ziaw Россия  
Дата: 09.01.12 12:19
Оценка: 1 (1)
Здравствуйте, CodingUnit, Вы писали:

Z>>Конечно же where надо менять. Мне оно не нравится примерно по тем же причинам: найдено быстрое и костыльное решение, неплохо выглядящее лишь на первый взгляд. Добавлено ключевое слово к when/with к которым и так новичкам привыкнуть непросто.


CU>ну предложи что лучше, какой синтаксис был бы логичнее


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

от ошибок в голове ничем не застрахуешь. если же писать правильно — проблем не будет.
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
От: 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>Хотя, конечно, две стрелки в разные стороны совсем не радуют мое чувство прекрасного.
мое тоже
Re[2]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 08.01.12 20:34
Оценка:
Здравствуйте, Ziaw, Вы писали:

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


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


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

| Test(field = f) => f


или даже

| Test(f) => f

если поле одно, а тот синтаксис конструктор паттерн и не потянет, хотя вообще какой то другой синтаксис сделать совсем не просто, для where сделано свое PExpr.Where тип в аст, чтобы что то здесь расширять я боюсь придется править и лексер и парсер и дерево и все остальное. Синтаксис Test(field = f) просто живет на существующем синтаксисе, а распознавание на уровне типизации, где раньше был блок что только вариант опции могут работать с таким синтаксисом, теперь уже class, interface, variant. Изменения уже в мастере так что можно тестировать.

Z>Хотя, конечно, две стрелки в разные стороны совсем не радуют мое чувство прекрасного.

согласен
Re[2]: Паттерн матчинг классов без where
От: IT Россия linq2db.com
Дата: 08.01.12 23:15
Оценка:
Здравствуйте, Ziaw, Вы писали:

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


Зачем? Предложенный синтаксис более чем понятен и максимально компактен.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Паттерн матчинг классов без where
От: _Claus_  
Дата: 08.01.12 23:17
Оценка:
я немного потестил изменение — все нравится.
вот странность есть:

class u
  public h: int = 5
  
module Program 
      
  Main() : void
    
    def g : object = u()        
    
    match(g)
      | u(h) => _ = h
      | _ => {}


error : `u' cannot be variant option, since it starts with lowercase letter

невнятная ошибка, необоснованная, как по мне. особенно учитывая расширение.
Re[3]: Паттерн матчинг классов без where
От: _Claus_  
Дата: 08.01.12 23:33
Оценка:
а это вроде должно работать. вроде ты был согласный. или нет?

class U
  public j: int = 5
  public h: int = 5
  
module Program 
      
  Main() : void
  
    def g : object = U()        
    
    match(g)
      | U(h) => _ = h
      | _ => {}


error: pattern matches 1 values, while the type `U' has 2 fields

для классов и паттернов приоритетным разумно было сделать сопоставление по именам.
а если не проходит — тогда ряд.

оно и более компактно, и человечней.

PS каждый пост требует вводить имя и пароль. вдруг. как починить?
Re[4]: Паттерн матчинг классов без where
От: Аноним  
Дата: 09.01.12 00:02
Оценка:
вот даже совместимость можно сделать полную с написанным, — вместо этой ошибки проверить, можно ли завязать поля по именам,
и если нет, тогда ее и показывать. так никому плохо не будет, а некоторым хорошо станет
Re[3]: Паттерн матчинг классов без where
От: Ziaw Россия  
Дата: 09.01.12 04:20
Оценка:
Здравствуйте, IT, Вы писали:

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


IT>Зачем? Предложенный синтаксис более чем понятен и максимально компактен.


Тем, что предложен синтаксис вызова конструктора. При этом такого конструктора у типа нет. Вдобавок, матч по конструктору сейчас однозначно ассоциирован с матчем по варианту, зачем терять эту однозначность?

Язык должен быть максимально логичен. В данном случае логикой является легкость реализации и количество символов. Мне это не нравится.

Конечно же where надо менять. Мне оно не нравится примерно по тем же причинам: найдено быстрое и костыльное решение, неплохо выглядящее лишь на первый взгляд. Добавлено ключевое слово к when/with к которым и так новичкам привыкнуть непросто.

P.S. Кстати, те небольшие правки, которыми можно добиться нужного поведения, тестировались на сложных, многовложенных матчах?
Re[4]: Паттерн матчинг классов без where
От: IT Россия linq2db.com
Дата: 09.01.12 06:36
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Тем, что предложен синтаксис вызова конструктора. При этом такого конструктора у типа нет. Вдобавок, матч по конструктору сейчас однозначно ассоциирован с матчем по варианту, зачем терять эту однозначность?


Мне этот синтаксис больше напоминает инициализатор, чем конструктор. А если конструктор, то с параметрами по умолчанию для всех полей класса.
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Паттерн матчинг классов без where
От: Ziaw Россия  
Дата: 09.01.12 10:11
Оценка:
Здравствуйте, IT, Вы писали:

Z>>Тем, что предложен синтаксис вызова конструктора. При этом такого конструктора у типа нет. Вдобавок, матч по конструктору сейчас однозначно ассоциирован с матчем по варианту, зачем терять эту однозначность?


IT>Мне этот синтаксис больше напоминает инициализатор, чем конструктор. А если конструктор, то с параметрами по умолчанию для всех полей класса.


Инициализатор это <-. Зачем его напоминать, если он уже есть?
Re[4]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 09.01.12 11:18
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>
_C_>class u
_C_>  public h: int = 5
  
_C_>module Program 
      
_C_>  Main() : void
    
_C_>    def g : object = u()        
    
_C_>    match(g)
_C_>      | u(h) => _ = h
_C_>      | _ => {}
_C_>


_C_>error : `u' cannot be variant option, since it starts with lowercase letter


_C_>невнятная ошибка, необоснованная, как по мне. особенно учитывая расширение.


да это остатки от кода работающего с вариантными опциями, надо подумать что с этим делать, дело в том что когда начинается с большой это явно тип, в ПМ приходится различать что мы матчим типы или переменные, в принципе в o(a, b), o — не может быть переменной, а (a, b) могут быть и тем и другим. Я посмотрю что можно будет сделать в компиляторе.
Re[4]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 09.01.12 11:22
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>а это вроде должно работать. вроде ты был согласный. или нет?


_C_> match(g)

_C_> | U(h) => _ = h
_C_> | _ => {}

_C_>error: pattern matches 1 values, while the type `U' has 2 fields


это правильно, в ПМ паттерн конструктор должен матчить все поля, или опускать с помощью _, иначе это неверно, мы следуем традиции функциональных языков, пока кардинальные изменения в ПМ не собираемся вводить, но стоит пообсуждать.

_C_>PS каждый пост требует вводить имя и пароль. вдруг. как починить?

не знаю, у меня есть такое, но firefox запомнил пароль, и когда ввожу ник, он пароль подставляет
Re[4]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 09.01.12 11:30
Оценка:
Здравствуйте, Ziaw, Вы писали:

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


Z>Тем, что предложен синтаксис вызова конструктора. При этом такого конструктора у типа нет. Вдобавок, матч по конструктору сейчас однозначно ассоциирован с матчем по варианту, зачем терять эту однозначность?


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

Z>Язык должен быть максимально логичен. В данном случае логикой является легкость реализации и количество символов. Мне это не нравится.

Z>Конечно же where надо менять. Мне оно не нравится примерно по тем же причинам: найдено быстрое и костыльное решение, неплохо выглядящее лишь на первый взгляд. Добавлено ключевое слово к when/with к которым и так новичкам привыкнуть непросто.

ну предложи что лучше, какой синтаксис был бы логичнее

Z>P.S. Кстати, те небольшие правки, которыми можно добиться нужного поведения, тестировались на сложных, многовложенных матчах?


да, в своей библиотеке я заменил все where на такой синтаксис, там есть и большие вложенные паттерны, пока все работает
Re[5]: Паттерн матчинг классов без where
От: Аноним  
Дата: 09.01.12 12:35
Оценка:
CU>это правильно, в ПМ паттерн конструктор должен матчить все поля, или опускать с помощью _, иначе это неверно, мы следуем традиции функциональных языков, пока кардинальные изменения в ПМ не собираемся вводить, но стоит пообсуждать.

можно не нарушать традицию, но вместо этой ошибки делать предложенный анализ на возможное сопоставление по именам полей.
более интеллектуальный компилятор — хорошо. меньше кода — тоже хорошо.
Re[6]: Паттерн матчинг классов без where
От: IT Россия linq2db.com
Дата: 09.01.12 14:20
Оценка:
Здравствуйте, Ziaw, Вы писали:

IT>>Мне этот синтаксис больше напоминает инициализатор, чем конструктор. А если конструктор, то с параметрами по умолчанию для всех полей класса.

Z>Инициализатор это <-. Зачем его напоминать, если он уже есть?

<- такое же уродство как и where и является следствием недостаточной расширяемости языка. Надеюсь в следующей версии это будет исправлено.
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 09.01.12 15:27
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Так я же предложил. Если для паттерн для варианта по синтаксису совпадает с его конструктором, то паттерн для объекта должен синтаксически совпадать с выражением его инициализации (точнее его подмножеством, имеющим смысл в виде паттерна).


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


| Test where (field = f) => 
| Test() <- {field = f} => // на один символ короче where (не то за что стоит бороться)
| Test() <- {f, f2} => // как определить конструктор? такого синтаксиса нет
| Test(field = f)       =>


ну так он и совпадает:

| Test(f)       =>


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

variant A
{
  | B
    {
      field : int;

      public this(a : int, b : int) {}
    }
 | 
}

    def test = A.B(1);
    match (test)
    {
      | A.B(1, 2) => ... // не скомпилируется
    }


и хотя есть конструктор этого объекта с двумя параметрами он это не воспримет, а просто берет все поля которые есть в объекте, точно также работает и с объектом, когда надо можно пользоваться рекорд паттерном, когда надо конструктором. Пока не видно твердых аргументов, имеющих основания, пока просто старая привычка пользоваться старым синтаксисом, просто стоит попробовать новый синтаксис и он выглядит стройно и логично. Если ты говоришь о логике ПМ, то она пока такая же как была раньше для where, так что если мы действуем не как в теории ПМ, если это действительно не правильно, имея конструкторы не матчить по ним, то об этом стоит поговорить отдельно как фич реквест, пока новый синтаксис это минимальное приближение к тому что было, не затрагивая основы.
Re[5]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 09.01.12 21:52
Оценка:
Здравствуйте, CodingUnit, Вы писали:

_C_>>error : `u' cannot be variant option, since it starts with lowercase letter


_C_>>невнятная ошибка, необоснованная, как по мне. особенно учитывая расширение.


CU>да это остатки от кода работающего с вариантными опциями, надо подумать что с этим делать, дело в том что когда начинается с большой это явно тип, в ПМ приходится различать что мы матчим типы или переменные, в принципе в o(a, b), o — не может быть переменной, а (a, b) могут быть и тем и другим. Я посмотрю что можно будет сделать в компиляторе.


Я реализовал эту функцию, теперь o(a, b) должен матчится правильно, введена следующая эвристика:


| o       => // всегда матчит переменную, потому что с маленькой буквы
| o()     => // всегда матчит объект, потому что даны скобки
| o(a, b) => // тоже объект, потому что скобки и значения конструктора
| O       => // всегда объект потому что с большой буквы
| o as t  => // o - объект, потому что находится с левой стороны as
| t is o  => // o - объект, потому что справа is


по идее не должно быть конфликтов, компилятор собирается в двух проходах, но могут быть скрытые недочеты, просьба протестить на разных вариантах, сами изменения сейчас пока не в мастере, а в ветке NowhereMatch главного репозитария, надеюсь разберетесь как ее выкачать
Re[6]: Паттерн матчинг классов без where
От: _Claus_  
Дата: 10.01.12 13:34
Оценка:
CU>Я реализовал эту функцию, теперь o(a, b) должен матчится правильно, введена следующая эвристика:


CU>
CU>| o       => // всегда матчит переменную, потому что с маленькой буквы
CU>| o()     => // всегда матчит объект, потому что даны скобки
CU>| o(a, b) => // тоже объект, потому что скобки и значения конструктора
CU>| O       => // всегда объект потому что с большой буквы
CU>| o as t  => // o - объект, потому что находится с левой стороны as
CU>| t is o  => // o - объект, потому что справа is
CU>


матчит переменную это присваивает или сравнивает? и если сравнивает то как — по ссылке или по равенству?
вообще эта зависимость от регистра сильно смущает и сбивает с толку. MS стиль это понятно, но тут языковая логика вяжется на стиль.
это не радует ваабще.

CU>по идее не должно быть конфликтов, компилятор собирается в двух проходах, но могут быть скрытые недочеты, просьба протестить на разных вариантах, сами изменения сейчас пока не в мастере, а в ветке NowhereMatch главного репозитария, надеюсь разберетесь как ее выкачать


не мог бы, уважаемый CodingUnit, просто выложить бинарик(и), чтобы желающие тестить просто в bin закинули, не парясь с вытяжкой
и компиляцией. сэкономил бы время всем.
Re[6]: Паттерн матчинг классов без where
От: Аноним  
Дата: 10.01.12 14:25
Оценка:
CU>Я реализовал эту функцию, теперь o(a, b) должен матчится правильно, введена следующая эвристика:


CU>
CU>| o       => // всегда матчит переменную, потому что с маленькой буквы
CU>| o()     => // всегда матчит объект, потому что даны скобки
CU>| o(a, b) => // тоже объект, потому что скобки и значения конструктора
CU>| O       => // всегда объект потому что с большой буквы
CU>| o as t  => // o - объект, потому что находится с левой стороны as
CU>| t is o  => // o - объект, потому что справа is

CU>


можешь привести пример, когда без различения регистра получается пухлый код?
или некрасивый?
Re[7]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 10.01.12 14:28
Оценка:
Здравствуйте, _Claus_, Вы писали:


CU>>
CU>>| o       => // всегда матчит переменную, потому что с маленькой буквы
CU>>| o()     => // всегда матчит объект, потому что даны скобки
CU>>| o(a, b) => // тоже объект, потому что скобки и значения конструктора
CU>>| O       => // всегда объект потому что с большой буквы
CU>>| o as t  => // o - объект, потому что находится с левой стороны as
CU>>| t is o  => // o - объект, потому что справа is
CU>>


_C_>матчит переменную это присваивает или сравнивает? и если сравнивает то как — по ссылке или по равенству?

_C_>вообще эта зависимость от регистра сильно смущает и сбивает с толку. MS стиль это понятно, но тут языковая логика вяжется на стиль.
_C_>это не радует ваабще.

эвристика нужна, она и до этого была, просто строже, маленькие буквы не могли использоваться в качестве имени типов, но я показал что это возможно. Ты наверное не знал до этого ПМ, расскажу как было и как стало:

| o       => // матчит переменную и раньше и теперь просто присваивает значение объекта переменной
| o()     => // раньше из за регистра никак не хотел распознавать тип, присваивал переменной o, теперь матчит тип o
| o(a, b) => // раньше как ты писал он писал что вариант опция требуется, теперь полноценно распознает тип, потому что указаны скобки и значения 
| O       => // всегда тип потому что с большой буквы, большие буквы не пишутся для переменных здесь, хотя помоему там по старому определяется эвристика для поиска типа с данным именем
| o as t  => // o - тип, потому что находится с левой стороны as, раньше маленькой буквы не воспринимал и нуждался в большой букве для типа
| t is o  => // o - тип, потому что справа is, сейчас разрешает маленькую букву


_C_>не мог бы, уважаемый CodingUnit, просто выложить бинарик(и), чтобы желающие тестить просто в bin закинули, не парясь с вытяжкой

_C_>и компиляцией. сэкономил бы время всем.
если бы я знал как это делается, никогда этим не занимался, я думаю люди подкованные в компиляторе сами разберутся
Re[7]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 10.01.12 14:47
Оценка:
Здравствуйте, Аноним, Вы писали:


CU>>Я реализовал эту функцию, теперь o(a, b) должен матчится правильно, введена следующая эвристика:



CU>>
CU>>| o       => // всегда матчит переменную, потому что с маленькой буквы
CU>>| o()     => // всегда матчит объект, потому что даны скобки
CU>>| o(a, b) => // тоже объект, потому что скобки и значения конструктора
CU>>| O       => // всегда объект потому что с большой буквы
CU>>| o as t  => // o - объект, потому что находится с левой стороны as
CU>>| t is o  => // o - объект, потому что справа is

CU>>


А>можешь привести пример, когда без различения регистра получается пухлый код?

А>или некрасивый?

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


| o(a, b)  =>
| t as var => 
| var is t =>


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

старая эвристика:
| o       => // всегда просто создает переменную, потому что с маленькой буквы
| o()     => // матчит переменную все равно
| o(a, b) => // отказывается матчить потому что маленькая буква
| O(a, b) => // a и b переменные, O - тип
| O(A, B) => // паттерн конструктор A и B типы, если типов нет или не совместимы с полями, ошибка
| O       => // тип, если типа нет ошибка

так что я внес только корректность в существующую систему и расширил функциональность, старый синтаксис по прежнему работает, в верхнем описании слово объект может быть неверно истолковано, под этим стоит понимать тип
Re[8]: Паттерн матчинг классов без where
От: Аноним  
Дата: 10.01.12 15:09
Оценка:
CU>эвристика нужна, она и до этого была, просто строже, маленькие буквы не могли использоваться в качестве имени типов, но я показал что это возможно. Ты наверное не знал до этого ПМ, расскажу как было и как стало:

я просто честно не понимаю, зачем нужна чувствительность к регистру. пример, когда это необходимо?
или это для удобства компилятору?

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


у тебя бинарик(и) с патчем. сворачиваешь в архив и вывешиваешь на файлообменник или github.
я не подкован в компиляторе. но потестировать мог бы.
Re[9]: Паттерн матчинг классов без where
От: _Claus_  
Дата: 10.01.12 15:15
Оценка:
А>у тебя бинарик(и) с патчем. сворачиваешь в архив и вывешиваешь на файлообменник или github.
А>я не подкован в компиляторе. но потестировать мог бы.

или влей в мастер. патч ведь ничего не рвет. тогда подберу утреннюю сборку.
Re[9]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 10.01.12 15:29
Оценка:
Здравствуйте, Аноним, Вы писали:

А>я просто честно не понимаю, зачем нужна чувствительность к регистру. пример, когда это необходимо?

А>или это для удобства компилятору?

да это нужно чтобы разрешить неоднозначность того что мы хотим от него, например такие записи:


| o       => // что мы хотим присвоить значение переменной или проверить что переменная имеет этот тип?
| o(a, b) => // что мы хотим присвоить поля объекта типа o, переменным a и b или же хотим проверить что типы полей совпадают с типами a и b?
| O       => // опять переменная или тип?

так вот для разрешения этого и введен синтаксис изначально на проверку согласно регистру, переменные должны быть маленькими, вариантные опции для чего изначально предназначался ПМ, начинаются с больших букв. Сейчас думая над введением удобного синтаксиса для классов, подумали как можно решить неоднозначность если у нас типы с маленькой буквы. Главное здесь правило: что если есть скобки то это только типы, и мы их матчим, если хотим распознать тип с маленькой буквы то пишем его со скобками, в остальном правила остаются прежние

А>у тебя бинарик(и) с патчем. сворачиваешь в архив и вывешиваешь на файлообменник или github.

А>я не подкован в компиляторе. но потестировать мог бы.
тут не просто, там и интеграцию надо собранную инсталлировать, я посмотрю может соберу инсталлятор
Re[10]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 10.01.12 15:30
Оценка:
Здравствуйте, _Claus_, Вы писали:

А>>у тебя бинарик(и) с патчем. сворачиваешь в архив и вывешиваешь на файлообменник или github.

А>>я не подкован в компиляторе. но потестировать мог бы.

_C_>или влей в мастер. патч ведь ничего не рвет. тогда подберу утреннюю сборку.


я без согласования с Владом ничего не делаю, надо подумать над всем этим и сделать тесты, как решим так и зальем в мастер
Re[10]: Паттерн матчинг классов без where
От: Аноним  
Дата: 10.01.12 16:02
Оценка:
CU>[nemerle]
CU>| o => // что мы хотим присвоить значение переменной или проверить что переменная имеет этот тип?
CU>| o(a, b) => // что мы хотим присвоить поля объекта типа o, переменным a и b или же хотим проверить что типы полей совпадают с типами a и b?
CU>| O => // опять переменная или тип?

т. е. вся петрушка из-за того, что вы разрешаете объявить переменную с именем класса? ход неоднозначный, как при любви Влада к строгости
он это терпит? я бы, если мне будет позволено советовать, от такой фичи избавился. все станет простым и понятным.

CU>тут не просто, там и интеграцию надо собранную инсталлировать, я посмотрю может соберу инсталлятор

насколько я помню соглашения, номер сборки роли не играет. а версия в мастере и твоей ветке одинаковая. т. е. твой compiler.dll должен
работать без доп. движений. могу проверить.
Re[11]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 10.01.12 16:14
Оценка:
Здравствуйте, Аноним, Вы писали:

CU>>[nemerle]

CU>>| o => // что мы хотим присвоить значение переменной или проверить что переменная имеет этот тип?
CU>>| o(a, b) => // что мы хотим присвоить поля объекта типа o, переменным a и b или же хотим проверить что типы полей совпадают с типами a и b?
CU>>| O => // опять переменная или тип?

А>т. е. вся петрушка из-за того, что вы разрешаете объявить переменную с именем класса?

вы все понимаете неверно, все это не для того чтобы объявить переменную с именем класса, я вам разъяснил как работала эвристика до этого, если не понимаете суть вопроса, стоит ли вступать в дискуссию? Единственное для чего нужны изменения это поддержка маленьких букв для типов t, в паттернах типа t(a, b) для классов, без ошибок которые давал компилятор. Остальное остается по старому.

А> он это терпит? я бы, если мне будет позволено советовать, от такой фичи избавился. все станет простым и понятным.

мы еще обсуждаем это, а вам надо сначала разобраться в синтаксисе Немерле чтобы давать какие то советы

CU>>тут не просто, там и интеграцию надо собранную инсталлировать, я посмотрю может соберу инсталлятор

А>насколько я помню соглашения, номер сборки роли не играет. а версия в мастере и твоей ветке одинаковая.
версия не одинаковая потому что внесены изменения, и одна сборка ничего не даст, интеграция тоже должна быть собрана на компиляторе
Re[12]: Паттерн матчинг классов без where
От: Аноним  
Дата: 10.01.12 16:30
Оценка:
CU>>>[nemerle]
CU>>>| o => // что мы хотим присвоить значение переменной или проверить что переменная имеет этот тип?
CU>>>| o(a, b) => // что мы хотим присвоить поля объекта типа o, переменным a и b или же хотим проверить что типы полей совпадают с типами a и b?
CU>>>| O => // опять переменная или тип?

А>>т. е. вся петрушка из-за того, что вы разрешаете объявить переменную с именем класса?

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

я искренне пытаюсь понять. то что написано выше иначе у меня в голове не складывается.
берем утверждение
CU>>>| o => // что мы хотим присвоить значение переменной или проверить что переменная имеет этот тип?

если o — это известный тип, то ессно(!) анализ типа.
если o — не тип, ессно это переменная и присвоение ей же.
и далее то же самое. где я чего не понял? и какое другое понимание может быть?
Re[13]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 10.01.12 16:36
Оценка:
Здравствуйте, Аноним, Вы писали:

А>я искренне пытаюсь понять. то что написано выше иначе у меня в голове не складывается.

А>берем утверждение
CU>>>>| o => // что мы хотим присвоить значение переменной или проверить что переменная имеет этот тип?

А>если o — это известный тип, то ессно(!) анализ типа.

А>если o — не тип, ессно это переменная и присвоение ей же.
А>и далее то же самое. где я чего не понял? и какое другое понимание может быть?

ну так вот логика в компиляторе работает так, что запись с начальной маленькой буквы всегда трактуется как переменная в паттерне | o =>
это не я придумал, но это так уже много лет, и далее тоже самое, а записи с большой буквы ВСЕГДА трактуются как типы.
Я решил немного расширить только для записи o(a, b) где o — явно что тип, потому что объявили выражение конструктора, ну и также для | t as var =>
и | var is t =>, где явно что работает с типами. Просто сделать компилятор несколько умнее, что тут непонятного?
Re[14]: Паттерн матчинг классов без where
От: Аноним  
Дата: 10.01.12 16:51
Оценка:
CU>и | var is t =>, где явно что работает с типами. Просто сделать компилятор несколько умнее, что тут непонятного?

понятно, что нелогично. то, что идет за | однозначно вычисляется как тип или переменная без всякого злого колдунства.
а там хотите верьте, хотите нет.
Re[15]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 10.01.12 17:03
Оценка:
Здравствуйте, Аноним, Вы писали:

А>понятно, что нелогично. то, что идет за | однозначно вычисляется как тип или переменная без всякого злого колдунства.

А>а там хотите верьте, хотите нет.

ну так было всегда, злое колдунство тут ненужно, все должно быть предсказуемо. Возможно это самое простое и легко трактуемое решение, когда один паттерн в разных местах программы означает одно и тоже, закладывать сюда типизатор, открыт ли тип или нет, даст каждый раз разные результаты и может дать очень непонятные ошибки. Но мы стараемся безболезненно для людей и компилятора, сделать его умнее, также на основе существующего синтаксиса.
Re[16]: Паттерн матчинг классов без where
От: Аноним  
Дата: 10.01.12 17:25
Оценка:
CU>ну так было всегда, злое колдунство тут ненужно, все должно быть предсказуемо. Возможно это самое простое и легко трактуемое решение, когда один паттерн в разных местах программы означает одно и тоже, закладывать сюда типизатор, открыт ли тип или нет, даст каждый раз разные результаты и может дать очень непонятные ошибки.

пример непонятной ошибки? я ж вот и хочу понять, как она может возникнуть. спать не могу

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


синтаксис хороший, и патч хороший, до идеала рукой подать.
Re[17]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 10.01.12 17:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>пример непонятной ошибки? я ж вот и хочу понять, как она может возникнуть. спать не могу


ну ты хочешь весь ПМ сделать на внешней логике, что за запись, есть ли тип такой или нет. Я уже сказал что если типы не открыты, а такое часто бывает то матчиться будет совсем не то что нам нужно, а будут связываться переменные и в ветке:

| A       =>


вы получите ошибку 1) A переменная не использована 2) все что ниже не используется, потому что переменная перекрыла его, вообщем неоднозначности только увеличиваются. Совсем другая эвристика паттернов, это другая тема, тут я уверен у спецов найдутся аргументы почему так не было сделано до сих пор, я углубляться в это не хочу. Вопрос остается открытым, Влад высказался что вроде все выглядит разумным, но пока не смотрел сам код, я скоро выложу сборку, заканчиваться она будет на слово LowerLetterTypesMatch можно качать и пробовать на существующем или новом коде.
Re[10]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 10.01.12 18:02
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>или влей в мастер. патч ведь ничего не рвет. тогда подберу утреннюю сборку.


выложил файл https://github.com/downloads/rsdn/nemerle/NemerleSetup-net-4.0-v1.1.468.0-experimental-LowerLetterTypesMatch.msi

можешь посмотреть существующие примеры, синтаксис без where, а также классы с маленькой буквы
Re[5]: Паттерн матчинг классов без where
От: calc.exe Россия  
Дата: 10.01.12 18:09
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>ну предложи что лучше, какой синтаксис был бы логичнее


Предлагаю заменить длинные ключевые слова на одиночные спецсимволы. В примере топикстартера будет так:

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
 }
}


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

with  - #
where - @
<-    - with


В случае ПМ будут краткие односимвольные инструкции. Для понимания их должно хватить. Кроме того высвобождается with для инициализаторов (Snippets] Обновленный макрос with
Автор: catbert
Дата: 13.12.10
) — очень красиво смотрится.
.
Re[18]: Паттерн матчинг классов без where
От: Аноним  
Дата: 10.01.12 18:19
Оценка:
CU>ну ты хочешь весь ПМ сделать на внешней логике, что за запись, есть ли тип такой или нет. Я уже сказал что если типы не открыты, а такое часто бывает

вот как такое бывает? хоть макросом генерим, все равно на финише понятно, тип это или нет. вот в этом затык у меня.
если б вообразить, что такое возможно, то да, а иначе это хомут. я так представляю, что в AST до типов сразу закладывается ограничение. а если так, то проблема там, эту связь надо считать позже. если по логике. F# обходится без такой казуистики. другие наверняка тоже. чем H хуже?
Re[7]: Паттерн матчинг классов без where
От: Ziaw Россия  
Дата: 11.01.12 05:48
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>и хотя есть конструктор этого объекта с двумя параметрами он это не воспримет, а просто берет все поля которые есть в объекте,


это тоже кривость правда я не знаю, что тут можно изменить.

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


Убедил. Это менее криво чем сейчас, а до Н2 все равно ничего не исправить. Лучшее враг хорошего.
Re[6]: Паттерн матчинг классов без where
От: Ziaw Россия  
Дата: 11.01.12 07:19
Оценка:
Здравствуйте, calc.exe, Вы писали:

CE>В случае ПМ будут краткие односимвольные инструкции. Для понимания их должно хватить. Кроме того высвобождается with для инициализаторов (Snippets] Обновленный макрос with
Автор: catbert
Дата: 13.12.10
) — очень красиво смотрится.


with будет доступен с новым парсером в nemerle2. Переходить ради него на символы мне совсем не нравятся.
Re[19]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 11.01.12 19:11
Оценка:
Здравствуйте, Аноним, Вы писали:


CU>>ну ты хочешь весь ПМ сделать на внешней логике, что за запись, есть ли тип такой или нет. Я уже сказал что если типы не открыты, а такое часто бывает


А>вот как такое бывает? хоть макросом генерим, все равно на финише понятно, тип это или нет. вот в этом затык у меня.

А>если б вообразить, что такое возможно, то да, а иначе это хомут. я так представляю, что в AST до типов сразу закладывается ограничение. а если так, то проблема там, эту связь надо считать позже. если по логике. F# обходится без такой казуистики. другие наверняка тоже. чем H хуже?

если генерим макросом, каким образом он узнает что это тип? если открыт тип то это тип, если нет то переменная, получается можно корректно сгенерить две макросборки, с разным поведением, вот это багодром тот еще, потом разбирайся что не так в твоей макросборке, что логика не соответствует. Для таких вещей сначала стоит разбираться в общей теории функциональных языков, потом знать сам язык, иметь опыт использования и говорить что могло быть лучше, а пока чистая теория и дискутировать тут сложно. Я не буду углубляться в тему почему так работает ПМ в Немерле, тема у нас другая, если хочешь размышлять на тему почему работает ПМ так, то заводи тему.
Re[6]: Паттерн матчинг классов без where
От: CodingUnit Россия  
Дата: 11.01.12 19:18
Оценка:
Здравствуйте, calc.exe, Вы писали:

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


CU>>ну предложи что лучше, какой синтаксис был бы логичнее


CE>Предлагаю заменить длинные ключевые слова на одиночные спецсимволы. В примере топикстартера будет так:


CE>Не для Немерле, а для перспективного языка будет следующая серия замен:


CE>
CE>with  - #
CE>where - @
CE><-    - with
CE>


А чем существующий синтаксис не нравится?

| A(field = f) =>
| A(f)         =>


Если мы для каждой операции будем производить новый символ, то язык будет похож на хаскель (с очень высоким порогом вхождения), или один из эзотерических языков. Такие конструкции понятны автору их, но непонятны для нового человека, который пришел из известных языков. Как мечты на тему: здорово было бы иметь такой синтаксис, годиться, но не более.
Re[7]: Паттерн матчинг классов без where
От: calc.exe Россия  
Дата: 12.01.12 14:05
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Если мы для каждой операции будем производить новый символ, то язык будет похож на хаскель (с очень высоким порогом вхождения), или один из эзотерических языков. Такие конструкции понятны автору их, но непонятны для нового человека, который пришел из известных языков. Как мечты на тему: здорово было бы иметь такой синтаксис, годиться, но не более.


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