Re[3]: Красиво избежать побочных эффектов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.06.12 15:01
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>А чем этот вариант "идеологически более правильный", чем первоначальный код?


Ничем.

ВВ> Двойной проход


Какой такой двойной проход?

ВВ> + то же самое локальное состояние.


А без состояния эта задачка нормально не решается. Его, конечно, можно в стек выпихнуть, но кайфа от этого немного.
... << RSDN@Home 1.2.0 alpha 5 rev. 52 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[4]: Красиво избежать побочных эффектов
От: Воронков Василий Россия  
Дата: 25.06.12 15:11
Оценка:
Здравствуйте, AndrewVK, Вы писали:

ВВ>> Двойной проход

AVK>Какой такой двойной проход?

Ну предполагается, что получив отобранную таким образом коллекцию, мы с ней что-то сделаем, т.е. совершим проход по ней, так ведь? Первоначальный код делает все в один проход. В твоем варианте я *предполагаю*, что ты просто забыл дописать в конце ToList. Вот тебе и двойной проход. А ToList там, мягко говоря, нужен.

И, кстати, его необходимость как раз и выдает главную проблему этого кода. Автору топика поведение (||) кажется неочевидным. Ты вместо этого заменил все на non-strict последовательность (без мемоизации!), причем с побочным эффектом.

Как-то это... хуже, да простите меня за критику.
Re[5]: Красиво избежать побочных эффектов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.06.12 15:14
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

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


Ну да. Ровно один проход.

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


Ну ты крут. Ничего я не забывал, и никаких двойных проходов нет.

ВВ> Вот тебе и двойной проход. А ToList там, мягко говоря, нужен


Зачем? Следующей строкой будет foreach. А если ты собрался результат отдавать наружу, то надо просто вынести каунтер в специальное хранилище, чтобы интерференции не было.
... << RSDN@Home 1.2.0 alpha 5 rev. 52 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[6]: Красиво избежать побочных эффектов
От: Воронков Василий Россия  
Дата: 25.06.12 15:19
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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

AVK>Ну да. Ровно один проход.
ВВ>> Первоначальный код делает все в один проход. В твоем варианте я *предполагаю*, что ты просто забыл дописать в конце ToList.
AVK>Ну ты крут. Ничего я не забывал, и никаких двойных проходов нет.

Нет, я просто пытаюсь представить, как должен выглядеть твой код *на самом деле*. Ведь не совсем так, как ты написал, правда? Теперь вот оказывается, что надо каунтер выносить в некое "специальное хранилище" (это, кстати, что такое?). При этом вообще-то проблемой первоначального варианта называлась неочевидность.

В общем можно полный код в студию. Со специальными хранилищами и всем прочим. У меня вот все же есть определенное подозрение, что твой вариант все же содержит некоторое количество изврата.
Re[7]: Красиво избежать побочных эффектов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.06.12 15:27
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Нет, я просто пытаюсь представить, как должен выглядеть твой код *на самом деле*.


Проблемы с восприятием текстовой информации?

ВВ> Ведь не совсем так, как ты написал, правда?


Ненправда.

ВВ> Теперь вот оказывается, что надо каунтер выносить в некое "специальное хранилище"


Не надо. Это просто я пытаюсь додумывать фантазии в твоей голове.

ВВ>В общем можно полный код в студию.


Нет никакого полного кода. Идею я продемонстрировал, а флудить тебе придется без меня.
... << RSDN@Home 1.2.0 alpha 5 rev. 52 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[8]: Красиво избежать побочных эффектов
От: Воронков Василий Россия  
Дата: 25.06.12 15:32
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Нет никакого полного кода. Идею я продемонстрировал, а флудить тебе придется без меня.


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

Я лишь просто поинтересовался у тебя, в чем, собственно, заключалась продемонстрированная идея. А теперь, оказывается, у меня с восприятием проблемы. Ну пусть так
Re[10]: Красиво избежать побочных эффектов
От: Kogrom  
Дата: 25.06.12 17:48
Оценка:
Знаю, что говорю сам с собой, но из любви к искусству ещё вариант с циклом:

def gen(items, myself, limit):
    for item in items:
        if item.owner != myself:
            yield item
        elif limit:
            limit -= 1
            yield item
        else:
            return

for item in gen(items, myself, limit): processItem(item)


Внешнего счётчика нет, функция (processItem), которая теоретически может дать побочный эффект, не находится в дебрях кода. Поэтому её в тестах легко можно заменить на подделку.
Re[11]: Красиво избежать побочных эффектов
От: Roman Odaisky Украина  
Дата: 25.06.12 20:49
Оценка:
Здравствуйте, Kogrom, Вы писали:

K>Знаю, что говорю сам с собой, но из любви к искусству ещё вариант с циклом:


K>
def gen(items, myself, limit):
    for item in items:
        if item.owner != myself:
            yield item
        elif limit:
            limit -= 1
            yield item
        else:
            return

А вот и нет. Проблема осталась: при добавлении условий легко напутать и поставить их не туда, сбив подсчет limit. Ну и ветка else лишняя.

Интересно подобрать декларативный подход, не императивный.
До последнего не верил в пирамиду Лебедева.
Re[12]: Красиво избежать побочных эффектов
От: Kogrom  
Дата: 27.06.12 13:10
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>А вот и нет. Проблема осталась: при добавлении условий легко напутать и поставить их не туда, сбив подсчет limit. Ну и ветка else лишняя.


else не лишний — без него цикл пройдёт по всему списку. Проблема с условиями сомнительна: почему её не будет при других подходах?

RO>Интересно подобрать декларативный подход, не императивный.


С этого надо было начинать.
Re[13]: Красиво избежать побочных эффектов
От: Воронков Василий Россия  
Дата: 27.06.12 13:47
Оценка:
Здравствуйте, Kogrom, Вы писали:

RO>>А вот и нет. Проблема осталась: при добавлении условий легко напутать и поставить их не туда, сбив подсчет limit. Ну и ветка else лишняя.

K>else не лишний — без него цикл пройдёт по всему списку. Проблема с условиями сомнительна: почему её не будет при других подходах?

Так он и должен идти по всему списку. Задача же обработать все элементы, у которых owner != myself (плюс доп. условие). У вас же получается, что как только лимит кончается и попадается первый элемент, у которого owner == myself, то вы выходите из функции. А это неправильно, т.к. в списке могут быть еще элементы, удовлетворяющие первому условию.

RO>>Интересно подобрать декларативный подход, не императивный.

K>С этого надо было начинать.

Я так понимаю, идея ТС в том, чтобы максимально упростить добавление новых условий. Здесь декларативный подход напрашивается сам собой — чтобы была возможность эти условия просто комбинировать. Вариант, который я привел, тоже, конечно, не идеален:

open core

let apply f c e | c e is Some c' = f e $ c'
                | else = c

let comb p max n e | p e = Some (comb p max n)
                   | n < max = Some (comb p max (n+1))
                   | else = None

let process act comb xs = foldl (apply act) comb xs

process processItem (comb even 5 0) [1..100]


Однако в нем по крайней мере можно ввести дополнительный комбинатор и делать так:

let orelse p a e | p e = a e | else = ()

process (processItem |> orelse (<25) |> orelse (>5) )  (comb even 5 0) [1..100]
Re[14]: Красиво избежать побочных эффектов
От: Kogrom  
Дата: 27.06.12 16:59
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Так он и должен идти по всему списку.


Да, действительно. Значит код будет ещё короче. Тогда условия не влияют друг на друга и нет проблемы в добавлении новых (elif limit легко можно поменять на if item.owner == myself and limit).

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

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