Всё-таки мутабельность объектов в небольших пределах - иногда весьма облегчает написание алгоритмов. Это здорово, когда можно в небольшом обозримом участке кода создать объект A, перебросить на него указатели из другого уже созданного объекта B (который мы только что создали), и отложить заполнение полей A до того момента, когда они станут известны
(
Read more... )
Comments 25
Reply
Reply
Reply
по существу вот:
http://kouzdra.livejournal.com/2684228.html
ещё есть дискуссия о "недоязыках":
https://github.com/facebook/immutable-js/issues/259
Reply
Reply
Хотя, конечно, понятно, что мутабельные структуры данных могут оказаться быстрее иммутабельных - просто потому, что позволяют всё то же самое и ещё кое-что. И в этом случае оптимальным кажется спрятать мутабельность под капот (всё равно ж внутри любого языка с иммутабельными данными - куча всего мутабельного... Взять хотя бы кучу в Хаскеле).
Reply
Да, ленивость хоть и стоит дополнительных затрат, но в данном случае они пошли в дело, и позволили не запоминать копию списка целиком для переворачивания его создания.
Reply
change :: Eq a => a -> [a] -> [a]
change val (x:xs) = if x==val then last xs : xs
else x : change val xs
change val [] = []
Все иммутабельно, список обходится ровно один раз, лишний раз не копируется и не разворачивается, стек не съедается, вроде (ибо идет ленивая манипуляция графом значений в куче).
Reply
Почему хорошо с памятью - ленивость прячет "разрушающее копирование" и даёт возможность отложить создание указателей. Интересно получилось.
( Ещё осознал, что та же ленивость позволяет создавать циклы в графе ссылок, неразруливыемые счетчиком ссылок shared_ptr ).
Reply
Перевод прикольный получился. Я правильно понимаю, что лямбды тут продолжают жить в узлах списка и после срабатывания, держа счетчики ссылок? Как правильно поосвобождать замыкания - обнулить next_getter после использования?
Reply
То, что cached_next нельзя объявить как const и инициализировать при создании.
> Как правильно поосвобождать замыкания - обнулить next_getter после использования?
Про это я не подумал, что можно так оптимизировать. Конкретно данный код и без этого работает без утечек памяти.
А если мы сделаем классический список чисел фиббоначи через zipWith с самим собой - то это не поможет.
Вот тут valgrind жалуется на утечку памяти: https://gist.github.com/dobrokot/0ebc9c9fbd55050dcee7
Чтобы их поосвобождать - нужен garbage collector, можно переписать на питоне/JavaScript/Java.
Reply
Решение на D:
http://dpaste.dzfl.pl/d35215cb3983
Тут change строит список мутабельно в один проход и без лишних выделений памяти, но возвращает его как immutable.
(не обошлось без одного каста внутри, но он не существенен)
Reply
Reply
Leave a comment