powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Тяпничная хвостовая рекурсия.
56 сообщений из 56, показаны все 3 страниц
Тяпничная хвостовая рекурсия.
    #39570583
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет друзья.

Илья. Сов. Саша. Зяма. Дима. И все-все другие мемберы.

Давайте поговорим про хорошие сценарии использования рекурсий в С++.
Степанов в своей книге различает "хвостовую" и "строгую хвостовую рекурсию".

У меня соотв. Вопросы. В каких случаях она не детектируется и код будет собран как чисто-рекурсивный?

Спасибо всем.

Ваш покорный слуга
mayton
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39570606
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зависит от умности оптимизатора. Но чаще всего, только строгая разворачивается в цикл.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39570607
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
последний раз я это ковырял в третьем gcc лет пять назад, и классический пример не разворачивался.
Код: plaintext
1.
2.
3.
4.
int fact(n) {
  if (n==0) return 1;
  return n * fact(n-1);
}
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39570636
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
https://godbolt.org

Ставим для gcc что нибудь типа -O2 -m32
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39574325
x0n1x
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
сорри, Степанова не читал,
но всегда думал, что "оптимизация хвостовой рекурсии" может быть сделана уже на уровне машинного кода тупой заменой
Код: sql
1.
2.
CALL xxx
RET

на
Код: sql
1.
JMP xxx

(если мы знаем, что xxx - адрес начала этой же функции)

на уровне генерации машинного кода такая замена явно не сложнее
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39574491
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я вообще не знаю за Степанова, за строгую хвостовую рекурсию, но
оптимизироваться она может просто за счёт "схлопывания" фрейма стека: вместо того, чтобы при вызове функции
делать новый фрейм с пермеменными, новый вызов может использовать старый фрейм со старыми переменными, переписав их новыми значениями, если нужно.

Это ка бы не цикл, но эффективно как цикл.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39574704
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЭто ка бы не цикл, но эффективно как цикл.
Это цикл. Там goto на начало ))
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39574713
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,
слишком специфично под каждый компилятор

скорее всего только самые простые оптимизации под "строгую хвостовую рекурсию" если повезёт
в языке без явных гарантий нельзя полагаться на это 100%

https://habrahabr.ru/company/pvs-studio/blog/261027/
https://habrahabr.ru/company/pvs-studio/blog/261029/
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39574715
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

klirichekЯ, может, сейчас жутко крамольную вещь скажу…
Но не кажется ли, что в ДАННОМ случае вместо массажа опций компилятора и рассматривания дизассемблера можно просто написать goto в исходном коде и получить нужный результат независимо от положения звёзд?+1
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39574785
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Многие алгоритмы намного проще и понятнее выглядят именно в рекурсивной форме, потому что в итеративной форме надо явно хранить состояние, а в рекурсивной оно часто скрыто под капотом.
Поэтому не всегда можно просто "просто написать goto ")))
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39574880
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyМногие алгоритмы намного проще и понятнее выглядят именно в рекурсивной форме, потому что в итеративной форме надо явно хранить состояние, а в рекурсивной оно часто скрыто под капотом.
Поэтому не всегда можно просто "просто написать goto "))) "строгую хвостовую рекурсию".
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39574964
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Окей. Поскольку топик заглох я подкину дровишек.

В книге - А.Степанов Д.Роуз - От Математики к обобщенному программированию
Во главе 2.1 Степанов рассуждает о методе Египетского умножения. Кратко поясню суть.
Один из множетелей раскладывается на сумму двоичных коэффициентов 1,2,4...e.t.c.
и раскрываются скобки. Далее - умножение сводится к сложению. Есть поинт в том
что количество операций будет минимально. Рекурсия используется в качестве базового
алгоритма.

Далее в главе 2.2 Степанов пытается уйти от рекурсии и фактичкески заменить ее итерацией.
Но для этого он делает несколько эквивалентных преобразований.

Приводится также определение:

