Re: match, всего лишь предупреждение??
От: nikov США http://www.linkedin.com/in/nikov
Дата: 17.09.13 17:23
Оценка: 2 (1)
Здравствуйте, artelk, Вы писали:

A>Имхо, если Nemerle позиционируется, как строготипизированный язык, то тут должна быть ошибка.



a = b / c;


Здесь должна быть ошибка компиляции если отсутствует явная проверка на (c != 0)?
Re[2]: match, всего лишь предупреждение??
От: artelk  
Дата: 17.09.13 17:27
Оценка:
Здравствуйте, nikov, Вы писали:

N>
N>a = b / c;
N>


N>Здесь должна быть ошибка компиляции если отсутствует явная проверка на (c != 0)?

Злой ты, nikov.
Подумаю...
Re[3]: match, всего лишь предупреждение??
От: _NN_ www.nemerleweb.com
Дата: 17.09.13 17:31
Оценка:
Здравствуйте, artelk, Вы писали:

Так надо дальше идти.
Тут должна быть ошибка компиляции ? Ведь может быть случай b = Int32.MaxValue, c = Int32.MaxValue

checked
{
  a = b + c;
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: match, всего лишь предупреждение??
От: artelk  
Дата: 17.09.13 21:26
Оценка:
Здравствуйте, artelk, Вы писали:

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


N>>
N>>a = b / c;
N>>

A>Подумаю...

Ошибка компиляции, при неполном матче, решает не проблему "ой, забыл добавить вхождение" при написании самого матча, а проблему "добавили позже новый элемент варианта, все скомпилировалось без ошибок, но упало в рантантайме".
Надеюсь, понятно выразился.
Re[4]: match, всего лишь предупреждение??
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.09.13 00:37
Оценка:
Здравствуйте, artelk, Вы писали:

A>
A> | _ => throw //пусть компилятор сам сочинит текст сообщения
A>


Мы обычно пишем так:
| _ => assert(false)

если охота, можно вторым параметром и более внятный текст задать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: match, всего лишь предупреждение??
От: CodingUnit Россия  
Дата: 18.09.13 09:53
Оценка:
Здравствуйте, artelk, Вы писали:

A>Ошибка компиляции, при неполном матче, решает не проблему "ой, забыл добавить вхождение" при написании самого матча, а проблему "добавили позже новый элемент варианта, все скомпилировалось без ошибок, но упало в рантантайме".

A>Надеюсь, понятно выразился.

Обычно варнинга хватает, и при компиляции будет выявлено несоответствие. Но то что компилятор не умеет определить что матч упадет 100% это да, хотя информация о связывании типов есть.
Re[7]: match, всего лишь предупреждение??
От: hi_octane Беларусь  
Дата: 19.09.13 00:48
Оценка:
_NN>Может все же не так плохо если в match требовать явно вариант "не подошло" в определенных случаях ?

Сейчас есть warning времени компиляции и возможная ошибка в рантайме. А в случае | _ => всё тоже самое, только без warning'a
Re[8]: match, всего лишь предупреждение??
От: _NN_ www.nemerleweb.com
Дата: 19.09.13 15:17
Оценка: +1
Здравствуйте, hi_octane, Вы писали:

_NN>>Может все же не так плохо если в match требовать явно вариант "не подошло" в определенных случаях ?


_>Сейчас есть warning времени компиляции и возможная ошибка в рантайме. А в случае | _ => всё тоже самое, только без warning'a


Ну если программист сам пишет код вида try { .. } catch { /* ничего не делай */ } , то тут ничем не поможешь.
Другое дело, что это надо писать явно.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[9]: match, всего лишь предупреждение??
От: hi_octane Беларусь  
Дата: 19.09.13 15:48
Оценка:
_NN>Ну если программист сам пишет код вида try { .. } catch { /* ничего не делай */ } , то тут ничем не поможешь.
_NN>Другое дело, что это надо писать явно.

Представь насколько сложнее станет поиск ошибок, если у каждого try потребовать обязательный catch { }. Тоже самое и с требованием | _ => в match.
Re[10]: match, всего лишь предупреждение??
От: _NN_ www.nemerleweb.com
Дата: 19.09.13 18:40
Оценка:
Здравствуйте, hi_octane, Вы писали:

_NN>>Ну если программист сам пишет код вида try { .. } catch { /* ничего не делай */ } , то тут ничем не поможешь.

_NN>>Другое дело, что это надо писать явно.

_>Представь насколько сложнее станет поиск ошибок, если у каждого try потребовать обязательный catch { }. Тоже самое и с требованием | _ => в match.


Между прочим в C++ всегда требуется catch, а в Java/C# либо catch, либо finally.
И ничего, все инструменты работают хорошо и находят ошибки.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[8]: match, всего лишь предупреждение??
От: artelk  
Дата: 20.09.13 06:48
Оценка:
Здравствуйте, hi_octane, Вы писали:

_NN>>Может все же не так плохо если в match требовать явно вариант "не подошло" в определенных случаях ?


_>Сейчас есть warning времени компиляции и возможная ошибка в рантайме. А в случае | _ => всё тоже самое, только без warning'a


Ок, давай рассмотрим минусы и... минусы.

Минусы в случае, если будет ошибка компиляции:

1. Если будут ошибки компиляции, то разработчику придется делать матчи полными. Иногда он будет бездумно вставлять | _ => throw, чтобы тупо подавить ошибку компиляции.
2. Иногда компилятору будет недостаточно мозгов, чтобы определить, что матч полный. Например, из за хитрых when или случаев типа такого:
variant Num { |Zero | One | Two | Three }

Sum(n1 : Num, n2 : Num) : Num
{
    match(n1)
    {
        | Zero => n2
        | _ =>
                match(n2)
                {
                    | Zero => n1
                    | _ =>
                            match(n1, n2) // warning : matching is not exhaustive, example unmatched value: (Num.One, Zero)
                            {
                                | (One, One) => Num.Two()
                                | (One, Two)
                                | (Two, One) => Num.Three()
                                | (Two, Two)
                                | (_, Three)
                                | (Three, _) => throw OverflowException()
                            }
                }
    }
}

И люди будут вставлять | _ => throw со всеми вытекающими.


Минус в случае, если будет только предупреждение:

1. В проекте множество матчей. На часть из них компилятор ругается, показывая warning. На часть из этих предупреждений мы отреагировали, сделав матчи полными. Часть из них проигнорировали, т.к. уверены, что в рантайме ошибки не выскочит.
Итого получилось, например, 10 предупреждений, которых мы проигнорировали. Добывили в какой-то вариант новый элемент, появилось 11-е предупреждение. Никто, естественно, не заметил. Ошибка в рантайме.

Что-то мне подсказывает, что минус второго случая (с учетом вероятности возникновения) заметно превышает минусы первого (с учетом вероятности возникновения).

PS
Конечно, если делать так:
variant FooBar { |Foo | Bar }

match(fooBar)
{
 | Foo => WriteLine("Foo")
 | _ => //я имею ввиду Bar, но мне лень писать
       WriteLine("Bar")
}

, то при добавлении в FooBar компилятор ничем не поможет в обоих случаях.
Re[9]: match, всего лишь предупреждение??
От: hi_octane Беларусь  
Дата: 20.09.13 08:04
Оценка:
A>1. Если будут ошибки компиляции, то разработчику придется делать матчи полными. Иногда он будет бездумно вставлять | _ => throw, чтобы тупо подавить ошибку компиляции.

Ага. И впоследствии, как только появится ещё одно значение типа variant или enum, это будет создавать ему проблему. И думаешь разработчик себя будет винить, или компилятор которые сначала заставил его этот throw написать, а потом никаких средств для поиска этих мест до запуска не дал?

A>2. Иногда компилятору будет недостаточно мозгов, чтобы определить, что матч полный. Например, из за хитрых when или случаев типа такого:

A>И люди будут вставлять | _ => throw со всеми вытекающими.

В реальном проекте тривиальных матчей, считанные единицы. Сейчас throw пишет компилятор, и вдобавок пишет предупреждение. Ты предлагаешь переложить половину этой работы на человека, а вторую половину выкинуть. А задача компилятора вообще-то человека максимально разгрузить

A>Минус в случае, если будет только предупреждение:


A>1. В проекте множество матчей. На часть из них компилятор ругается, показывая warning. На часть из этих предупреждений мы отреагировали, сделав матчи полными. Часть из них проигнорировали, т.к. уверены, что в рантайме ошибки не выскочит.

A>Итого получилось, например, 10 предупреждений, которых мы проигнорировали. Добывили в какой-то вариант новый элемент, появилось 11-е предупреждение. Никто, естественно, не заметил. Ошибка в рантайме.
warning as error на продакшн спасут разработчика от позора. А #pragma disable N#### от ложных срабатываний в тех местах где проверено мин нет.

Но когда предупреждение всё-таки выскочит — место ошибки можно будет найти до того как она вылезет в рантайм. В случае же с обязательным | _ => это вообще никак невозможно сделать до запуска.

A>Что-то мне подсказывает, что минус второго случая (с учетом вероятности возникновения) заметно превышает минусы первого (с учетом вероятности возникновения).


Чем вероятность измеряешь?
Re[10]: match, всего лишь предупреждение??
От: artelk  
Дата: 26.09.13 16:49
Оценка:
Здравствуйте, hi_octane, Вы писали:

Я почему такой злой был — у меня велосипеда небыло. Я тут междусобойчик готовил про ADT и pattern matching (плюс ненавязчивая реклама Nemerle ).
Хотел сказать такую фразу: "в отличие от switch/case по типам, в матче компилятор следит, чтобы был полный набор вхождений — т.е. как в паттерне Визитор".

Вобщем, согласен, что всегда и везде требовать полный матч не очень хорошо. Однако иногда хочется сказать компилятору: "вот тут должен быть полный матч, следи за этим".
Предлагаю разрешить эту проблему на уровне синтаксиса — сделать макрос matchex (от слова exhaustive) с таким поведением:
1. конвертация предупреждения в ошибку
2. запрет "_ => ..."

На сколько сложно это сделать?

PS Доклад прошел на отлично, всем понравилось!
Re[11]: match, всего лишь предупреждение??
От: _NN_ www.nemerleweb.com
Дата: 26.09.13 17:21
Оценка:
Здравствуйте, artelk, Вы писали:

A>Я почему такой злой был — у меня велосипеда небыло. Я тут междусобойчик готовил про ADT и pattern matching (плюс ненавязчивая реклама Nemerle ).

A>Хотел сказать такую фразу: "в отличие от switch/case по типам, в матче компилятор следит, чтобы был полный набор вхождений — т.е. как в паттерне Визитор".

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

A>Предлагаю разрешить эту проблему на уровне синтаксиса — сделать макрос matchex (от слова exhaustive) с таким поведением:
A>1. конвертация предупреждения в ошибку
A>2. запрет "_ => ..."

A>На сколько сложно это сделать?


Звучит хорошим компромисом.
Синтаксис то сделать несложно, см. regex match
Да и поведение тоже, сканнируем все сопоставления и делаем что хотим.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[11]: match, всего лишь предупреждение??
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.09.13 20:14
Оценка: +1
Здравствуйте, artelk, Вы писали:

A>Предлагаю разрешить эту проблему на уровне синтаксиса — сделать макрос matchex (от слова exhaustive) с таким поведением:

A>1. конвертация предупреждения в ошибку

Это и так делается. Запрещаешь ворнинги и разрешаешь те что хочешь оставить.

A>2. запрет "_ => ..."


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

A>На сколько сложно это сделать?


Сделать элементарно. Но незачем.

A>PS Доклад прошел на отлично, всем понравилось!


Надо было записывать и выкладывать куда-нить.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: match, всего лишь предупреждение??
От: STDray http://stdray.livejournal.com
Дата: 26.09.13 20:16
Оценка: +1
A>Я почему такой злой был — у меня велосипеда небыло. Я тут междусобойчик готовил про ADT и pattern matching (плюс ненавязчивая реклама Nemerle ).
A>Хотел сказать такую фразу: "в отличие от switch/case по типам, в матче компилятор следит, чтобы был полный набор вхождений — т.е. как в паттерне Визитор".
Я полагаю, что главное отличие сопоставления с образцом — это структурная декомпозиция и возможность связывать идентификаторы. В любом случае, у вас было полное право сказать эту фразу, поскольку компилятор действительно следит и информирует.

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

Он и так следит, просто не надо его игнорировать. Лично для ошибка компиляции при неполном матче не стала бы проблемой. Но, если посмотреть на ближайший родственный язык — F#. В нем подход абсолютно аналогичный. Например
type Test= Foo | Bar
let test = Foo
let x = match test with
         | Bar -> true

приводит к
 предупреждение FS0025: Незавершенный шаблон соответствует данному выражению. К примеру, значение "Foo" может указывать на случай, не покрытый шаблоном(ами).

Я полагаю, что в OСaml тоже самое. Видимо, практика применения показывает, что предупреждения в данной ситуации удобней.

A>Предлагаю разрешить эту проблему на уровне синтаксиса — сделать макрос matchex (от слова exhaustive) с таким поведением:

A>1. конвертация предупреждения в ошибку
A>2. запрет "_ => ..."
Я считаю, это организационный вопрос. Как уже писали выше, надо лишь трактовать warning'и как ошибку. Например по рецепту hardcase'a
Автор: hardcase
Дата: 17.09.13
. Плодить на ровном месте (непонятно кем поддерживаемый) дубликат одного из ключевых элементов языка — явный оверкилл, вне зависимости от сложности реализации. Тут же не лисперы собрались, чтобы ради косметических отличий пилить все с нуля в своей песочнице.
Re[12]: match, всего лишь предупреждение??
От: artelk  
Дата: 26.09.13 21:51
Оценка:
Здравствуйте, VladD2, Вы писали:

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


A>>Предлагаю разрешить эту проблему на уровне синтаксиса — сделать макрос matchex (от слова exhaustive) с таким поведением:

A>>1. конвертация предупреждения в ошибку

VD>Это и так делается. Запрещаешь ворнинги и разрешаешь те что хочешь оставить.


Кажется ты не понял. Макрос matchex — это не макроаттрибут уровня сборки, который во всем проекте заставляет делать матчи полными и при этом запрещает _=>...
Это вид матча, применяемый в конкретном месте — там, где нам нужно.
Вот делаешь ты, например, транслятор одной структуры данных в другую (или тупо специальный сериализатор какого-то варианта, например). И тебе нужно, чтобы, если в будущем автор этого варианта что-то еще добавит, транслятор не компилировался бы до тех пор, пока ты его не обновишь.

A>>2. запрет "_ => ..."


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


См. выше.
Re[13]: match, всего лишь предупреждение??
От: Аноним  
Дата: 27.09.13 06:37
Оценка: -1
Здравствуйте, artelk, Вы писали:

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


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


A>>>Предлагаю разрешить эту проблему на уровне синтаксиса — сделать макрос matchex (от слова exhaustive) с таким поведением:


Тогда уж лучше сделать
variant hhh
{
[RequestMatch]|Foot
|Bar
}

def t=hhh.Bar
match()
{
| Bar => ....
| _ =>
}
// error Foot request match


def t=hhh.Bar
match()
{
| Foot => ....

}
// warning match not full


[RequestMatch]
variant hhh
{
|Foot
|Bar
}
Re[13]: match, всего лишь предупреждение??
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.09.13 19:28
Оценка:
Здравствуйте, artelk, Вы писали:

A>Кажется ты не понял. Макрос matchex — это не макроаттрибут уровня сборки, который во всем проекте заставляет делать матчи полными и при этом запрещает _=>...

A>Это вид матча, применяемый в конкретном месте — там, где нам нужно.

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

A>Вот делаешь ты, например, транслятор одной структуры данных в другую (или тупо специальный сериализатор какого-то варианта, например). И тебе нужно, чтобы, если в будущем автор этого варианта что-то еще добавит, транслятор не компилировался бы до тех пор, пока ты его не обновишь.


Я обычно думаю нужно ли делать "| _ =>" в маче и не делаю его, если можно просто перечислить оставшиеся элементы. Я "| _ =>" только там, где есть осмысленная обработка. В крайнем случае я ставлю assert3(false) в "| _ =>".

Ну, и на ворнинги всегда обращаю внимание и не иду дальше если они есть.

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