- 1
- 2
- 3
fib 1 = 1
fib 2 = 1
fib n = fib(n-1) + fib (n-2)
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+133
fib 1 = 1
fib 2 = 1
fib n = fib(n-1) + fib (n-2)
Хаскель это вам не математика, тут надо и вычислительную сложность учитывать.
да и пример учебный
надо {{0,1},{1,1}} возвести в степень n за логарифм и умножить на {1,1}
(и плохо если это сделано в ущерб производительности)
Может иммутабильные переменные? В функциональных языках приняты не мутабильные переменные.
Чаще всего они и не нужны. Обычно, если умеешь нормально писать программы, то на 200 строк кода ~ 1 переменная, а остальные константы. Так что проблем то и нет.
Посмотри в сторону F#. На мой взгляд, читаемый паскаля-синтаксис в функциональном языке. И никаких тебе монад. Можно даже императивно писать.
И всё, язык сам провоцирует на чистый стиль.
Можно на оригинальном языке?
Ещё я бы отделил dusty- просто грязные функции (которые смотрят снаружи себя, например, GetTime) и dirty- ОЧЕНЬ грязные функции (которые меняют состояние снаружи себя, например, Random). Разница в том, например, что заставить отладчик посмотреть значение dusty-функции ещё можно, а значение dirty-функции - почти невозможно, ведь всё нарушится.
Любая функция из внешней библиотеки объявляется как очень грязная, само собой. Но с возможностью через хаки заставить компилятор понимать её, как чистую.
Ну и понятно, что чистая функция может вызывать только чистые, dusty - чистые и dusty, а dirty - любые.
Нужно сделать, что-бы по умолчанию все static переменные (такие, что в С++) или глобальные переменные создавались по экземпляру на поток. Тогда проблем с синхронизацией между потоками не будет, не смотря на императивный стиль. А если хочешь погемороиться, то добавляешь ключевое слово shared к объявлению переменной и получаешь что хотел - одна переменная на все потоки.
Хуже того в современных C#\Java даже нельзя некоторые вещи ограничить, как например в С++. Например, в этих языках, даже нельзя указать, что-бы какие-то переменные были константными.
Особенно это плохо с параметрами, передаваемыми в функцию.
Передаёшь свой объект в функцию программиста из соседнего отдела. А эта функция твой объект безнаказанно портит, не предупреждая об этом во время компиляции!
То есть модификатора const на входные параметры нету?
В Дельфи он есть, но он не мешает испортить содержимое динмассива (ссылочный тип потому что). То есть действует только на POD-типы.
В Аде он есть (только слово не const, а in), динмассивы портить нельзя (хитрые объекты - можно, но только если их составить определённым образом, "с дырой", так вот даже стандартный вектор был немного переделан так, чтобы убрать для него "дырку"), вешается на параметры по-умолчанию. Но с этим тоже есть косяк - вот например, я хочу скопировать объект и испортить копию. Всё нормально, но если объект был собран на стеке, то нафига его копировать, он и так снаружи сразу же забудется? Говорят, правда, что это есть такая оптимизация у компилятора, чтобы это разруливать.
Например, код С++:
Что-бы быть уверенным что функция не испортит объект - нужно писсимизировать код, создавая копию объекта
Тфу. На сишарп\ява конечно же.
В С++ эта проблема не стоит, тк там можно параметры при передачи в функцию делать константными:
зы:фикс для второго кода из поста: Ну и естественно TConcreteObject o инициализировать нужно.
Ну и const_cast никто не отменял, хотя это уже на совести пользователя.
В Аде, например, это решается так: все указатели объекта приватны, все методы, что меняют данные по указателю, объявляются, как меняющие состояние объекта. Но это получается целиком на совести того, что пишет класс этого объекта.
Да, запрещенно. Можно вызывать только const методы
Естественно, этот метод изменять члены объекта не может.
Ну для указателей в С++ можно конкретно указывать что там константное, а что нет, например:
Если указатель указывает на внешний объект, то это забота внешнего объекта быть константным или нет.
Если внешний объект константный, то его без хаков будет не поменять.
Например - класс строки. Сами символы лежат где-то по указателю, в поле не хранятся, есть только поле для указателя на них. Они для нашего класса - внешний объект. Но если их менять в const методе, то будет лажа. То есть это на совести разработчика класса.
Да...
Видимо, имелась ввиду ситуация типа:
Сейчас покажу эту оптимизацию. Жаль что она ручками делается, хотя вроде какие-то упрощённые её варианты делают и компиляторы.
Это очень полезная возможность, особенно для оптимизации работы с математикой (например, матрицы или вектора). Все же все перегруженные операторы в С++ - это те же функции, а значит в случае: Создаваться на стеке временные объекты будут "много раз за строку", которые можно ради оптимизации безболезненно испортить. Поэтому часто пишут перегрузку операций под оба варианта объектов (для нормальных и временных (правильное название lvalue и rvalue по стандарту)).
Это почему это? Дороже создание потока, может быть, но не на много.
Тут ещё забавнее проблема будет. Допустим, в одной части программы мы используем потоки для каких-то сложных вычислений, требующих много переменных потока. В другой части — используем кучу короткоживущих нитей. Эти части могут быть писаны разными людьми, даже быть внутри разных библиотек (детали реализации). И вот окажется, что при создании любого потока нужно будет выделить и проинициализировать ещё тысячи переменных потока, используемых где-то там (а нам не нужных). И вызвать деструкторы при завершении потока.
Ну зачем же? Ненужные накладные расходы. Инициализируем только те переменные, что используются в потоке, а остальные не инициализируем, раз не нужны. В языке D так и сделано.
Помоему, она там опциональна. Вплоть до того, что в одном коде часть конструкций её использует, а часть нет. Вообщем как и в С++\CLI.
>Тогда уровень косвенности при доступе может ещё возрасти.
А может и нет. Как реализовали.
Пиздец. Типичное крестоблядское уёбищное решение.
У нормальных людей всё делается так: по умолчанию удобство и надёжность, а для скорости надо немного извратиться. А в С++ - так: по умолчанию скорость, а чтобы оно не глючило, надо извращаться. Счастливой отладки, хули.
Сказать "ты не учёл один момент", или "ты ничего не понял", и продолжить чем-то очевидным, с чем оппонент и не думал спорить.
Понятно.
Мертвый язык же. И вообще много лишних букв писать приходится.
живёт в F#
Откуда вы знаете, как мы думаем?
нет, просто код в топике ни о чём. Обычная демонстрация конструкций языка, это ничего не говорит ни о качестве мануала, ни, тем более, языка.