Говорят что функция обладает свойством строгой хвостовой рекурсии если во всех хвостовых
рекурсивных вызовах формальные параметры совпадают с соответствующими аргументами.

С позволения Степанова я публикую фрагмент кода (не финальный).
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
int mult_acc3(int r,int n,int a){
  if (odd(n)){
    r = r + a;
    if (n == 1) return r;
  }
  n = half(n);
  a = a + a;
  return mult_acc3(r,n,a);
}



Далее идет еще цепочка ручных трансформаций где Степанов сводит это к итерации.

По сабжу меня интересовал только рекурсивный вариант. Поэтому я на этом остановлюсь.

Зависимые функции четности и деления пополам - half(),odd() я поскипаю. Они тривиальны.

Интересует также связь этого метода с оптимизацией умножения в длинных целых.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575062
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonОдин из множетелей раскладывается на сумму двоичных коэффициентов 1,2,4...e.t.c.
и раскрываются скобки.
если о цели: я может чего не понимаю, но какой смысл выполнять обычный алгоритм "умножение столбиком"?
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575065
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)если о цели: я может чего не понимаю, но какой смысл выполнять обычный алгоритм "умножение столбиком"?Когда пишется собственная реализация арифметики больших чисел - смысл появляется.
Причины написания могут быть разные.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575067
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov,

я в плане алгоритма, зачем использовать заведомо O(n^2), можно для начала взять хотя бы тот же алгоритм Карацубы
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575070
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)зачем использовать заведомо O(n^2), можно для начала взять хотя бы тот же алгоритм КарацубыАлгоритм Карацубы настолько сложен, что оправдывает себя только на очень больших числах. Или я неправ?
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575072
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorovkealon(Ruslan)зачем использовать заведомо O(n^2), можно для начала взять хотя бы тот же алгоритм КарацубыАлгоритм Карацубы настолько сложен, что оправдывает себя только на очень больших числах. Или я неправ?все они имеют определённый лимит от которого становятся разумны
Алгоритм Фюррера например хоть и O(N*Ln(n)), но проигрывает на мелких числах
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575075
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)maytonОдин из множетелей раскладывается на сумму двоичных коэффициентов 1,2,4...e.t.c.
и раскрываются скобки.
если о цели: я может чего не понимаю, но какой смысл выполнять обычный алгоритм "умножение столбиком"?
Я понимаю внутренне ваше возмущение. Скажу честно что я не сравнивал метод Карацубы
и метод Египтян. Более того я даже не считаю что он (Египетский) хорош. Просто тема топика - рекурсия
и я взял первый материал который под рукой оказался.

А по теме египтян могу предположить что умножение в столбик было им недоступно скорее
всего по причине того что их система записи чисел - непозиционная.

Видимо сравнение и сложение для них было проще.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575079
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)Basil A. Sidorovпропущено...
Алгоритм Карацубы настолько сложен, что оправдывает себя только на очень больших числах. Или я неправ?все они имеют определённый лимит от которого становятся разумны
Алгоритм Фюррера например хоть и O(N*Ln(n)), но проигрывает на мелких числах
Окей. Давайте их тоже обсудим.

Но на правах топик-стартера я прошу учесть хештеги #C++ и #рекурсия.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575087
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

да нету никакого возмущения, просто фактически это умножение в столбик, с предварительным переводом одного из операндов в двоичную форму.

собственно по теме:
повлиять на алгоритм компилятора мы в принципе не особо можем, а вот выдать ему код без рекурсии - можем.
ИМХО если идти напрямую от комбинатора неподвижной точки, то можно написать генератор кода для любой итеративной функции, которую возможно так разложить.
Вот только зачем?
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575114
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет. Как раз интересно дать ему код с рекурсией. Но на выходе получить safe-stack-overflow код.

Ну... если не повезло - то хотя-бы увидеть Warning уровня компилляции. "Не шмогла..." дескыть.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575139
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)...
если о цели: я может чего не понимаю, но какой смысл выполнять обычный алгоритм "умножение столбиком"?

