metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2010-09-13 05:45 pm
Entry tags:

Принудительная хвостовая рекурсия: жрать память вместо стека?

Читаю про катаморфизмы и FSharp. Вообще, изначально это я искал ответ на этот вопрос, но зачитался и забыл.

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

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

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


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


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

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

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

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

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

Кстати, в исходниках 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."

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

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

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

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