metaclass: (Default)
[personal profile] metaclass
Читаю про катаморфизмы и FSharp. Вообще, изначально это я искал ответ на этот вопрос, но зачитался и забыл.

Там приводится пример, как выразить foldBack (оно же foldr) через fold(оно же foldl) с помощью continuations. И выглядит это как будто мы заменяем использование стека в случае не-tail-recursive функции таким же использованием памяти из head. Причем в случае стека выделение и удаление памяти достаточно дешевое, а вот что будет в случае обычной памяти - вопрос загадочный. Непонятно, есть ли тогда какие-нибудь преимущества у такого преобразования не-tail-recursive функции в tail-recursive?

Date: 2010-09-13 05:56 pm (UTC)
From: [identity profile] antilamer.livejournal.com
Нет никаких преимуществ, обыкновенное извращение.

Date: 2010-09-14 06:18 am (UTC)
From: [identity profile] plumqqz.livejournal.com


"От Радослава ко Хотеславу. возьми у прасола 2 гривене и 5 куно". (1-я стр.).
"Якове брате, еби лежа, ебехото, аесово".(2-я строчка)


"Радослав дает указание своему брату Хотеславу: "Возьми у прасола (торговца) 2 гривны и 5 кун". Это указание Хотеславу резко не понравилось; возможно, брат отсылает его к прасолу вместо того, чтобы просто отдать долг (есть аналогии этой ситуации в новгородской грамоте 690). Он ответил язвительно и не стесняясь формой выражения. Обращение - "Якове брате" (а не Радославе) - по-видимому, ироническое или даже саркастическое. Хотеслав называет брата не мирским, а крестильным именем, да еще со словом брате; надо полагать, это было уместно лишь в церковной или в особо торжественной ситуации, но никак не в сочетании с последующей грубостью. Примерный смысл ответа - "не оригинальничай" (веди себя, как все).

Date: 2010-09-14 06:46 am (UTC)
From: [identity profile] metaclass.livejournal.com
Отлично, можно на работе использовать :)

Date: 2010-09-14 09:19 am (UTC)
From: [identity profile] dsorokin.blogspot.com (from livejournal.com)
Иногда все же есть смысл, потому что .NET поддерживает TCO. Только есть нюансы, когда такая оптимизация не работает.

Date: 2010-09-14 09:27 am (UTC)
From: [identity profile] antilamer.livejournal.com
То-то и оно, что вообще никакого смысла нет. При применении полученного continuation'а все равно стек будет наворачиваться.

Date: 2010-09-14 12:03 pm (UTC)
From: [identity profile] dsorokin.blogspot.com (from livejournal.com)
Не совсем понял. В данном примере из той статьи смысла нет или, вообще, стек наворачивается всегда?

Кстати, в исходниках Async есть забавный комментарий (там продолжения используются):

"F# don't always take tailcalls to functions returning 'unit' because this is represented as type 'void' in the underlying IL. Hence we don't use the 'unit' return type here, and instead invent our own type."

Date: 2010-09-14 12:05 pm (UTC)
From: [identity profile] antilamer.livejournal.com
Я не вглядывался в эту конкретную статью, но я помню другую статью, где тоже foldr выражался через foldl или наоборот.
Там вместо того, чтобы сделать нормальный foldr, с помощью foldl строилось замыкание, которое потом сделает foldr.
Так вот, это замыкание для своего *выполнения* требует такого же линейного объема *стека*, а не кучи (а само по себе еще и занимает место в куче).

Date: 2010-09-14 01:02 pm (UTC)
From: [identity profile] dsorokin.blogspot.com (from livejournal.com)
Ну, бывает. Тут засады возможны.

Посмотрел еще раз пример FoldBack. Вроде бы, выглядит логично (но куда проще было бы взять и переписать все через надежный Async :). Только unit как возвращаемый тип несколько беспокоит меня. Если я правильно понял тот комментарий разработчиков F#, то такое продолжение как в статье может запросто съесть и стек на некоторых версиях .NET, а может и сработать как надо.

Date: 2010-09-15 04:21 am (UTC)
From: [identity profile] dsorokin.blogspot.com (from livejournal.com)
Кстати, туплю... Стек не должен съедаться. Функция FoldBack полиморфна, а потому тип unit будет заменен компилятором на внутренний тип Unit. Тогда значение () просто станет null. То есть, злобного void'а не будет. Условия для TOC будут благоприятными.

Date: 2010-09-13 05:59 pm (UTC)
From: [identity profile] blacklion.livejournal.com
Стек, особенно в 32-бит мультитреде, может быть куда меньше хипа.

Date: 2010-09-13 06:12 pm (UTC)
From: [identity profile] gds.livejournal.com
стек бывает ограничен жостко (обычно в опциях линкера устанавливается), тогда как хип растёт согласно имеющейся памяти (а то и своп используется, если есть).
Например, кое-где я использую формально типо-небезопасную библиотеку (хотя там с типами всё хорошо, но не доказано), но чуть более медленную, зато tail-recursive на всех функциях, работающих со списками.

Date: 2010-09-13 06:31 pm (UTC)
From: [identity profile] raydac.livejournal.com
в случае рекурсии прикинь какой у тебя отладочный стек вызовов JVM попытается построить для объекта Exception и это при нехватке памяти то, так что разница есть

Date: 2010-09-13 07:18 pm (UTC)
From: [identity profile] theiced.livejournal.com
фиолетовый крокодильчики летать

Date: 2010-09-13 07:26 pm (UTC)
From: [identity profile] usovalx.livejournal.com
Не знаю как там с производительностью аллокатора в .Net, но в том-же ocaml выделение памяти в куче чудовищно быстрое.

Date: 2010-09-13 08:34 pm (UTC)
From: [identity profile] gds.livejournal.com
но на стеке -- быстрее, поэтому стандартный List.map выигрывает по скорости у алгоритма, выделяющего на хипе и далее небезопасно (Obj) меняющего cons cell. (хотя, в целом, всё получается безопасно, кодэ см. в extLib.)
Собственно, потому и не меняют List.map в stdlib, что текущая версия на мелких списках чудо как хороша. (а именно, с текущим мусорщиком лучше не сделать.)
А для больших объёмов рекомендуют не списки, а что-то побыстрее.

Date: 2010-09-14 07:43 pm (UTC)
From: [identity profile] mchrome-cat.livejournal.com
Кстати, если не ошибаюсь, в chicken scheme первое поколение кучи на стеке и лежит.

Date: 2010-09-13 09:01 pm (UTC)
From: [identity profile] migmit.livejournal.com
Ну, появляется возможность делать call/cc.

Date: 2010-09-13 09:28 pm (UTC)
From: [identity profile] usovalx.livejournal.com
Если я правильно понимаю migmit, то продолжение в случае call/cc выделяется на хипе и может быть передано вверх.

Date: 2010-09-14 04:56 am (UTC)
From: [identity profile] migmit.livejournal.com
Если не ошибаюсь, речь идёт о CPS transform. Коли так, см. The 90 minutes Scheme to C compiler.

Date: 2010-09-14 07:39 pm (UTC)
From: [identity profile] mchrome-cat.livejournal.com
Кстати, существует книжка от Andrew Appel - "Compiling with continuations", где он по идее (я сам не читал) подробно рассказывает, зачем нужен cps.

Profile

metaclass: (Default)
metaclass

April 2017

S M T W T F S
      1
2345678
9101112 131415
16171819202122
23242526272829
30      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 1st, 2025 08:30 pm
Powered by Dreamwidth Studios