Мне кажется, люди привыкли к использованию рекурсии в ограниченном виде - кажется, это показал Ноам Хомский. Но на деле люди редко углубляются больше чем на три уровня, а если и углубляются, то обычно в стиле хвостовой рекурсии. Понимание рекурсии есть сложнейшее искусство. А ведь рекурсия - один из самых мощных инструментов программиста, если его как следует освоить. И поэтому заботиться о корректности надо всегда.
Сейбел:Тем не менее многие пытались разработать языки или системы, дающие возможность написать программу непрограммисту. Считаете ли вы эти попытки обреченными на неудачу - ведь дело не в правильности синтаксиса, а в том, что программирование неестественно по природе.
Стил:Да. И, кроме того, люди сосредоточены на главном, они не думают о пограничных случаях, о сложных случаях, о маловероятных случаях. А именно в таких случаях начинаются разногласия - как сделать правильно.
Иногда я спрашиваю студента: “Что будет в таком-то случае?” - “То-то и то-то”. И тут же кто-нибудь вскакивает: “Нет, должно быть вот так!” Вот такие вещи и надо отражать в программной спецификации.
Неслучайно для описания процесса программирования мы пользуемся терминами из арсенала магии. Мы говорим: что-то произошло как по волшебству или автоматически. Думаю, это оттого, что заставить машину сделать нужную тебе вещь - почти то же самое, что добиться исполнения желания.
Посмотрите: героям волшебных сказок достаточно придумать желание, махнуть рукой - и вот оно выполнено. И, конечно, сказки полны поучительных ситуаций: герой забыл учесть пограничный случай - и из-за этого случилось что-то нехорошее.
Сейбел:Возьмем “Fantasia” - она в том числе об опасности рекурсии.
Стил:“Fantasia” и рекурсия, да. Или “Я хочу быть самым богатым человеком в стране”, - в итоге все становятся бедняками, а он остается при своем. Такое в волшебных сказках случается, потому что люди забывают о разных путях, ведущих к цели. Если думать только о главном желании, пренебрегая деталями, много чего не стыкуется.
Сейбел:Каков же урок волшебных сказок? Гэндальфы становятся великими магами путем тяжких трудов и зубрежки заклинаний, а легкого пути нет?
Стил:Да. Другой пример. Допустим, я говорю своему умному компьютеру: “Хочу, чтобы имена в моей телефонной книге шли по алфавиту”, - и он выбрасывает все имена, кроме первого. Алфавитный порядок не нарушен, но это не то, чего мне хотелось. И оказывается, что спецификацию вида “хочу упорядочить имена по алфавиту, без потери данных, без дублирования” чертовски трудно написать.
Сейбел:Получается, есть свойства языков, которые делают труд программистов, освоивших эту неестественную работу, более продуктивным? Вы сейчас проектируете язык, у вас должно быть мнение на этот счет.
Стил:Я уже говорил: нельзя пренебрегать точностью. В то же время мы можем создавать инструменты для повышения точности. Мы не можем сделать эту процедуру тривиальной, но можем помочь избежать некоторых ошибок. Вместо того чтобы допускать циклическое переполнение 32-битных целых, можно сделать обнаружение арифметического переполнения или предоставить возможность работы с большими числами. Сейчас реализация всего этого обходится дороже, но я считаю, что работа с настоящими большими числами дает немного меньше ошибок для некоторых видов программирования. Программисты и создатели алгоритмов для операционных систем все время попадают в одну и ту же ловушку. Они говорят: “Нам нужно синхронизировать фазы, так что будем брать по одному числу. При начале новой фазы вычисления будем увеличивать на единицу какую-нибудь переменную, получать новое число - и тогда все участники будут уверены, что работают в одной и той же фазе, пока не начнется какая-нибудь операция”. Это работает на практике, но с 32-битными числами вы досчитаете до 4 миллиардов довольно быстро. Что будет в случае циклического переполнения? Все будет в порядке? Или нет? Многие подобные алгоритмы в компьютерной литературе содержат эту небольшую ошибку. Что если какой-нибудь поток застопорится со 2-й по 32-ю итерацию? Маловероятно, но все-таки возможно. Надо или как-то смягчить эту проблему в смысле корректности, или все просчитать и показать, что такой вариант настолько маловероятен, что беспокоиться не о чем. Или, возможно, для вас приемлем один компьютерный сбой в день. Суть в том, что надо проанализировать проблему, а не игнорировать ее. Тот факт, что счетчик может переполниться, - проблема еле заметная, большинство программистов она не затронет. Но для остальных это ловушка в их алгоритмах.
Читать дальше
Конец ознакомительного отрывка
Купить книгу