ничего общего от слова совсем:
столбик сформулирован в терминах позиционного представления числа
а египетскому умножению (он же - russian peasant algorithm) до лампады представление числа.
Он работает в терминах удвоения, деления пополам и определения четности.
К тому, что понятно как удваивать - 100% шансы применить этот алгоритм.
Попробуйте применить столбик к размножению строк.
А египетское умножение отменно обеспечивает умножение целых чисел, возведения их в степень,
возведение в степень квадратных матриц, кватернионов и строк, а как бонус еще и вычисление чисел Фибоначчи.
Возведения в целую степень вообще всего, что может быть мыслимо как полугруппа с ассоциативной операцией.
Книжка эта про обобщенное программирование, а египетское умножение - базовый алгоритм, на примере которого и раскрывается представление об обобщенном программировании.

kealon(Ruslan)Basil A. Sidorov,

я в плане алгоритма, зачем использовать заведомо O(n^2), можно для начала взять хотя бы тот же алгоритм Карацубы
Зря вы это сказали.
Алгоритмы анализируются в ценах элементарных (базовых для анализа) операций.
Для этого алгоритма элементарной операцией является операция сложения.
И выполняется она Log(n) раз.
То есть, с точки зрения выполнения базовых операций, с ростом масштаба задачи, данный алгоритм масштабируется
как суперконстанта по отношению к числу выполняемых базовых операций.
Надо совсем не иметь представления об обсуждаемом предмете, чтобы задавать вопрос - зачем рассматривать такой алгоритм.

maytonЗависимые функции четности и деления пополам - half(),odd() я поскипаю. Они тривиальны.
Дело не в том, тривиальны они или нет, а в том, какое поведение они ожидают от применяемого к ним параметра.
В данном случае - поведение (целого) числа.
Именно это и определяет направление дальнейшего будущего обобщения.
Поэтому таким алгоритмом имеет смысл возводить квадратные матрицы в целую степень или размножать строки целое число раз, при условии, что базовая операция умножения матрицы или склейки строк будет предоставлена той полугруппой, которую представляет соответствующий параметр функции.
А вот умножать строки на строки, или матрицы на матрицы таким алгоритмом нельзя.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575140
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
bool odd(int n) { return n & 0x1; }

int half(int n) { return n >> 1; }
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575142
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

не знаю, зачем ты это написал.
Если ты опять про "элементарность реализации", то я опять о том, что существо дела в другом.

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

Т.е. параметры у алгоритма неравноценны:
а - может быть представлено любым типом, обеспечивающим поведение полугруппы
n - может быть только типом, эквивалентным целому числу.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575143
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Четность. И целочисленное деление на два.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575144
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ок
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575145
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Точно ОК?
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575148
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
точно.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575187
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boobyничего общего от слова совсем:
столбик сформулирован в терминах позиционного представления числаи к чему он приводит любое число? вангую что к двоичному представлению

boobykealon(Ruslan)Basil A. Sidorov,

я в плане алгоритма, зачем использовать заведомо O(n^2), можно для начала взять хотя бы тот же алгоритм Карацубы
Зря вы это сказали.
Алгоритмы анализируются в ценах элементарных (базовых для анализа) операций.
Для этого алгоритма элементарной операцией является операция сложения.
И выполняется она Log(n) раз.
То есть, с точки зрения выполнения базовых операций, с ростом масштаба задачи, данный алгоритм масштабируется
как суперконстанта по отношению к числу выполняемых базовых операций.
Надо совсем не иметь представления об обсуждаемом предмете, чтобы задавать вопрос - зачем рассматривать такой алгоритм.с тем, что сложение базовая операция для длинных чисел я не соглашусь, всё таки у неё цена O(N)
отсюда и выходит O(N^2) для оценки "умножения столбиком". В контексте умножения двух чисел - это бесполезный алгоритм.

