Вот уже почти 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
}
и это сработало! Я одновременно получил и кортеж, и значение из него.
Вот это в Немерле мне нравится больше всего. Он работает так как предполагаешь, даже если на первый взгляд предположения кажутся очень смелыми!