Не перестаю удивляться
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.10 19:16
Оценка: 20 (4)
Вот уже почти 4 года как знаком с Nemerle, но до сих пор не перестаю удивляться логичности его проектирования.

Сам много раз писал в статьях, что для декомпозиции кортежей можно применять специальный вид паттерн-матчинга. Выглядит это так:
TitleImpl(parags : list[XElement], styleName : string) : list[XElement] * string { ... }
...
 def (tail, title) = TitleImpl(parags, "H1");
 используем tail и title


Здесь (tail, title) — это паатерн-матчинг с паттерном "кортеж".

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

Конечно можно использовать индексы для получения вложенных значений:
 def res = TitleImpl(parags, "H1");
 используем res[0] вместо tail и res[1] вместо title

Но использование res[0] и res[1] как-то некрасиво.

Наткнувшись очередной раз на эту ситуацию я вспомнил не однократно повторяемые самим же собой слова "это паттерн" и подумал — раз это паттерн, то я наверно могу использовать паттерн "as". Сам не веря в то, что это сработает я попробовал написать:
Title(parags : list[XElement]) : list[XElement] * string
{
  def (_, title) as res = TitleImpl(parags, "H1");
  
  if (title == null)
  {
    Error(0, "Первым абзацем должен идти заголовок статьи помеченный стилем 'H1'");
    (parags, "<<Не задан заголовок статьи>>")
  }
  else res
}

и это сработало! Я одновременно получил и кортеж, и значение из него.

Вот это в Немерле мне нравится больше всего. Он работает так как предполагаешь, даже если на первый взгляд предположения кажутся очень смелыми!
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Не перестаю удивляться
От: z00n  
Дата: 04.02.10 19:39
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>и это сработало! Я одновременно получил и кортеж, и значение из него.


А в каком языке с паттерн-матчингом это не так?


scala> val all@(first,second) = (11,12)
all: (Int, Int) = (11,12)
first: Int = 11
second: Int = 12


# let (first,second) as all = (11,12);;
val first : int = 11
val second : int = 12
val all : int * int = (11, 12)
Re: Не перестаю удивляться
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 04.02.10 20:17
Оценка:
Круто! Много раз встречал ситуации когда это было бы полезным.
Ce n'est que pour vous dire ce que je vous dis.
Re[2]: Не перестаю удивляться
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.10 21:45
Оценка:
Здравствуйте, z00n, Вы писали:

Z>А в каком языке с паттерн-матчингом это не так?


А фиг его знает. Я почему-то вообще не думал, что оно так должно работать. Точнее вот подумал, что хорошо бы чтобы работал, и оно работает .

Раньше я почему-то думал, что это слишком круто чтобы быть правдой.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Не перестаю удивляться
От: hardcase Пират http://nemerle.org
Дата: 04.02.10 21:51
Оценка: 42 (1)
Здравствуйте, VladD2, Вы писали:

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


Поделюсь и своей "Америкой".

Сопоставление с образцом для аргументов-кортежей работает в лямбдах:
def debugger_display_fmt = {
    def (_, fmt) = fields.FoldLeft( (" ", ""),
        (f, (prefix, fmt)) => (", ", fmt + prefix + f.PropertyName + " = {" + f.PropertyName + "}"));
    "\\{" + fmt + " \\}" 
}

Этот код из списка свойств формирует строку форматирования для отладчика: \{ a = {a}, b = {b} \}
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Не перестаю удивляться
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.10 22:04
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Сопоставление с образцом для аргументов-кортежей работает в лямбдах:

H>
H>def debugger_display_fmt = {
H>    def (_, fmt) = fields.FoldLeft( (" ", ""),
H>        (f, (prefix, fmt)) => (", ", fmt + prefix + f.PropertyName + " = {" + f.PropertyName + "}"));
H>    "\\{" + fmt + " \\}" 
H>}
H>

H>Этот код из списка свойств формирует строку форматирования для отладчика: \{ a = {a}, b = {b} \}

Скажу больше. В лямбдах исходного синтаксиса он работал всегда. А вот в лямбдах вида (...) => ... он заработал после того как я соответствующий макрос допилил напильником.

Проблема только в том, что про синтаксис as я не знал и по этому, скорее всего код вроде
(f, (prefix, fmt) as y) => ... y

работать не будет .
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Не перестаю удивляться
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.10 22:16
Оценка: 21 (1)
Здравствуйте, hardcase, Вы писали:

H>Сопоставление с образцом для аргументов-кортежей работает в лямбдах:

H>
H>def debugger_display_fmt = {
H>    def (_, fmt) = fields.FoldLeft( (" ", ""),
H>        (f, (prefix, fmt)) => (", ", fmt + prefix + f.PropertyName + " = {" + f.PropertyName + "}"));
H>    "\\{" + fmt + " \\}" 
H>}
H>

H>Этот код из списка свойств формирует строку форматирования для отладчика: \{ a = {a}, b = {b} \}

Еще одно "кстати". На мой взгляд для работы со строками намного удобнее использовать $-строки. Вот как может выглядеть твой пример с их применением:
def debugger_display_fmt = $<#\{ ..$(fields; ", "; f => $"$(f.PropertyName) = {$(f.PropertyName)}") \}#>;

Или, что еще лучше, с вынесением функции формирования свойства отдельно:
def fieldToStr(f) { $"$(f.PropertyName) = {$(f.PropertyName)}" }

def debugger_display_fmt = $<#\{ ..$(fields; ", "; fieldToStr) \}#>;

