- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
function fib<T>(n: T) {
return n <= 2 ? n : fib(n - 1) + fib(n - 2);
}
function main()
{
print (fib(5));
print (fib(6.0));
}
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
0
function fib<T>(n: T) {
return n <= 2 ? n : fib(n - 1) + fib(n - 2);
}
function main()
{
print (fib(5));
print (fib(6.0));
}
я вам принес "рекурсивные генерики"..... внимание вопрос... а каким таким хером получилось вычеслить тут возвращаемый тип, а ?
Возможно вы имели в виду индуктивные?
В яжасцрипт только один численный тип, float64?
В момент инстанциации?
Рекурсивная функция вполне может "зациклиться".
То, что рекурсивная функция не зареркурсируется до бесконечности, еще надо доказать
Конпелятор подумает -- "бесконечная функция без побочек -- это UB, значит она не будет вызвана, значит можно выбрать любой тип, пусть будет void".
Ниже конпелятор тебе поясняет эту ошибку: template argument deduction/substitution failed, couldn't deduce template parameter `T1'.
Т.е. он в момент конпеляции четвертой строчки искал какой-нибудь подходящий shit, но вариант с шаблоном не подошёл т.к. невозможно определить T1, а других вариантов и нету.
Но ты не указал T1 в строке 4 явно, а вывести его (по правилам крестов, когда вывод от аргументов к результатам) нельзя. Поэтому данный шаблон не подошёл. А других вариантов не нашлось.
Да, это какой-то тип содержащий ноль, но почему int32? В принципе, подходит любой другой тип с нулём. И функция может вернуть что угодно при a != 0.
Он и про P=NP докажет
В данном случае, возможно.
Но перепиши код как
И, без обработки всего остального кода, тип возвращаемого значения в точности не узнаешь.
Тайпскрипт -- это не система доказательства теорем, сойдёт и более консервативный тип в духе int | float или даже any...
... и возвращаемое значение функции было разработано настолько, что туда помещался любой объект.
Вообще в тайпскрипте скучно. Не то, что в крестах — перегрузка операторов, (частичная) специализация, ADL... Вопрос, что вызовется, может стать увлекательной головоломкой.
Но с ним ничего нельзя было сделать, не вытащив обратно с помощью каста.
В С++ есть перезгрузка операторов
Яблоко минус int может быть груша
Предлагаю поработать нейронкой и дописать код, чтобы работало поведение.
1) return shit(a - 1) какой имеет возвращаемый тип? случайный? - нет. он всегда предопределён. а что определяет возвращаемый тип функции shit? это строка "return 0" и строка "return 1.0". больше return в коде нет. значит список типов возвращаемых в shit - всегда предопределен и он конечен.
к сожалению, нет. Он зависит от того, какого типа выражение "a - 1".
Допустим, оно типа "яблоки".
Но какого типа выражение "яблоки минус 1"?
Допустим, оно типа "апельсины".
Но какого типа выражение "апельсины минус один"?
И так до бесконечности.
Когда Алан Тюринг это понял, он обмокнул ножик в яде, разрезал яблоко, и съел половинку... и погиб:((((
И всё становится просто прекрасно и легко вычисляемо.
Ну да, мы же можем сказать, что в общем случае у нас такое вот поведение, но если тип равен именно апельсину, то логика вообще совершенно другая.
Кресты такие кресты
http://coliru.stacked-crooked.com/a/6f521a764aef91f5
Так то да, бывают забавные эффекты, когда один цпп файл видит хедер со специализацией, а во второй его подключить забыли и там работает общий случай. Но это в общем-то даже не UB, просто неприятные различия в поведении.
> кто первый
Не, там всё сложнее. В каждой точке, где ты вызываешь функцию, составляется список вариантов, фильтруется, сортируется и выбирается "самый подходящий". Если выживет несколько кандидатов -- будет ошибка, а не первый.
Это другое, это нарушение ODR когда одноимённая функция в разных юнитах трансляции как-то получилась с разным телом.
А у разных специализаций имена разные, линкер их не мержит между собой.
З.Ы. Но если ты напишешь в джвух файлах разные специализации для одного типа -- вот там да, имена совпали, нарушение ODR, UB, кишки, распидорасило.
Q: Почему одна и та же функция у меня в одном месте тормозит, а в другом летает?
A: Потому что нужно подключить petuh.hpp.
Реально ведь магия уровня Ruby: подключаешь файл, и всё начинает работать иначе
Наконец-то кто-то решил проблему остановки.
На js это очень просто: function f() { return f; }. А теперь расставь типы.
Блин, у них и на это ответ есть: type Fn = () => Fn.