maytonНет. Как раз интересно дать ему код с рекурсией. Но на выходе получить safe-stack-overflow код.

Ну... если не повезло - то хотя-бы увидеть Warning уровня компилляции. "Не шмогла..." дескыть.
Далеко полез, чё по проще заставить его посчитать - и то проблема. Компиляторы довольно ограниченная "вещь в себе".
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39575227
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне кажется что Буби как-то сходу внес в топик сам вопро определения алгебры для нашего алгоритма.
Мне сложно говорить на эту тему т.к. надо сначала почитать соотв. теорию, а времени
нет и возникают вопросы более насущные и актуальные. Забегая вперед... в последних
главах книги Степанов касается обобщений чисел. Но я-бы предложил поскипать это
и пока говорить о рекурсии.

P.S. Вобщем ... просил я только масла на завтрак мне подать (с) Баллада о королевском бутерброде
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39577181
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owlпоследний раз я это ковырял в третьем gcc лет пять назад, и классический пример не разворачивался.
Код: plaintext
1.
2.
3.
4.
int fact(n) {
  if (n==0) return 1;
  return n * fact(n-1);
}



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

Anatoly MoskovskyMasterZivЭто ка бы не цикл, но эффективно как цикл.
Это цикл. Там goto на начало ))

Вероятно речь шла не о полученном наборе инструкций после трансляции программы, а об исходном синтаксисе)
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Тяпничная хвостовая рекурсия.
    #39788139
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Докину в тему.

Вариант хвостовой рекурсии в Scala. Для сравнения.
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
def fact(x: BigInt): BigInt = {
    if (x < 0)
      throw new IllegalArgumentException

    @tailrec def facttail(x: BigInt, accum: BigInt): BigInt =
      if (x == 0)
        accum
      else
        facttail(x - 1, accum * x)

    facttail(x, 1)
}



В данном случае аннотация @tailrec дополнительно информирует компиллятор
о требовании размотки рекурсии в цикл. Не всякая рекурсия разматывается.
Должен присутсвовать аккумулятор.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39788222
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,
Scala - функциональный язык, не знаю как в нутрах компилятора сделано, но если так же как в хаскель, т.е. компилируется в комбинаторы, то вполне реальная вещь
kealon(Ruslan)ИМХО если идти напрямую от комбинатора неподвижной точки, то можно написать генератор кода для любой итеративной функции, которую возможно так разложить.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39788235
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возвращаясь к теме С++. Зачем Степанову понадобилась строгая хвостовая?
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39788238
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonВозвращаясь к теме С++. Зачем Степанову понадобилась строгая хвостовая?микроконтроллёры например, но то так, пальцем в небо

медленнно работают рекурсивные вызовы + непредсказуемое поведение
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #39790703
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Из стековерфлоу.
https://stackoverflow.com/questions/34125/which-if-any-c-compilers-do-tail-recursion-optimization#220660
Претендует на хвостовую. Но не строгая.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
#include <stdio.h>
static int atoi(const char *str, int n)
{
    if (str == 0 || *str == 0)
        return n;
    return atoi(str+1, n*10 + *str-'0');
}



Забавно если бы я хотел выровнять формальные параметры то сломал-бы простоту и лаконичность
всего atoi. Было-бы что-то вроде.
Код: plaintext
1.
2.
3.
 n = n * 10 + *str-'0';
 str++;
 return atoi(str, n);
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Тяпничная хвостовая рекурсия.
    #40032487
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще один пример с хвостиком. От Массачусетских языков. Кодинг - мой. И возможные баги тоже мои.

Первый исходник - лобовое решение факториала.
Второй - с оптимизацией. В книге пишут что tail-recursion обязателен для сертификации всех реализаций Scheme.
Код: python
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
;;; Recursive factorial,
;;; Language: MIT/GNU Scheme
;;; Dec-20, 2020 : mayton

(define (fact x)
   (cond
      ((= x 0) 1)
      ((= x 1) 1)
      (else (* x (fact (- x 1))))
   )
)

