Ленивые вычисления
От: Ka3a4oK  
Дата: 09.12.10 06:36
Оценка:
Как сделать этот код в ленивом стиле? Интересует не то, как его ручками переделать на if-ы, а как используя макросы Немерле добиться нужного поведения.

def a=SomeHavyFunction1();
def b=SomeHavyFunction2();

match(a, b)
{
|(5, _) => 2 //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
|(_, 5) => 3 
|(6, 6) => 4
}
Re: Ленивые вычисления
От: hardcase Пират http://nemerle.org
Дата: 09.12.10 07:08
Оценка: 1 (1)
Здравствуйте, Ka3a4oK, Вы писали:

KK>Как сделать этот код в ленивом стиле? Интересует не то, как его ручками переделать на if-ы, а как используя макросы Немерле добиться нужного поведения.


KK>
KK>def a=SomeHavyFunction1();
KK>def b=SomeHavyFunction2();

KK>match(a, b)
KK>{
KK>|(5, _) => 2 //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
KK>|(_, 5) => 3 
KK>|(6, 6) => 4
KK>}
KK>


Можно вот так:

using Nemerle;

....

    def a = SomeFuncA(6);
    def b = lazy(SomeFuncB(6)); // макрос lazy - изготавливает экземпляр LazyValue
    match(a, b)
    {
      |(5, _) => 2 //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
      |(_, LazyValue where ( Value = 5 )) => 3 
      |(6, LazyValue where ( Value = 6 )) => 4
      | _ => 0;
    }
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Ленивые вычисления
От: Ka3a4oK  
Дата: 09.12.10 07:27
Оценка:
А если более сложный пример:

def a=SomeHavyFunction1();
def b=SomeHavyFunction2();

match(a, b)
{
|(option.Some(v), _) => v //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
|(_, option.Some(v)) => v 
|(option.None(), option.None()) => ...
}
Re[3]: Ленивые вычисления
От: Ka3a4oK  
Дата: 09.12.10 07:43
Оценка:
Разобрался. Как-то громоздко получается. А нельзя ли сделать ленивые вычисления почти zero-cost для пользователя. Позволив ему только декларировать, что выражение является ленивым. Это нельзя сделать принципиально или просто еще над эти никто не работал?
Re[3]: Ленивые вычисления
От: hardcase Пират http://nemerle.org
Дата: 09.12.10 07:44
Оценка:
Здравствуйте, Ka3a4oK, Вы писали:

KK>А если более сложный пример:


KK>
KK>def a=SomeHavyFunction1();
KK>def b=SomeHavyFunction2();

KK>match(a, b)
KK>{
KK>|(option.Some(v), _) => v //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
KK>|(_, option.Some(v)) => v 
KK>|(option.None(), option.None()) => ...
KK>}
KK>


Во-первых option можно не указывать, варианта Nemerle.Core.option находится в using-ах по-умолчанию.
Во-вторых все точно также:

    match(a, b)
    {
      |(Some(v), _) => v
      |(_,       LazyValue where ( Value = Some(v) )) => v
      |(None(),  LazyValue where ( Value = None() ))  => 0
    }
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: Ленивые вычисления
От: hardcase Пират http://nemerle.org
Дата: 09.12.10 07:54
Оценка:
Здравствуйте, Ka3a4oK, Вы писали:

KK>Разобрался. Как-то громоздко получается. А нельзя ли сделать ленивые вычисления почти zero-cost для пользователя. Позволив ему только декларировать, что выражение является ленивым. Это нельзя сделать принципиально или просто еще над эти никто не работал?


Никому это было не нужно.
Но если операция частая, то можно генерировать шаблон LazyValue автоматом, для этого нужно написать макрос lazy match, использование которого может выглядеть так:
lazy match(...)
{
  | lazy(x) =>
}

