Comments 23
Самомодифицирующийся код вообще штука крайне дырявая по своей сути, да и отладчики и анализаторы малость с ума сходят от такого.
+10
К тому же, он не поддаётся JIT-компиляции, и тратится время на парсинг нового кода. Генерировать код во время загрузки — нормально, генерировать функцию каждую рекурсию — тормоза.
0
Относитесь к этому, как к макросам на препроцессоре Си. Тоже страшная вещь, из-за которой могут возникнуть трудноотлавливаемые ошибки (да и отладчикам с анализаторами туго), но программисты на Си нередко их используют :-)
+1
Зачем в приведенном примере вообще рекурсия и даже отдельная функция? Всё можно было сделать циклом с аккумулятором. А если рекурсия разветвляющаяся (типа заливки или двоичного дерева), лучше использовать массив-стек.
0
Вижу, у кого-то есть противоположное мнение. Не могли бы вы разъяснить?
0
Минус я не ставил, но попробую ответить: just for fun
+1
Статья — о хвостовой рекурсии, а не о подсчете чисел Фибоначчи. Любая рекурсивная функция (из тех, что можно переписать в вид с хвостовой рекурсией) сгодилась бы, но рекурсивный алгоритм подсчета числ Фибоначчи используется здесь (а также во многих других местах) как стандартный пример рекурсии.
+3
Вероятно, что автор просто не нашел лучше примера, чем просто описать крайне простую операцию через хвостовую рекурсию. Это крайне похоже на пример с факториалом, который считают через рекурсию. (Пример неудачный, я с вами согласен)
У меня было другое представление о хвостовой рекурсии (это набросок, подробнее в вики):
Так почему же несогласны? Автор попытался изложить материал на примере, пускай и неудачном, но за что его так сильно пинать?
У меня было другое представление о хвостовой рекурсии (это набросок, подробнее в вики):
function A()
{
/*условия*/
B();
}
function B()
{
/* условия */
A();
}
Так почему же несогласны? Автор попытался изложить материал на примере, пускай и неудачном, но за что его так сильно пинать?
+3
Тут дело не в примере. Хвостовая рекурсия всегда может быть записана как цикл с аккумулятором, так что единственное зачем это нужно — just for fun.
0
ну это как когда объясняют вычитание на примере «у тебя было 3 яблока, ты отдал одно Васе ...» и тот кому объясняют спрашивает «а почему, собственно, я должен отдавать яблоки Васе?»
+4
Данные функции даны как примеры! Они выполняют свою роль демонстрации метода.
0
Для ненормального программирование — вполне сойдёт.
Надо только не забыть внутрь текста для eval добавить комментарий, что тут полная жопа и дебажить даже не стоит пытаться.
Надо только не забыть внутрь текста для eval добавить комментарий, что тут полная жопа и дебажить даже не стоит пытаться.
+5
Вместо
А так — довольно интересное решение, жаль контекст объявления функции теряется.
return eval("var $tail$function = function "+name+"("+args.join(",")+") {"+newBody+"};$tail$function");
можно обойтисьreturn Function(args.join(','),newBody)
А так — довольно интересное решение, жаль контекст объявления функции теряется.
+1
Контекст легко вернуть:
var that = this;
return function () {
return Function(args.join(','), newBody).call(that);
}
0
Не о том контексте речь — речь о области видимости переменных, если так понятней.
var foo=21;
!function(){
var foo=42;
function fn1(){
console.log(foo)}
var src=fn1.toString();
var fn2=Function(src.substring(src.indexOf('{')+1,src.lastIndexOf('}')));
fn1();//=>42
fn2();//=>21
}()
С eval'ом примерно та же ситуация, но с другого бока — функция объявляется не в глобальном контексте, а в контексте замыкания Function.prototype.tail.+2
Клёва. А почему бы подобное не сделать в общем случае? Вроде же, понятно, когда вызов хвостовой в общем случае.
0
Вы имеете в виду хвостовые вызовы других функций (не себя)? В теле одной функции этого так просто не сделаешь, получится подобие трамплина, который описан по ссылке в статье. Это медленно. Да, можно написать такой препроцессор, который хвостовые вызовы преобразует так, как требуется в этой статье.
0
Sign up to leave a comment.
Эмуляция хвостовой рекурсии в JavaScript