Это намного проще читать (да и писать тоже) когда привыкаешь к $-нотации.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Не перестаю удивляться
От: Roman Odaisky Украина  
Дата: 04.02.10 22:31
Оценка: +1 :)
Здравствуйте, z00n, Вы писали:

VD>>и это сработало! Я одновременно получил и кортеж, и значение из него.

Z>А в каком языке с паттерн-матчингом это не так?

Так даже и без паттерн-матчинга:

#!/usr/bin/python

x, y = xy = range(2)
До последнего не верил в пирамиду Лебедева.
Re[3]: Не перестаю удивляться
От: FR  
Дата: 05.02.10 07:06
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А фиг его знает. Я почему-то вообще не думал, что оно так должно работать. Точнее вот подумал, что хорошо бы чтобы работал, и оно работает .


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


Это вообще еще из OCaml'а наверно в Немерле перекочевало:

# let (a, b) as c = (123, 124);;
val a : int = 123
val b : int = 124
val c : int * int = (123, 124)
#


Так что благодарить надо французов
Re[3]: Не перестаю удивляться
От: hardcase Пират http://nemerle.org
Дата: 05.02.10 07:07
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>def fieldToStr(f) { $"$(f.PropertyName) = {$(f.PropertyName)}" }


VD>def debugger_display_fmt = $<#\{ ..$(fields; ", "; fieldToStr) \}#>;

VD>[/c#]
VD>Это намного проще читать (да и писать тоже) когда привыкаешь к $-нотации.

Сплайс-нотацию знаю, а вот до такого способа использования не додумался. Спасибо.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Не перестаю удивляться
От: FR  
Дата: 05.02.10 07:15
Оценка:
Здравствуйте, hardcase, Вы писали:


H>Поделюсь и своей "Америкой".


H>Сопоставление с образцом для аргументов-кортежей работает в лямбдах:


Это тоже из OCaml, там любое объявление — это сопоставление с образцом.
Re[3]: Не перестаю удивляться
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 05.02.10 11:03
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Еще одно "кстати". На мой взгляд для работы со строками намного удобнее использовать $-строки.


Зависит от контекста, конечно, но сплайсы использовать еще и безопаснее
... << RSDN@Home 1.2.0 alpha 4 rev. 1421>>

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[4]: Не перестаю удивляться
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.02.10 14:28
Оценка: :)
Здравствуйте, FR, Вы писали:

FR>Это вообще еще из OCaml'а наверно в Немерле перекочевало


А что в ML этого не было?

FR>Так что благодарить надо французов


Ну, тогда огромное им спасибо за наше счастливое детство (с).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Не перестаю удивляться
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.02.10 14:35
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Зависит от контекста, конечно, но сплайсы использовать еще и безопаснее


Главное, на мой взгляд, то что при их использовании идею проще выцепить. Я чтобы перепсать исходный пример минут 5 внимательно вчитывался в код и пытался понять, что означают эти prefix и fmt. Это как с циклами супротив ФВП. По алгоритму нужно угадать задумку.

В общем, все по IT. Изменение вида сложности. Сложность количественная трансформируется в сложность обучения. Для тех кто въехал в нотацию все становится просто и очевидно. Но при этом могут оказаться люди которые в следствии того, что они не в теме поспримут код "как какие-то кроказябры".

ЗЫ

Но со сплайсингом есть одна проблема. При применении ..$x-нотации формируется код с очень сильно перегруженными методами. В следствии чего даже небольшие объемы могут сильно тормозить. Особенно это заметно при редактирования кода в интеграции. Обходится это дело помещением сплайс-строк в отдельные функции (с явно указанными типами параметров) или даже в отдельные методы.
Надо бы, конечно, заняться этой проблемой. Но времени катастрофически не хватает.
С другой стороны выразительность того стоит. Лучше тратить машинное время, чем время тех кто пишет и читает код.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Не перестаю удивляться
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.02.10 14:38
Оценка:
Здравствуйте, FR, Вы писали:

FR>Это тоже из OCaml, там любое объявление — это сопоставление с образцом.


Еще бы из окамла убрать дурацкий, на мой взгляд, синтаксис let ... in, и добавить скобки как в гражданской математики, перегрузку реализовать по человечески и ..., впрочем получился бы Немерле.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Не перестаю удивляться
От: nikov США http://www.linkedin.com/in/nikov
Дата: 05.02.10 17:34
Оценка:
Здравствуйте, VladD2, Вы писали:

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


FR>>Это тоже из OCaml, там любое объявление — это сопоставление с образцом.


VD>Еще бы из окамла убрать дурацкий, на мой взгляд, синтаксис let ... in, и добавить скобки как в гражданской математики, перегрузку реализовать по человечески и ...,


Вот это не надо.
Re[5]: Не перестаю удивляться
От: z00n  
Дата: 05.02.10 18:52
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А что в ML этого не было?


Было.

Standard ML of New Jersey v110.65 [built: Fri Jun 15 11:06:31 2007]
- val all as (x,y) = (11,12);
val all = (11,12) : int * int
val x = 11 : int
val y = 12 : int
Re[6]: Не перестаю удивляться
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.02.10 20:56
Оценка:
Здравствуйте, z00n, Вы писали:

Z>
Z>Standard ML of New Jersey v110.65 [built: Fri Jun 15 11:06:31 2007]
Z>- val all as (x,y) = (11,12);
Z>val all = (11,12) : int * int
Z>val x = 11 : int
Z>val y = 12 : int
Z>


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