;;; The same, with tail recursion

(define (fact-tail x)
  (define (fact-internal partial-product x)
     (if (> x 1)
       (fact-internal (* x partial-product) (- x 1))
       partial-product
     )
  )
  (fact-internal 1 x)
)
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032503
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

давай функциональные языки не будем рассматривать, там всё фундаментально понятно и доказано когда можно и когда нельзя - 21059004
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032529
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Руслан. Большинство "инициативных" топиков здесь требуют немедленного ответа на вопрос "зачем".

Скорее всего низачем. Просто - игры разума.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032545
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton

Давайте поговорим про хорошие сценарии использования рекурсий в С++.
Степанов в своей книге различает "хвостовую" и "строгую хвостовую рекурсию".

А чем по Степанову хвостовая рекурсия отличается от строгой хвостовой?
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032548
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот тут-же цитата 21058333
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032558
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

я просто говорю, что для функциональных языков этот вопрос фундаментально закрыт - надо, отсюда и логичное требование в сертификации
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032621
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошо. Не будем трогать функциональные. Просто к слову пришлось.

Будем издеваться над императивными.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032647
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
mayton

Давайте поговорим про хорошие сценарии использования рекурсий в С++.
Степанов в своей книге различает "хвостовую" и "строгую хвостовую рекурсию".

А чем по Степанову хвостовая рекурсия отличается от строгой хвостовой?


Для строгой хвостовой рекурсии есть железобетонный, гарантированный алгоритм разворота
в простой цикл.
Поэтому, в таком случае, программист имеет право писать "красиво", а обученный компилятор
сделает "как надо".

Если алгоритм обладает строгой строгой хвостовой рекурсией, то использование удобной
рекурсивной записи программистом бесплатно с точки зрения накладных расходов.
"умный" компилятор рекурсию полностью исключит и заменит на цикл.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032651
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
petrav
пропущено...

А чем по Степанову хвостовая рекурсия отличается от строгой хвостовой?


Для строгой хвостовой рекурсии есть железобетонный, гарантированный алгоритм разворота
в простой цикл.
Поэтому, в таком случае, программист имеет право писать "красиво", а обученный компилятор
сделает "как надо".

Если алгоритм обладает строгой строгой хвостовой рекурсией, то использование удобной
рекурсивной записи программистом бесплатно с точки зрения накладных расходов.
"умный" компилятор рекурсию полностью исключит и заменит на цикл.

Спасибо. Вот вы понятно пояснили.

Тока мне кажется, что сама идея этой хвостовой рекурсией не совместима с C++. Что будет с
вызовом деструкторов локальных объектов? Правильно, они похерятся. Т.е. по хорошему
нужно вводить атрибут какой-то для таких функций: типа настаиваю на такой фишке, а
компилятор уже проверяет может или не может.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032662
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,

тут дела так стоят:
Использование рекурсии вообще какой-то - неотделимо от императивного программирования.
Заявить несовместимость рекурсии с языком эквивалентно заявлению о неспособности
реализовать в этом языке циклический алгоритм произвольного вида.

Рекурсия вообще - это идея циклического алгоритма вообще.
Специальные случаи вроде строгой хвостовой позволяют свести алгоритм к простому циклу.
Например, свести самому программисту (и не ошибиться при этом), даже если компилятор этого делать не умеет.
Делать это или нет - вопрос борьбы за время организации вызова и передачи параметров.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032666
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby,

ну, для каких-то случаев - еще и за размер стека.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032709
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Тока мне кажется, что сама идея этой хвостовой рекурсией не совместима с C++. Что будет с
вызовом деструкторов локальных объектов? Правильно, они похерятся. Т.е. по хорошему
нужно вводить атрибут какой-то для таких функций: типа настаиваю на такой фишке, а
компилятор уже проверяет может или не может.
почему они похерятся?
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032710
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
petrav
Тока мне кажется, что сама идея этой хвостовой рекурсией не совместима с C++. Что будет с
вызовом деструкторов локальных объектов? Правильно, они похерятся. Т.е. по хорошему
нужно вводить атрибут какой-то для таких функций: типа настаиваю на такой фишке, а
компилятор уже проверяет может или не может.
почему они похерятся?