Макрос ищет шаблоны lazy(x) и преобразовывает их к виду: LazyValue where ( Value = x ).
/* иЗвиНите зА неРовнЫй поЧерК */
Re[5]: Ленивые вычисления
От: hardcase Пират http://nemerle.org
Дата: 09.12.10 07:56
Оценка:
Здравствуйте, hardcase, Вы писали:

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


KK>>Разобрался. Как-то громоздко получается. А нельзя ли сделать ленивые вычисления почти zero-cost для пользователя. Позволив ему только декларировать, что выражение является ленивым. Это нельзя сделать принципиально или просто еще над эти никто не работал?


H>Никому это было не нужно.

H>Но если операция частая, то можно генерировать шаблон LazyValue автоматом, для этого нужно написать макрос lazy match, использование которого может выглядеть так:
H>
H>lazy match(...)
H>{
H>  | lazy(x) =>
H>}
H>

H>Макрос ищет шаблоны lazy(x) и преобразовывает их к виду: LazyValue where ( Value = x ).


Осталось дождаться знатоков ActiveMatch, возможно такую штуку возможно реализовать в рамках этого крутого макроса (я с ним покачто не разбирался).
/* иЗвиНите зА неРовнЫй поЧерК */
Re[6]: Ленивые вычисления
От: Рысцов Денис  
Дата: 09.12.10 15:22
Оценка: 17 (2)
Здравствуйте, hardcase, Вы писали:

H>Осталось дождаться знатоков ActiveMatch, возможно такую штуку возможно реализовать в рамках этого крутого макроса (я с ним покачто не разбирался).

ActiveMatch это поддерживает изначально

Объявляем активный паттерн:

