Re[11]: Действительно ли ML языки хороши в компиляторописани
От: Mamut Швеция http://dmitriid.com
Дата: 25.04.08 07:05
Оценка:
M>>Приведенный вариант просто вернет true или false. Мой вариант вернет список не прошедших валидацию полей и всех ошибок, которые с ними связаны (правила валидации могут передаваться списком).
SR>А, ну надо было тогда в условие задачи, добавить, что правила проверки должны задаваться более-менее декларативно.


Ну, во многом в этом и состоит смысл ПМа — описывать ребуемое декларативно



M>>При этом функция остается общей и может использоваться для любых полей любой веб-формы. Без ПМа здесь только один выход — создание некоего движка правил. Но это — совсем неудобно

SR>А у вас стало быть не движок правил?

Да, действительно, я неправильно выразился. Он у меня тоже есть Но описывается он гораздо понятнее


SR>
SR>    public void main() {
SR>        Form form = new Form();
SR>        form.put("login", "name");
SR>        form.put("password", "123");
SR>        form.put("password_repeated", "123");
SR>        form.put("email", "name@domain.com");
SR>        form.put("born_year", "1980");
        
SR>        Object[] rules = new Object[] {
SR>            "login", "length", parameters(4, 16),
SR>            "password", "length", parameters(4, 16),
SR>            "password", "=", parameters("password_repeated"),
SR>            "email", "email", parameters(),
SR>            "born_year", "<", parameters("1990")
SR>        };
        
SR>        check(form, rules);
SR>    }

SR>    // О боже мой, кажется, я реализовал сопоставление с образцом для списка в Java!
SR>    // Этого не может быть, наверное я сплю.
SR>    private void check(Form form, Object[] rules) {
SR>        for (int index = 0; index < rules.length; index += 3) {
SR>            String field = rules[index].toString();
SR>            String rule = rules[index+1].toString();
SR>            Object[] parameters = (Object[])rules[index+2];
        
SR>            check(form, field, rule, parameters);
SR>        }
SR>    }

SR>    private void check(Form form, String field, String rule, Object[] parameters) {
SR>        if (rule.equals("length")) { 
SR>            int min = (Integer)parameters[0]; 
SR>            int max = (Integer)parameters[1];
SR>            checkLength(form.get(field), min, max);
SR>        }
SR>        ...
SR>        // остальной код в той же мере тривиален
SR>    }
SR>



Правильно. И такой код придется писать каждый раз заново для любой более-менее тривиальной смены структуры передаваемых данных.

То есть. Для исхдного примера
Автор: z00n
Дата: 14.12.07
придется реализовывать метод equals для term, для моего примера — целую отдельную функцию, эмулирующую сопоставление с образом, для менее тривиального примера
Автор: z00n
Дата: 24.04.08
придется еще как-нибудь изворачиваться. А ПМ позвлит все задачи решить декларативно. Это не магическая пуля, конечно, писать все равно придется Но каждый раз это будет легко и — главное! — одинаково.

Просто if поможет только сравнить значения. ПМ позволит наглядно сравнить и структуру и значения.
... << RSDN@Home 1.2.0 alpha 4 rev. 1084>>


dmitriid.comGitHubLinkedIn
Re[12]: Действительно ли ML языки хороши в компиляторописани
От: SmbdRsdn  
Дата: 25.04.08 10:21
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Правильно. И такой код придется писать каждый раз заново для любой более-менее тривиальной смены структуры передаваемых данных.

Какой такой? Цикл по списку? Так это аналог рекурсии по списку, которую тоже придется писать каждый раз.

M>То есть. Для исхдного примера
Автор: z00n
Дата: 14.12.07
придется реализовывать метод equals для term,

Метод equals легко автоматизируется, также как создание getter, setter и конструктора по полям в eclipse.
Я уж молчу про поддержку со стороны компилятора.

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

Странно, стороннику ФП не нравятся отдельные функции. Ну раз не нравятся объедините в одну большую.

M>для менее тривиального примера
Автор: z00n
Дата: 24.04.08
придется еще как-нибудь изворачиваться.

Пример не более тривиален чем исходный.

M>А ПМ позвлит все задачи решить декларативно. Это не магическая пуля, конечно, писать все равно придется Но каждый раз это будет легко и — главное! — одинаково.

Так все задачи или не магическая пуля?

M>Просто if поможет только сравнить значения. ПМ позволит наглядно сравнить и структуру и значения.

Какая структура в вашем-то примере?
Re[13]: Действительно ли ML языки хороши в компиляторописани
От: Mamut Швеция http://dmitriid.com
Дата: 25.04.08 10:47
Оценка:
M>>Правильно. И такой код придется писать каждый раз заново для любой более-менее тривиальной смены структуры передаваемых данных.
SR>Какой такой? Цикл по списку? Так это аналог рекурсии по списку, которую тоже придется писать каждый раз.

При этом с ПМ рекрсия по списку тривиальна


M>>То есть. Для исхдного примера
Автор: z00n
Дата: 14.12.07
придется реализовывать метод equals для term,

SR>Метод equals легко автоматизируется, также как создание getter, setter и конструктора по полям в eclipse.

{ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
      http:request(...
      
{ok, {_, _, Body}} = http:request(...


{ok, {_, 200, _}, _, _} = http:request(


Какой-какой автоматизированый equals мне поможет это написать?


SR>Я уж молчу про поддержку со стороны компилятора.


Я тоже умолчу

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

SR>Странно, стороннику ФП не нравятся отдельные функции. Ну раз не нравятся объедините в одну большую.

В какую ону большую? В Tom что ли?

M>>для менее тривиального примера
Автор: z00n
Дата: 24.04.08
придется еще как-нибудь изворачиваться.

SR>Пример не более тривиален чем исходный.

     | {i,FLT,{'Break',s}} :: z -> return best(emit(sb,s),n,k+#s,z)
     | {i,BRK,{'Break',_}} :: z -> return best(nl(sb,i),i,i,z)
     | {i,FLT,{'Group',x}} :: z -> return best(sb,w,k,{i,FLT,x}::z)


это, я так понимаю, предлагается переписать в виде
if(term.m == FLT && term.cell.type == 'Break' && term.cell.data == s)
{
}
else if(term.m == BRK && term.cell.type == 'Break')
{
}
else if(term.m == FLT && term.cell.type == 'Group' && term.cell.data == x)
{
}


?

M>>А ПМ позвлит все задачи решить декларативно. Это не магическая пуля, конечно, писать все равно придется Но каждый раз это будет легко и — главное! — одинаково.

SR>Так все задачи или не магическая пуля?

Любая, где требуется разбор структур (данных). Сопоставление с образцом — это унифицированый подход к разбору произвольных структур(данных)


M>>Просто if поможет только сравнить значения. ПМ позволит наглядно сравнить и структуру и значения.

SR>Какая структура в вашем-то примере?

rules_list         = [fields_and_rules]
fields_and_rules   = [field_rules]
field_rules        = {field} | {field, Rules}
Rules              = Rule | [Rule]
Rule               = function | OperatorRule | FunctionRule
OperatorRule       = {Operator, value} | (Operator, field)
Operator           = '=' | '/=' | '<' | '=<' | '>' | '>='
FunctionRule       = {function, value} | {function, field}


Как придумал, так и записал. Более того, реализация сильно похожа на то же самое

Но у меня, безусловно, простой пример. А есть посложнее. Типа того, что я привел в самом начале.
... << RSDN@Home 1.2.0 alpha 4 rev. 1084>>


dmitriid.comGitHubLinkedIn
Re[4]: Паттерн-матчинг - отличие от обычных конструкций
От: z00n  
Дата: 25.04.08 10:50
Оценка:
Здравствуйте, GlebZ, Вы писали:
GZ>Sestoft — это вот этот?
Да, это он.
Re[14]: Действительно ли ML языки хороши в компиляторописани
От: SmbdRsdn  
Дата: 25.04.08 11:32
Оценка:
Здравствуйте, Mamut, Вы писали:

M>При этом с ПМ рекрсия по списку тривиальна

Неужели считаете, что цикл нетривиален?

M>
M>{ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
M>      http:request(...
      
M>{ok, {_, _, Body}} = http:request(...


M>{ok, {_, 200, _}, _, _} = http:request(
M>


M>Какой-какой автоматизированый equals мне поможет это написать?

Как-то определили, что мне знаком erlang?

Потом, предлагаю, не отвлекаться каждый раз на свои структуры.
Как повелось сторонниками ФП демонстрировать преимущества сопоставления с образцом на основе структур для условного калькулятора так предлагаю и продолжать.
Нет, если конечно считаете, что у вас какая-то принципиально иная структура, которая в калькулятор не укладывается.

SR>>Странно, стороннику ФП не нравятся отдельные функции. Ну раз не нравятся объедините в одну большую.


M>В какую ону большую? В Tom что ли?

Гм, по вашему одна большая функция не разбитая на малые превращается сразу в язык программирования Tom. Интересная способ рассуждений.

SR>>Пример не более тривиален чем исходный.


M>
M>     | {i,FLT,{'Break',s}} :: z -> return best(emit(sb,s),n,k+#s,z)
M>     | {i,BRK,{'Break',_}} :: z -> return best(nl(sb,i),i,i,z)
M>     | {i,FLT,{'Group',x}} :: z -> return best(sb,w,k,{i,FLT,x}::z)
M>


M>это, я так понимаю, предлагается переписать в виде

M>
M>if(term.m == FLT && term.cell.type == 'Break' && term.cell.data == s)
M>{
M>}
M>else if(term.m == BRK && term.cell.type == 'Break')
M>{
M>}
M>else if(term.m == FLT && term.cell.type == 'Group' && term.cell.data == x)
M>{
M>}
M>


M>?

Нет. Вспомните, я и код такого вида не приводил.

M>Любая, где требуется разбор структур (данных). Сопоставление с образцом — это унифицированый подход к разбору произвольных структур(данных)

Это вы хватили, насчет произвольных структур. Вот например разработчики Tom'а заявляли, что в Tom возможно сопоставлять с образцом более сложные структуры чем в Scala, но все равно не произвольные.

M>>>Просто if поможет только сравнить значения. ПМ позволит наглядно сравнить и структуру и значения.

SR>>Какая структура в вашем-то примере?

M>
M>rules_list         = [fields_and_rules]
M>fields_and_rules   = [field_rules]
M>field_rules        = {field} | {field, Rules}
M>Rules              = Rule | [Rule]
M>Rule               = function | OperatorRule | FunctionRule
M>OperatorRule       = {Operator, value} | (Operator, field)
M>Operator           = '=' | '/=' | '<' | '=<' | '>' | '>='
M>FunctionRule       = {function, value} | {function, field}
M>


M>Как придумал, так и записал.


M>Более того, реализация сильно похожа на то же самое

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

M>Но у меня, безусловно, простой пример. А есть посложнее. Типа того, что я привел в самом начале.

Про посложнее это понятно. Однако считается, что преимущество сопоставления с образцом видно уже на простых иерархиях.
А у вас странно звучит — да на простой иерархии особой разницы не видно, но если ее навернуть на порядок, тогда преимущество будет очевидно.
Re[15]: Действительно ли ML языки хороши в компиляторописани
От: Mamut Швеция http://dmitriid.com
Дата: 25.04.08 12:05
Оценка:
M>>При этом с ПМ рекрсия по списку тривиальна
SR>Неужели считаете, что цикл нетривиален?

Он менее "читаем", чем ПМ

M>>
M>>{ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
M>>      http:request(...
      
M>>{ok, {_, _, Body}} = http:request(...


M>>{ok, {_, 200, _}, _, _} = http:request(
M>>


M>>Какой-какой автоматизированый equals мне поможет это написать?

SR>Как-то определили, что мне знаком erlang?

Ну, мы ж про паттерн-матчинг говорим? А тут вполне себе паттерн-матчинг. Вполне понятный даже незнакомому с Эрлангом

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

SR>Как повелось сторонниками ФП демонстрировать преимущества сопоставления с образцом на основе структур для условного калькулятора так предлагаю и продолжать.
SR>Нет, если конечно считаете, что у вас какая-то принципиально иная структура, которая в калькулятор не укладывается.

Ну, в исходном
Автор: z00n
Дата: 14.12.07
сообщении был приведен и пример кода их компилятора

Вообще-то на одном только изолированом примере показать/доказать что-то сложно.
Надо привести два-три примера, где ПМ позволяет использовать одинаковый подход к решению проблемы, а язык без ПМа требует каждый раз нового подхода (здесь
Автор: SmbdRsdn
Дата: 22.04.08
— реализация метода equals, здесь
Автор: SmbdRsdn
Дата: 24.04.08
— функции с применением if-ов). А ПМ в итоге позволяет читать код, как книгу, без необходимости пробираться сквозь дебри if-ов и попыток понять, что же автор хотел сказать тем или иным циклом

SR>>>Странно, стороннику ФП не нравятся отдельные функции. Ну раз не нравятся объедините в одну большую.


M>>В какую ону большую? В Tom что ли?

SR>Гм, по вашему одна большая функция не разбитая на малые превращается сразу в язык программирования Tom. Интересная способ рассуждений.

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


SR>>>Пример не более тривиален чем исходный.


M>>
M>>     | {i,FLT,{'Break',s}} :: z -> return best(emit(sb,s),n,k+#s,z)
M>>     | {i,BRK,{'Break',_}} :: z -> return best(nl(sb,i),i,i,z)
M>>     | {i,FLT,{'Group',x}} :: z -> return best(sb,w,k,{i,FLT,x}::z)
M>>


M>>это, я так понимаю, предлагается переписать в виде

M>>
M>>if(term.m == FLT && term.cell.type == 'Break' && term.cell.data == s)
M>>{
M>>}
M>>else if(term.m == BRK && term.cell.type == 'Break')
M>>{
M>>}
M>>else if(term.m == FLT && term.cell.type == 'Group' && term.cell.data == x)
M>>{
M>>}
M>>


M>>?

SR>Нет. Вспомните, я и код такого вида не приводил.

Ну, для калькулятора был код с term.equals, для проверки веб-=форм был код с if'ами. Для этого конкретного примера term.equals не подойдет, потому что нам не всегда все значения нужны. Так что if-ы

M>>Любая, где требуется разбор структур (данных). Сопоставление с образцом — это унифицированый подход к разбору произвольных структур(данных)

SR>Это вы хватили, насчет произвольных структур. Вот например разработчики Tom'а заявляли, что в Tom возможно сопоставлять с образцом более сложные структуры чем в Scala, но все равно не произвольные.

Это, возможно, ограничения языков и/или JVM.

M>>Более того, реализация сильно похожа на то же самое

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

Это мои кривые руки.


M>>Но у меня, безусловно, простой пример. А есть посложнее. Типа того, что я привел в самом начале.

SR>Про посложнее это понятно. Однако считается, что преимущество сопоставления с образцом видно уже на простых иерархиях.
SR>А у вас странно звучит — да на простой иерархии особой разницы не видно, но если ее навернуть на порядок, тогда преимущество будет очевидно.

На простых просто как раз и начинается- а вот тут я могу if'ом, а вот тут — функцией...


Хотя... Опять же. ПМ предлагает одинаковый подход к решению всех приведенных здесь примеров. Который еще и очень легко читается.
... << RSDN@Home 1.2.0 alpha 4 rev. 1084>>


dmitriid.comGitHubLinkedIn
Re[7]: Действительно ли ML языки хороши в компиляторописани
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 25.04.08 13:29
Оценка: 30 (1) +1
SmbdRsdn,

LCR>>А решать вопрос "сбрасывать или нет" каждый раз должен программист?

SR>Нет. Сбрасывать не зачем.
Тогда приведи наконец этот мега-equals (или matches, неважно). Хотя бы его poc.

SR>Я, конечно, понимаю, отчего возникло непонимание.

SR>Мне было лень писать что-то вроде:
SR>
SR>abstract class Term {};
SR>class Num extends Term {};
SR>class Var extends Term {}

SR>@Exhaustive
SR>Term simplify(Term term) {
SR>  if (term instanceof Num)
SR>     return ...;
SR>  if (term instanceof Var)
SR>     return ...;
SR>  // отсутствует "This method must return a result of type Term."
SR>}
SR>


SR>для показа как может выглядеть проверка на полноту при сопоставлении с образцом в Java.

Это очень хорошо, что ты снизошёл до более предметного разговора, только вот здесь ничего проверить невозможно, потому что у компилятора нет доказательства того, что у Term только 2 потомка. Ведь действительно, мы при запуске можем добавить ещё пару джарок, в которых может определено ещё сколько угодно подклассов Term. В Скале такой проблемы нет, потому что класс помечен sealed.

Попытка номер два?

LCR>>Специально помеченные if-ы

SR>Не отдельные if, а отдельный метод. Помеченный аннотацией. Что является законным способом добавления мета-данных в Java.
Как ты собираешься отделять "паттерн-матчинговские" if-ы от обычных, в которых объекты просто сравниваются между собой?

LCR>>(которые, заметим, работают совсем не так как выглядят!)

SR>Работают так же как и выглядят. То есть делают тоже, что и написано. Просто быстрее.
Да вот оказывается нет, не так.
      _Term x = new _Term();
      if (term.equals(new Mul(new Num(1), x))) return x.value;

Я ожидаю здесь создания композиции из трёх объектов и сравнения (по-видимому глубокого) с объектом term. А оказывается:
1. никакого создания объектов не происходит
2. equals вовсе никакое не сравнение, он не симметричен (уж не знаю, что там с транзитивностью), возвращает значения через параметры (то есть метод имеет побочные эффекты!), и вообще это не метод, а просто символическое имя, которое этот препроцессор понимает по-своему.
3. класс _Term вообще какой-то волшебный. Он одновременно является подклассом всех классов входящих в юнион-тип, потому что класс может принимать в качестве параметра не абстрактный Term, а какие-то конкретные термы, и вайлдкард может матчить как раз конкретный терм:
...
case class Yo(n: Add) extends Term

def simplify(term: Term) = term match {
  ...
  case Yo(x) => x
  case _ => term
}

4. код неявно предполагает, что объекты типов Term, Num, Mul, Add и т.п. иммутабельны, а конструкторы не имеют побочных эффектов. Но это полная туфта, в яве ты нигде не можешь потребовать того, чтобы объект был иммутабельным, и задача определения наличия значимых побочных эффектов в общем случае неразрешима.

Короче, ты просто пытаешься старым именем назвать новую сущность. Код стал более понятным? Щаз. Лично меня ты ввёл в конкретное заблуждение. Я сначала так и подумал: товарищ создаёт дерево на трёх элементах, заводит локальную переменную, передаёт в функцию equals — фигня какая-то. Зачем это делать, если можно этого не делать?

SR>К тому же в Java сообществе имеется много материалов, о том как написать свой equals и для каких целей это может потребоваться.

Да, я всё жду от тебя твоего мега-equals. Не забудь про рефлексивность, симметричность, транзитивность и неналичие побочных эффектов (это чтобы порядок вызова нескольких equals не имел значения).

SR>Готового производительного решения и нет. А преимущества в отсутствии необходимости перехода на другой язык с сильно измененным синтаксисом только для возможности сопоставления с образцом.

Ничего хорошего в этом я не вижу в упор. Синтаксис должен подчёркивать главное и всячески помогать в программировании, а не смешивать разные сущности в одной ступе а потом тщательно толочь чтобы у программиста сформировалась равномерно распределённая каша в голове... Syntax does matter.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[16]: Действительно ли ML языки хороши в компиляторописани
От: SmbdRsdn  
Дата: 25.04.08 19:15
Оценка: -2 :)
Здравствуйте, Mamut, Вы писали:

M>>>При этом с ПМ рекрсия по списку тривиальна

SR>>Неужели считаете, что цикл нетривиален?

M>Он менее "читаем", чем ПМ

Цикл это цикл, причем тут сопоставление с образцом? Сопоставление происходит уже внутри цикла.

M>>>
M>>>{ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
M>>>      http:request(...
      
M>>>{ok, {_, _, Body}} = http:request(...


M>>>{ok, {_, 200, _}, _, _} = http:request(
M>>>


M>>>Какой-какой автоматизированый equals мне поможет это написать?

SR>>Как-то определили, что мне знаком erlang?

M>Ну, мы ж про паттерн-матчинг говорим? А тут вполне себе паттерн-матчинг. Вполне понятный даже незнакомому с Эрлангом

Ладно попробую, хотя смысл ok слабо понятен. Какое-то ключевое слово в erlang, видимо. Так что пока без ok.
    private Response getResponse() {
        return new Response(list (
            list ( "HTTP/1.1", 200, "OK" ),
            list (
                "Content-Type: text/html; charset=UTF-8", 
                "Content-Length: 0" ),
            list ( "" )
        ));        
    }
    
    public void parse() {
        Response response = getResponse();
        
        Any _ = new Any();
        Match version = new Match(), responsePhrase = new Match(), headers = new Match(), body = new Match();        
        if (response.matches( list ( list (version, 200, responsePhrase), headers, body ))) {
            System.out.println(responsePhrase.value);
        }
        if (response.matches( list (_, _, body))) {
            System.out.println(body.value);
        }        
        if (response.matches( list ( list (_, 200, _), headers, body))) {
            System.out.println(headers.value);
        }
    }


M>Ну, в исходном
Автор: z00n
Дата: 14.12.07
сообщении был приведен и пример кода их компилятора

Какого компилятора? Была приведена только функция упрощения выражения. Потому что Одерски показывал только сопоставление с образцом.
Я уже приводил ссылку на полную версию программы на Scala.
Кстати код на Java, который был приведен в исходном сообщении, вроде бы тоже не руками написан, а с применением спец-компилятора Java

M>Вообще-то на одном только изолированом примере показать/доказать что-то сложно.

M>Надо привести два-три примера, где ПМ позволяет использовать одинаковый подход к решению проблемы, а язык без ПМа требует каждый раз нового подхода (здесь
Автор: SmbdRsdn
Дата: 22.04.08
— реализация метода equals, здесь
Автор: SmbdRsdn
Дата: 24.04.08
— функции с применением if-ов).


M>А ПМ в итоге позволяет читать код, как книгу, без необходимости пробираться сквозь дебри if-ов и попыток понять, что же автор хотел сказать тем или иным циклом

Какие дебри? Даже if'а в if'e нет. Замените if на case и вот практически код на erlang. Или там дебри case'ов?

SR>>Гм, по вашему одна большая функция не разбитая на малые превращается сразу в язык программирования Tom. Интересная способ рассуждений.

M>Или в нечто ему подобное. Потому что мы же хотим некую общую функцию, которая поможет разбирать образцы не только на одном примере разбора веб-форм
Списки — простой случай, повторяю в который раз. Неужели сомневаетесь, что можно написать обобщенную функцию разбора?


SR>>Нет. Вспомните, я и код такого вида не приводил.


M>Ну, для калькулятора был код с term.equals, для проверки веб-=форм был код с if'ами. Для этого конкретного примера term.equals не подойдет, потому что нам не всегда все значения нужны. Так что if-ы

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

M>Это, возможно, ограничения языков и/или JVM.

В Nemerle тоже сопоставляются только варианты.

M>На простых просто как раз и начинается- а вот тут я могу if'ом, а вот тут — функцией...

M>Хотя... Опять же. ПМ предлагает одинаковый подход к решению всех приведенных здесь примеров. Который еще и очень легко читается.
не вижу различий, еще раз считайте что if это case.
Re[8]: Действительно ли ML языки хороши в компиляторописани
От: SmbdRsdn  
Дата: 25.04.08 20:09
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>SmbdRsdn,


LCR>Тогда приведи наконец этот мега-equals (или matches, неважно). Хотя бы его poc.

Это в почти стандартный equals для сравнения не по ссылке а по содержанию.
class A {
  public Class1 field1;
  public Class2 field2;

  public boolean equals(Object object) {
    return object instanceof A && equals((A)object);
  }
  
  private boolean equals(A a) {
     return field1.equals(a.field1) && field2.equals(a.field2);
  }
}

Конечно реальный equals отличается еще поддержкой связывания.

LCR>Это очень хорошо, что ты снизошёл до более предметного разговора, только вот здесь ничего проверить невозможно, потому что у компилятора нет доказательства того, что у Term только 2 потомка. Ведь действительно, мы при запуске можем добавить ещё пару джарок, в которых может определено ещё сколько угодно подклассов Term. В Скале такой проблемы нет, потому что класс помечен sealed.

Не забывайте, что Скала не может выйти за пределы JVM.
LCR>Попытка номер два?
Надуманная проблема, тем не менее хорошо, что она была озвучена. Решение — конструктор базового класса видимый только из пакета, потомки sealed.

LCR>>>Специально помеченные if-ы

SR>>Не отдельные if, а отдельный метод. Помеченный аннотацией. Что является законным способом добавления мета-данных в Java.
LCR>Как ты собираешься отделять "паттерн-матчинговские" if-ы от обычных, в которых объекты просто сравниваются между собой?
Зачем? Вполне разумно вынести сопоставление с образцом в отдельный метод, в котором не будет if'ов вида (if (object.equals(new Object()))) не представляющих сопоставление с образцом.


SR>>Работают так же как и выглядят. То есть делают тоже, что и написано. Просто быстрее.

LCR>Да вот оказывается нет, не так.
LCR>
LCR>      _Term x = new _Term();
LCR>      if (term.equals(new Mul(new Num(1), x))) return x.value;
LCR>

LCR>Я ожидаю здесь создания композиции из трёх объектов и сравнения (по-видимому глубокого) с объектом term. А оказывается:
LCR>1. никакого создания объектов не происходит
А что тут удивительного? В Java для повышения производительности во время выполнения объект может и не создаваться каждый раз, а браться из пула уже созданных объектов. Даже проще во время компиляции преобразовать образец не в набор if'ов, а в обращение к некоторому пулу образцов, который будет создавать объекты по требованию.
LCR>2. equals вовсе никакое не сравнение, он не симметричен (уж не знаю, что там с транзитивностью),
Симметричность, специально не проверял, но кажется будет симметричен и транзитивен.
LCR>возвращает значения через параметры (то есть метод имеет побочные эффекты!),
Не забывайте, это же Java!
Что еще за требование, что метод не может иметь побочных эффектов?
Может и от оператора присваивания отказаться?
LCR>и вообще это не метод, а просто символическое имя, которое этот препроцессор понимает по-своему.
В каком-то смысле любой метод это символическое имя которое компилятор понимает по своему.
LCR>3. класс _Term вообще какой-то волшебный. Он одновременно является подклассом всех классов входящих в юнион-тип, потому что класс может принимать в качестве параметра не абстрактный Term, а какие-то конкретные термы, и вайлдкард может матчить как раз конкретный терм:
Класс _Term очень простой, его даже можно вывести из его применения.
public class _Term extends Term {
  public Term value;
}

LCR>4. код неявно предполагает, что объекты типов Term, Num, Mul, Add и т.п. иммутабельны, а конструкторы не имеют побочных эффектов.
Из кода не видно, зачем ему это предположение, видимо очень не явно. На Java с Yo можно сопоставлять аналогично предыдущим классам.

LCR>Короче, ты просто пытаешься старым именем назвать новую сущность.

Скорее новым (для Java) именем старую. Equals можно было переопределять давным давно.

LCR>Код стал более понятным? Щаз. Лично меня ты ввёл в конкретное заблуждение.

Ну если так легко ввести в заблуждением кодом вида if (object.equals(new Object())), тогда не знаю.
Видимо надо начинать спрашивать про опыт программирования на Java.

SR>>К тому же в Java сообществе имеется много материалов, о том как написать свой equals и для каких целей это может потребоваться.

LCR>Да, я всё жду от тебя твоего мега-equals. Не забудь про рефлексивность, симметричность, транзитивность и неналичие побочных эффектов (это чтобы порядок вызова нескольких equals не имел значения).

LCR>Ничего хорошего в этом я не вижу в упор. Синтаксис должен подчёркивать главное и всячески помогать в программировании, а не смешивать разные сущности в одной ступе а потом тщательно толочь чтобы у программиста сформировалась равномерно распределённая каша в голове... Syntax does matter.

Ну это поэзия, которая может быть и красивой, но часто неправой. А в реальности имеем синтаксис отличающийся словом new.
Re[17]: Действительно ли ML языки хороши в компиляторописани
От: Mamut Швеция http://dmitriid.com
Дата: 26.04.08 08:13
Оценка:
M>>>>При этом с ПМ рекрсия по списку тривиальна
SR>>>Неужели считаете, что цикл нетривиален?

M>>Он менее "читаем", чем ПМ

SR>Цикл это цикл, причем тут сопоставление с образцом? Сопоставление происходит уже внутри цикла.

match([]) ->
    not_ok.
match([H|T]) ->
    ok.


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

match([{ok, Value}|T]) ->
    ok.
match([что_то_там|T]) ->
    ok.
match([{ok, {{Version, 200, ReasonPhrase}, Headers, Body}}|T]) ->
    %% здесь мы сразу получаем доступ ко всем переменным
    ok.


M>>>>
M>>>>{ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
M>>>>      http:request(...
      
M>>>>{ok, {_, _, Body}} = http:request(...


M>>>>{ok, {_, 200, _}, _, _} = http:request(
M>>>>


M>>>>Какой-какой автоматизированый equals мне поможет это написать?

SR>>>Как-то определили, что мне знаком erlang?

M>>Ну, мы ж про паттерн-матчинг говорим? А тут вполне себе паттерн-матчинг. Вполне понятный даже незнакомому с Эрлангом

SR>Ладно попробую, хотя смысл ok слабо понятен. Какое-то ключевое слово в erlang, видимо. Так что пока без ok.
SR>
SR>    private Response getResponse() {
SR>        return new Response(list (
SR>            list ( "HTTP/1.1", 200, "OK" ),
SR>            list (
SR>                "Content-Type: text/html; charset=UTF-8", 
SR>                "Content-Length: 0" ),
SR>            list ( "" )
SR>        ));        
SR>    }
    
SR>    public void parse() {
SR>        Response response = getResponse();
        
SR>        Any _ = new Any();
SR>        Match version = new Match(), responsePhrase = new Match(), headers = new Match(), body = new Match();        
SR>        if (response.matches( list ( list (version, 200, responsePhrase), headers, body ))) {
SR>            System.out.println(responsePhrase.value);
SR>        }
SR>        if (response.matches( list (_, _, body))) {
SR>            System.out.println(body.value);
SR>        }        
SR>        if (response.matches( list ( list (_, 200, _), headers, body))) {
SR>            System.out.println(headers.value);
SR>        }
SR>    }
SR>


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

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

%% Первый пример, http://rsdn.ru/Forum/Message.aspx?mid=2766871&only=1
%% намеренно сокращен :)

match({0, x}) ->
    0;
match({1, x}) ->
    x;
match({a, b}) ->
    a*b;
    
%% Второй пример, с правилами валидации
%% http://rsdn.ru/Forum/Message.aspx?mid=2927907&only=1
%% Слегка сокращен

match({Field, Rule}) ->
    match_rule(Field, Rule);
match(Field) when is_atom(Field) ->
    field_exists(Field);
    
match_rule(Field, {Func, Value}) ->
  Func(Field, Value);
  
%% третий пример, http://rsdn.ru/Forum/Message.aspx?mid=2927730&only=1

match([]) ->
    ok;
match({i, _, empty}) ->
    ok;
match({i, m, {'Cons', x, y}}) ->
    ok;
    %% и так далее


%% четвертый пример, http://rsdn.ru/Forum/Message.aspx?mid=2929226&only=1

match({ok, {{Version, 200, ReasonPhrase}, Headers, Body}}) ->
    ok;
match({ok, {{_, 404, ReasonPhrase}, _, _}}) ->
    ok;



Я с удовольствием посмотрю на общую функцию match, которая разберется со всеми этими примерами одним махом.



SR>>>Гм, по вашему одна большая функция не разбитая на малые превращается сразу в язык программирования Tom. Интересная способ рассуждений.

M>>Или в нечто ему подобное. Потому что мы же хотим некую общую функцию, которая поможет разбирать образцы не только на одном примере разбора веб-форм
SR>Списки — простой случай, повторяю в который раз. Неужели сомневаетесь, что можно написать обобщенную функцию разбора?


Сомневаюсь. Выше приведено четыре примера, на каждый из которых с нашей стороны был приведен простейший декларативный код с ПМом, а с вашей — четыре разные функции, которые еще и накладывают ограничения на реализацию (например, необходимость реализации метода equals в первом примере)


SR>>>Нет. Вспомните, я и код такого вида не приводил.


M>>Ну, для калькулятора был код с term.equals, для проверки веб-=форм был код с if'ами. Для этого конкретного примера term.equals не подойдет, потому что нам не всегда все значения нужны. Так что if-ы

SR>Если бы вы внимательно посмотрели на код с equals то увидели бы, что там далеко не все значения используются в дальнейшем.

Зачем их тогда упоминать?

M>>Это, возможно, ограничения языков и/или JVM.

SR>В Nemerle тоже сопоставляются только варианты.

M>>На простых просто как раз и начинается- а вот тут я могу if'ом, а вот тут — функцией...

M>>Хотя... Опять же. ПМ предлагает одинаковый подход к решению всех приведенных здесь примеров. Который еще и очень легко читается.
SR>не вижу различий, еще раз считайте что if это case.

и if и case могут проверять только значения. ПМ позвляет проверять и структуру и значения сразу, без какойлибо дополнительной работы со сторноы программиста. В этом — главное и основное отличие
... << RSDN@Home 1.2.0 alpha 4 rev. 1084>>


dmitriid.comGitHubLinkedIn
Re[18]: Действительно ли ML языки хороши в компиляторописани
От: SmbdRsdn  
Дата: 26.04.08 21:46
Оценка: :)
Здравствуйте, Mamut, Вы писали:

M>>>>>При этом с ПМ рекрсия по списку тривиальна

SR>>>>Неужели считаете, что цикл нетривиален?

M>>>Он менее "читаем", чем ПМ

SR>>Цикл это цикл, причем тут сопоставление с образцом? Сопоставление происходит уже внутри цикла.

M>
M>match([]) ->
M>    not_ok.
M>match([H|T]) ->
M>    ok.
M>


M>намного понятнее. Тем более, что мы сразу на месте можем указать, что нам нужно:

Вы не поняли изначально. В вашем коде и моем нет сопоставления цикл — pattern matching. А есть сопоставление цикл — рекурсия.
А нужна она для того, чтобы после разбора начала списка, разобрать хвост списка. Это же стандартная тема сопоставления ФП и ИП.

M>И это называется удобным???


M>На каждый случай писать свою, отдельную, специализированную функцию, заточенную под разбор только данного конкретного случая?

Гм, у вас какое-то преувеличение насчет списков. Эта структура данных известна давным давно, все с ней более менее ясно.
С чего вы взяли, что там отдельная специализированная функция? Там обобщенная. А класс Response всего лишь обертка, которую можно и не заводить.
Я же его завел, потому что мне хотелось иметь инфиксную форму вызова matches.
А так было бы,
boolean matches(Object[] list, Object[] pattern) {
}

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

M>На четырех простейших примерах — это уже четвертая такая функция.

Не четыре, а два и приводилась декларативная форма представления. А как это реализовано внутри не важно, главное, что можно сделать это обобщенно.
Неужели считаете, что в Scala сопоставление со списком и с вариантами это одна функция? Конечно, это может быть и так, но скорее всего их тоже две.

M>ПМ позволяет использовать унифицированый подход к разбору как структуры так и значений:

Сопоставление с образцом в Java позволяет ровно тоже самое.

M>Я с удовольствием посмотрю на общую функцию match, которая разберется со всеми этими примерами одним махом.

M>
M>match({0, x}) ->
M>    0;
M>match({1, x}) ->
M>    x;
M>match({a, b}) ->
M>    a*b;
M>

Match x = new Match();
if (list.matches(0, x))
  return 0;
if (list.matches(1, x))
  return x.value;
Match a = new Match, b = new Match();
if (list.matches(a, b))
  return a.value * b.value;

M>
M>match({Field, Rule}) ->
M>    match_rule(Field, Rule);
M>match(Field) when is_atom(Field) ->
M>    field_exists(Field)
M>match_rule(Field, {Func, Value}) ->
M>  Func(Field, Value);
M>

Match field = new Match(), rule = new Match();
if (list.matches(field, rule)) {
  Match func = new Match(), value = new Match();
  if (rule.value.matches(func, value))
    return func.value(field.value, value.value);
}
if (list.matches(field))
  return fieldExists(field.value);

M>
M>match([]) ->
M>    ok;
M>match({i, _, empty}) ->
M>    ok;
M>match({i, m, {'Cons', x, y}}) ->
M>    ok;
M>

if (list.matches())
  return ok;
Match i = new Match(), empty = new Match();
if (list.matches(i, _, empty))
  return ok;
Match m = new Match(), x = new Match(), y = new Match();
if (list.matches(i, m, list("Cons", x, y)))
  return ok;

M>
M>match({ok, {{Version, 200, ReasonPhrase}, Headers, Body}}) ->
M>    ok;
M>match({ok, {{_, 404, ReasonPhrase}, _, _}}) ->
M>    ok;
M>

Match ok = new Match(), version = new Match(), reasonPhrase = new Match(), headers = new Match(), body = new Match();
if (list.matches(ok, list (version, 200, reasonPhrase), headers, body)
  return ok;
if (list.matches(ok, list (_, 404, reasonPhrase), _, _)
  return ok;


M>Сомневаюсь. Выше приведено четыре примера, на каждый из которых с нашей стороны был приведен простейший декларативный код с ПМом, а с вашей — четыре разные функции, которые еще и накладывают ограничения на реализацию (например, необходимость реализации метода equals в первом примере)


С моей стороны функции, не приводились, а приводился лишь образец для сопоставления.
И случаев относящихся к сопоставление с образцом не четыре, а два. Сопоставление со списком, и сопоставление с вариантами.

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

SR>>Если бы вы внимательно посмотрели на код с equals то увидели бы, что там далеко не все значения используются в дальнейшем.

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

M>и if и case могут проверять только значения. ПМ позвляет проверять и структуру и значения сразу, без какойлибо дополнительной работы со сторноы программиста. В этом — главное и основное отличие

Так же и при сопоставлении с образцом в Java.
Re[19]: Действительно ли ML языки хороши в компиляторописани
От: FR  
Дата: 27.04.08 10:29
Оценка: 1 (1) :)
Здравствуйте, SmbdRsdn, Вы писали:

Вообще классно пишешь, и главное так хитро и тонко, я вот почитал и практическм перестал сомневатся в преимуществах ML образных
Re[20]: Действительно ли ML языки хороши в компиляторописани
От: SmbdRsdn  
Дата: 27.04.08 11:54
Оценка: :)
Здравствуйте, FR, Вы писали:

FR>Вообще классно пишешь, и главное так хитро и тонко, я вот почитал и практическм перестал сомневатся в преимуществах ML образных

Спасибо, за похвалу.
Re[20]: Действительно ли ML языки хороши в компиляторописани
От: WolfHound  
Дата: 27.04.08 13:02
Оценка:
Здравствуйте, FR, Вы писали:

FR>Вообще классно пишешь, и главное так хитро и тонко, я вот почитал и практическм перестал сомневатся в преимуществах ML образных

Давай-давай.
У нас конкурентов меньше будет.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[19]: Действительно ли ML языки хороши в компиляторописани
От: WolfHound  
Дата: 27.04.08 13:02
Оценка: +1
Здравствуйте, SmbdRsdn, Вы писали:

SR>Гм, у вас какое-то преувеличение насчет списков. Эта структура данных известна давным давно, все с ней более менее ясно.

А причем тут вобще списки?

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

Вобще говоря списки это частный случай вариантов.
Не знал?
variant List[T]
{
| Cons { value : T; tail : List[T]; }
| Null
}

А компилятор их просто слегка подсахаривает.

А алгоритм генерации сопоставления с образцом уже не различает списки там или нет.

M>>ПМ позволяет использовать унифицированый подход к разбору как структуры так и значений:

SR>Сопоставление с образцом в Java позволяет ровно тоже самое.
Реализацию такую чтобы я ее не разломал в пыль с первой же попытки в студию.
Про то чтобы оно еще и работало хотябы со скоростью аналога на скале я думаю можно вобще не заикаться.

M>>Я с удовольствием посмотрю на общую функцию match, которая разберется со всеми этими примерами одним махом.

У этой горы кода есть 2 проблемы:
1)Куча грязи.
2)Он не работает.
А так да. Написать кучу неработающего псевдокода с кучей грязи может любой.

SR>Так же и при сопоставлении с образцом в Java.

А его нет.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[20]: Действительно ли ML языки хороши в компиляторописани
От: SmbdRsdn  
Дата: 27.04.08 16:07
Оценка:
Здравствуйте, WolfHound, Вы писали:

Гм, а раньше только улыбались в оценках...

WH>А причем тут вобще списки?

Если {0, {1, 2}} не список, тогда действительно не причем.

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

WH>Вобще говоря списки это частный случай вариантов.
WH>Не знал?
WH>
WH>variant List[T]
WH>{
WH>| Cons { value : T; tail : List[T]; }
WH>| Null
WH>}
WH>

WH>А компилятор их просто слегка подсахаривает.
А можно в этот вариант вложить {0, {1, 2}}? Или только {0, 1, 2}?

WH>А алгоритм генерации сопоставления с образцом уже не различает списки там или нет.

Тем лучше, значит и в java можно сделать единую функцию сопоставления с образцом

WH>Реализацию такую чтобы я ее не разломал в пыль с первой же попытки в студию.

Ожидаете устойчивый к разламыванию в пыль код сопоставления с образцом?
Что вы кстати вкладываете в понятие разламывание в пыль?
До получения ответа, не рискну выкладывать код, так как не знаю требований.
Впрочем, куски кода мною уже выкладывались, в них не хватает буквально по строчке кода в паре мест.
Убежден, что из этих кусков решение можно восстановить целиком.

WH>Про то чтобы оно еще и работало хотябы со скоростью аналога на скале я думаю можно вобще не заикаться.

Скорость сопоставления с образцом уже обсуждалась. Могу лишь вновь повторить свои доводы.

WH>У этой горы кода есть 2 проблемы:

WH>1)Куча грязи.
"Грязь" — там только в необходимости заранее объявлять переменные.
Грязь в кавычках, потому что существует много доводов как за, так и против использования переменных без их объявления.
Сами же образцы для сопоставления отличаются несущественно.
WH>2)Он не работает.
Он не не работает, он не приведен целиком.
Впрочем с учетом того, что код проделывающий сопоставление с образцом является в достаточной мере обобщенным и может быть вынесен в библиотеку.
WH>А так да. Написать кучу неработающего псевдокода с кучей грязи может любой.
Псевдокод это, обычно, код, для которого пока не существует компилятора.
Мой же код с успехом компилируется существующими компиляторами Java.

WH>А его нет.

А она есть. Замечу, правда, что в эту игру — есть/нет — можно играть долго.
Re[19]: Действительно ли ML языки хороши в компиляторописани
От: Mamut Швеция http://dmitriid.com
Дата: 27.04.08 16:13
Оценка:
SR>Вы не поняли изначально. В вашем коде и моем нет сопоставления цикл — pattern matching. А есть сопоставление цикл — рекурсия.
SR>А нужна она для того, чтобы после разбора начала списка, разобрать хвост списка. Это же стандартная тема сопоставления ФП и ИП.

Ничего не понял

M>>И это называется удобным???


M>>На каждый случай писать свою, отдельную, специализированную функцию, заточенную под разбор только данного конкретного случая?

SR>Гм, у вас какое-то преувеличение насчет списков. Эта структура данных известна давным давно, все с ней более менее ясно.


Причем тут списки? Идет речь не о списках, а о произвольных структурах.

SR>С чего вы взяли, что там отдельная специализированная функция? Там обобщенная. А класс Response всего лишь обертка, которую можно и не заводить.

SR>Я же его завел, потому что мне хотелось иметь инфиксную форму вызова matches.
SR>А так было бы,
SR>
SR>boolean matches(Object[] list, Object[] pattern) {
SR>}
SR>

SR>И сопоставлять она будет списки с произвольной структурой.
SR>В который уже раз повторяю — обратите внимание, практически всегда, когда идет нахваливание сопоставления с образцом речь идет о вариантах, а не о просто списках.

Так никто про списки изначально и не говорил


M>>На четырех простейших примерах — это уже четвертая такая функция.

SR>Не четыре, а два и приводилась декларативная форма представления. А как это реализовано внутри не важно, главное, что можно сделать это обобщенно.

Как это реализовано внутри — это очень важно. Во всех примерах на Яве приходилось задвигать передаваемые данные в прокрустово ложе if'а (case'а), потому что ни if ни case не разбирают структуру разбираемых данных.

SR>Неужели считаете, что в Scala сопоставление со списком и с вариантами это одна функция? Конечно, это может быть и так, но скорее всего их тоже две.


Да, но прогарммисту, это использующему — абсолютно все равно:
case input_data of
    [{elem1, elem2}|T] -> сделаем что-то одно
    [[L]|T] -> разбираем вложенный список
    {a, b} -> а ждесь вообще не список, оппаньки
    {[H|T], [H2|T2]} -> и здесь не список передали. но внутри список
    {a, {b, {c, d}}} -> здесь списком даже и не пахнет, но все разобрали
    {_, _, _, _, x} -> нам важен только 5-й параметр, хотя струкутра может быть такой:
    {{a, b, c}, [H|T], {[H2|T2]}, d, e} -> и все равно мы ее сможем разобрать
end




M>>ПМ позволяет использовать унифицированый подход к разбору как структуры так и значений:

SR>Сопоставление с образцом в Java позволяет ровно тоже самое.

Не позволяет. Его в Яве нет. Все, что есть — это if/case, которые структуру разобрать не позволяют.


M>>Я с удовольствием посмотрю на общую функцию match, которая разберется со всеми этими примерами одним махом.


SR>[поскипаны примеры псевдокода]


что за list.match()? кто его написал? откуда он взялся? он будет работать для произвольных данных?


M>>Сомневаюсь. Выше приведено четыре примера, на каждый из которых с нашей стороны был приведен простейший декларативный код с ПМом, а с вашей — четыре разные функции, которые еще и накладывают ограничения на реализацию (например, необходимость реализации метода equals в первом примере)


SR>С моей стороны функции, не приводились, а приводился лишь образец для сопоставления.

SR>И случаев относящихся к сопоставление с образцом не четыре, а два. Сопоставление со списком, и сопоставление с вариантами.

И для каждого случая пришлось писать отдельную функцию, разбирающую отдельную структуру только в данном конкретном случае для того, чтобы вернуть true/false, чтобы это можно было проверить if/case'ом

M>>и if и case могут проверять только значения. ПМ позвляет проверять и структуру и значения сразу, без какойлибо дополнительной работы со сторноы программиста. В этом — главное и основное отличие

SR>Так же и при сопоставлении с образцом в Java.

Еще раз — Java такого не позволяет:

ПМ:
match({1, 2, 3}) ->
    ok;

match({"a", "b", "c"}) ->
    ok;

match([H|T]) ->
    ok.


Как общим кодом на Яве узнать, что:
— в первом случае у нас объект с тремя целочисленными полями
— во втором — с тремя текстовыми полями
— в третьем — вообще списко/массив
?

Более того, если нас не интересует тимп полей, а только их структура? Сколько перегруженых операторов equals придется писать для каждого отдельного случая?


dmitriid.comGitHubLinkedIn
Re[20]: Действительно ли ML языки хороши в компиляторописани
От: SmbdRsdn  
Дата: 27.04.08 17:08
Оценка: :)
Здравствуйте, Mamut, Вы писали:

M>Ничего не понял

Сочувствую.

M>Причем тут списки?

M>Так никто про списки изначально и не говорил
Притом, что в ваших образцах в большинстве случаев приводятся списки.
То есть, что-то типа {obj1, obj2, _, {obj3, _ }, _}.
Я же вам в который раз отвечаю, что такие образцы легко релизуются в java. Легко по сравнению со вторым типом.
А вот более интересные типа Obj1(Obj2(_, Obj3())) у вас встречаются значительно реже.

M>Как это реализовано внутри — это очень важно. Во всех примерах на Яве приходилось задвигать передаваемые данные в прокрустово ложе if'а (case'а), потому что ни if ни case не разбирают структуру разбираемых данных.

Конечно не разбирают. Разбирает метод matches. А if в зависимости от успешности разбора передает управление.
Кстати, когда я говорил вам обратить внимание, что if это case, я имел ввиду, case из erlang, а не из java.

M>Да, но прогарммисту, это использующему — абсолютно все равно:

M>
M>case input_data of
M>    [{elem1, elem2}|T] -> сделаем что-то одно
M>    [[L]|T] -> разбираем вложенный список
M>    {a, b} -> а ждесь вообще не список, оппаньки
M>    {[H|T], [H2|T2]} -> и здесь не список передали. но внутри список
M>    {a, {b, {c, d}}} -> здесь списком даже и не пахнет, но все разобрали
M>    {_, _, _, _, x} -> нам важен только 5-й параметр, хотя струкутра может быть такой:
M>    {{a, b, c}, [H|T], {[H2|T2]}, d, e} -> и все равно мы ее сможем разобрать
M>end
M>

if (data.matches(list(elem1, elem2), T))
if (data.matches(list(L), T))
if (data.matches(a, b)
if (data.matches(list(H, T), list(H2, T2))
if (data.matches(a, list(b, list(c, d)))
if (data.matches(_, _, _, _, x))
if (data.matches(list(a, b, c), list(H, T), list(list(H2, T2), d, e)))


M>Не позволяет. Его в Яве нет. Все, что есть — это if/case, которые структуру разобрать не позволяют.

Позволяют. Играть, в эту игру можно долго.

SR>>[поскипаны примеры псевдокода]

Какой же это псевдокод? Вполне себе успешно компилируется Java.

M>что за list.match()? кто его написал? откуда он взялся? он будет работать для произвольных данных?

Его написал я. Я. Я его написал. Да.

M>И для каждого случая пришлось писать отдельную функцию, разбирающую отдельную структуру только в данном конкретном случае для того, чтобы вернуть true/false, чтобы это можно было проверить if/case'ом

Нет код обобщенный, пишу уже в который раз.

M>Еще раз — Java такого не позволяет:

Позволяет. Играть в эту игру можно долго.

M>ПМ:

M>
M>match({1, 2, 3}) ->
M>    ok;

M>match({"a", "b", "c"}) ->
M>    ok;

M>match([H|T]) ->
M>    ok.
M>


M>Как общим кодом на Яве узнать, что:

M>- в первом случае у нас объект с тремя целочисленными полями
if (list.matches(1, 2, 3))
  return ok;

M>- во втором — с тремя текстовыми полями
if (list.matches("a", "b", "c")
  return ok;

M>- в третьем — вообще списко/массив
Match h = new Match(); Tail t = new Tail();
if (list.matches(h, t))
  return ok;

M>?

M>Более того, если нас не интересует тимп полей, а только их структура?

Что же не привели образец для сопоставления? Уверен я легко мог бы сделать такой и на Java.
M>Сколько перегруженых операторов equals придется писать для каждого отдельного случая?
0. equals пишется для вариантов, но при поддержке компилятора и среды его можно и не писать.
Re[21]: Действительно ли ML языки хороши в компиляторописани
От: Cyberax Марс  
Дата: 27.04.08 17:13
Оценка:
Здравствуйте, SmbdRsdn, Вы писали:

M>>Более того, если нас не интересует тимп полей, а только их структура?

SR>Что же не привели образец для сопоставления? Уверен я легко мог бы сделать такой и на Java.
Нельзя. Точнее, можно, но совершенно непрактично.

M>>Сколько перегруженых операторов equals придется писать для каждого отдельного случая?

SR>0. equals пишется для вариантов, но при поддержке компилятора и среды его можно и не писать.
?? equals можно автоматически сгенерировать с помощью IDE.
Sapienti sat!
Re[21]: Действительно ли ML языки хороши в компиляторописани
От: WolfHound  
Дата: 27.04.08 17:19
Оценка:
Здравствуйте, SmbdRsdn, Вы писали:

WH>>А причем тут вобще списки?

SR>Если {0, {1, 2}} не список, тогда действительно не причем.
Это вобще туплы.

SR>А можно в этот вариант вложить {0, {1, 2}}? Или только {0, 1, 2}?

В этот нельзя.
Язык статически типизированный.
В динамически типизированных языках таких как erlang можно.

SR>Тем лучше, значит и в java можно сделать единую функцию сопоставления с образцом

Теоритически все можно сделать... особенно на словах...

WH>>Реализацию такую чтобы я ее не разломал в пыль с первой же попытки в студию.

SR>Ожидаете устойчивый к разламыванию в пыль код сопоставления с образцом?
Да.

SR>Что вы кстати вкладываете в понятие разламывание в пыль?

Покажи код увидишь.

SR>До получения ответа, не рискну выкладывать код, так как не знаю требований.

Устойчивость к дуракам типа меня.
Ну и чтобы лишних проверок не делал.

SR>Впрочем, куски кода мною уже выкладывались, в них не хватает буквально по строчке кода в паре мест.

SR>Убежден, что из этих кусков решение можно восстановить целиком.
Вот еще за тебя делать твою работу.

WH>>Про то чтобы оно еще и работало хотябы со скоростью аналога на скале я думаю можно вобще не заикаться.

SR>Скорость сопоставления с образцом уже обсуждалась. Могу лишь вновь повторить свои доводы.
Ты где настолько умные компиляторы видел?
Я покачто видел только компиляторы которые генерили оптимальный код только если точно знали что происходит.

SR>"Грязь" — там только в необходимости заранее объявлять переменные.

Там ее еще много.

SR>Грязь в кавычках, потому что существует много доводов как за,

Аргументов за нет и быть не может.
Ибо невозможно обосновать наличие текста который совершенно ничего не дает.

SR>так и против использования переменных без их объявления.

А это вобще бред.
Переменные объявляются в коде паттерна.

SR>Сами же образцы для сопоставления отличаются несущественно.

На игрушечных примерах.

SR>Псевдокод это, обычно, код, для которого пока не существует компилятора.

SR>Мой же код с успехом компилируется существующими компиляторами Java.
Полный код в студию.
В чем проблема?
Ведь ты же его вроде как уже написал.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.