Они (деструкторы) начнут вызываться в неправильной последовательности. Это принципиально.

Или же они вообще перестанут вызываться.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032717
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
kealon(Ruslan)
пропущено...
почему они похерятся?

Они (деструкторы) начнут вызываться в неправильной последовательности. Это принципиально.

Или же они вообще перестанут вызываться.

А как деструкторы связаны с хвостовой рекурсией?
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032720
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
petrav
пропущено...

Они (деструкторы) начнут вызываться в неправильной последовательности. Это принципиально.

Или же они вообще перестанут вызываться.

А как деструкторы связаны с хвостовой рекурсией?

Я понял тему топика так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
void foo(int a)
{
    ++a;
    if (a>6)
    {
        return;
    }
    else
    {
       foo(a);
    }
}


Я корректно всё понял? И вместо рекурсии в ассемблере будет jump на начало функции?
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032723
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
void foo(int a)
{
    ++a;
    if (a>6)
    {
        return;
    }
    else
    {
       foo(a);
    }
}


Я корректно всё понял? И вместо рекурсии будет jump на начало функции?

Я не силен в теории построения компилляторов. Но по моему свертка хвоста превращает рекурсию
в банальный loop. Как там в ассемблере делется loop? Я щас не помню. Много вариантов.
Да можно jump сделать. А можно JNZ (jump-non-zero-flag). Суть вобщем не в этом.
А в том что стек не будем потреблять.

И еще убийственная киллер фича всей функциональщины - все переменные в такой
функции становятся values. Константами. Раз нет цикла. То ничего и не меняется.

Вселенная с застывшим временем.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032726
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton

Я не силен в теории построения компилляторов. Но по моему свертка хвоста превращает рекурсию
в банальный loop. Как там в ассемблере делется loop? Я щас не помню. Много вариантов.
Да можно jump сделать. А можно JNZ (jump-non-zero-flag). Суть вобщем не в этом.
А в том что стек не будем потреблять.

И еще убийственная киллер фича всей функциональщины - все переменные в такой
функции становятся values. Константами. Раз нет цикла. То ничего и не меняется.

Вселенная с застывшим временем.

Отлично. Я как раз недавно смотрел научно популярный ролик как вернуть время назад. На Физике Побединского.
Но вернёмся к деструкторам и доработаем код.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
void foo(int a)
{
    MyObject obj;
    ++a;
    if (a>6)
    {
        return;
    }
    else
    {
       foo(a);
    }
}



Тут два варианта:

- При честной рекурсии у нас деструкторы класса MyObject вызываются в правильной последовательности.
- А при фокусах с разворачиванием рекурсии в цикл что с ними будет? ПНХ?
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032728
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,

в вашем примере для компилятора нет хвостовой рекурсии
так как вызов не хвостовой, он такой лишь на первый взгляд
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032733
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
petrav,

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

Конечно, я понимаю, что деструктор неявно вызывается в конце функции. Упрощённо.
Но что будет если MyObject изначально был алиасом к int, а потом я переделал MyObject на класс с деструктором?
Поэтому я сразу и написал, что тогда в язык нужно добавить атрибут к функции "настаиваю на хвостовой рекурсии".
Не получилось -- сбой компиляции.
...
Рейтинг: 0 / 0
Тяпничная хвостовая рекурсия.
    #40032745
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Поэтому я сразу и написал, что тогда в язык нужно добавить атрибут к функции "настаиваю на хвостовой рекурсии".
Не получилось -- сбой компиляции.
я тоже так думаю - "явное лучше неявного"
...
Рейтинг: 0 / 0
56 сообщений из 56, показаны все 3 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Тяпничная хвостовая рекурсия.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]