lazied['a](x : LazyValue['a]) : option['a]
{
  Some(x.Value)
}

И используем:

def a = SomeFuncA(6);
def b = lazy(SomeFuncB(6));
active match(a, b)
{
  | (5, _) => 2
  | (_, lazied(5)) => 3 
  | (6, lazied(x)) => x
  | _ => 0
}
Re[7]: Ленивые вычисления
От: Ka3a4oK  
Дата: 09.12.10 20:28
Оценка:
Можно подробнее про актив матч?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Re[8]: Ленивые вычисления
От: Рысцов Денис  
Дата: 09.12.10 21:06
Оценка: 21 (1)
Здравствуйте, Ka3a4oK, Вы писали:

KK>Можно подробнее про актив матч?


Он был добавлен в F# для разбора объектов, которые не являются размеченными объединениями, но помимо этого его можно использовать для декомпозиции pattern matching в случае, когда правило в левой части является слишком длинным. Для последней цели я добавил его реализацию в Nemerle, так как для разбора не вариантов в Nemerle уже есть конструкция, её hardcase уже выше приводил ( | LazyValue where ( Value = 5 ))).

Код, объяснение как работает (http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/ActivePatterns/ActivePatterns/ActiveImpl.n) и примеры (http://code.google.com/p/nemerle/source/browse/#svn/nemerle/trunk/snippets/ActivePatterns/Test) есть в репозитории.

Если что-то непонятно — задавай вопросы.
Re[9]: Ленивые вычисления
От: hardcase Пират http://nemerle.org
Дата: 09.12.10 21:23
Оценка:
Здравствуйте, Рысцов Денис, Вы писали:

РД>Здравствуйте, Ka3a4oK, Вы писали:


KK>>Можно подробнее про актив матч?


РД>Он был добавлен в F# для разбора объектов, которые не являются размеченными объединениями, но помимо этого его можно использовать для декомпозиции pattern matching в случае, когда правило в левой части является слишком длинным. Для последней цели я добавил его реализацию в Nemerle, так как для разбора не вариантов в Nemerle уже есть конструкция, её hardcase уже выше приводил ( | LazyValue where ( Value = 5 ))).


На самом деле у нас просто нет такого специфического вида макросов, которые можно раскрывать раскрываться в шаблонах match-а.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[9]: Ленивые вычисления
От: Ziaw Россия  
Дата: 10.12.10 00:10
Оценка:
Здравствуйте, Рысцов Денис, Вы писали:

РД>Если что-то непонятно — задавай вопросы.


Непонятно, почему это еще не вошло в стандартную библиотеку макросов

Фича must have.
Re[9]: Ленивые вычисления
От: Ziaw Россия  
Дата: 10.12.10 00:32
Оценка:
Здравствуйте, Рысцов Денис, Вы писали:

РД>Если что-то непонятно — задавай вопросы.


Почему матчащийся объект передается последним аргументом? Это не очень логично, на мой взгляд.
Re: Ленивые вычисления
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.12.10 16:12
Оценка:
Здравствуйте, Ka3a4oK, Вы писали:

KK>Как сделать этот код в ленивом стиле? Интересует не то, как его ручками переделать на if-ы, а как используя макросы Немерле добиться нужного поведения.


KK>
KK>def a=;
KK>def b=SomeHavyFunction2();

KK>match(a, b)
KK>{
KK>|(5, _) => 2 //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
KK>|(_, 5) => 3 
KK>|(6, 6) => 4
KK>}
KK>


Начнем с того, что этот код не корректен. match не полный.

Перепиши код:
if (a == 5)
  ...
else match (a, SomeHavyFunction2())
{
 | (_, 5) => 3 
 | (6, 6) => 4
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Ленивые вычисления
От: Аноним  
Дата: 12.12.10 18:57
Оценка:
Здравствуйте, VladD2, Вы писали:

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


KK>>Как сделать этот код в ленивом стиле? Интересует не то, как его ручками переделать на if-ы, а как используя макросы Немерле добиться нужного поведения.


KK>>
KK>>def a=;
KK>>def b=SomeHavyFunction2();

KK>>match(a, b)
KK>>{
KK>>|(5, _) => 2 //Не хочется, чтобы b вычислялось, если срабатывает эта альтернатива
KK>>|(_, 5) => 3 
KK>>|(6, 6) => 4
KK>>}
KK>>


VD>Начнем с того, что этот код не корректен. match не полный.


VD>Перепиши код:

VD>
VD>if (a == 5)
VD>  ...
VD>else match (a, SomeHavyFunction2())
VD>{
VD> | (_, 5) => 3 
VD> | (6, 6) => 4
VD>}
VD>


не красиво.... если отложенные применяются, то синтаксис должен быть минимален
Re[3]: Ленивые вычисления
От: catbert  
Дата: 12.12.10 19:22
Оценка:
Здравствуйте, Аноним, Вы писали:

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


То есть лучше неправильно и непонятно, но красиво и минимально? Мне такой баланс не нравится.
Re[4]: Ленивые вычисления
От: Аноним  
Дата: 12.12.10 19:40
Оценка:
Здравствуйте, catbert, Вы писали:

C>Здравствуйте, Аноним, Вы писали:


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


C>То есть лучше неправильно и непонятно, но красиво и минимально? Мне такой баланс не нравится.


много кода зачастую может понять и запомнить только автор. В чем тут неправильность я не понял.
сейчас код позволяет сделать ошибки.
lazyvalue where (value=5) много не интуитивного кода
5 проще и понятнее
Re[10]: Ленивые вычисления
От: Рысцов Денис  
Дата: 12.12.10 23:35
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Почему матчащийся объект передается последним аргументом? Это не очень логично, на мой взгляд.


Немного логики здесь есть, это связано с тем, что тип активного case без параметров это 'a->optional['b], где 'a — тип разбираемого объекта. Представим теперь "фабрику" активных case'ов с одним параметром, её тип: 'c->('a->optional['b]) в haskell это и тип функции, которая возвращает функцию, и тип функции двух переменных, а в Nemerle тип функции от двух переменных: ('c*'a)->optional['b]. Именно эту сигнатуру и имеет параметрический активный case
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.