Представитель Шуры Люберецкого в ЖЖ (brat_luber) wrote,
Представитель Шуры Люберецкого в ЖЖ
brat_luber

Categories:

SICP, середина

Неспешно читаю-решаю упражнения из SICP. Дошел где-то до середины книги, так что могу написать какое-то более развернутое мнение.

Начну с плюсов. Как недавно заметил [info]infowatch, в “околокомпьютерных” областях достаточно велико количество самоучек, а “официальные” учебные планы зачастую неадекватны – следовательно, любой более-менее приличный “компьютерщик” в той или иной степени оказывается “самоучкой”. Недостатки такого подхода очевидны – нет “систематичности” знаний и “единой картины мира”.

Вообще, складывается такое впечатление, что отечественное программирование во многом представляет собой некий “карго-культ”, копирующий внешние стороны такового в США. Кто-то рассказал про интервью при приеме на работу в Google и Microsoft – и все-все-все, включая распоследнюю “веб-студию”, бросаются спрашивать про сортировку и красно-белые деревья. То, что когда-то эти вопросы позволяли Google и Microsoft набирать исключительно студентов-отличников ведущих американских ВУЗов – в расчет не принимается. Аналогичное впечатление производят и учебные планы – например, вопросы, связанные с индуктивными вычислениями и прочей рекурсией явно заимствованы из курсов с использованием Lisp наподобие SICP. На “традиционных” у нас C и Pascal они выглядят довольно дико. В общем, самоучки учат самоучек.

Что делать в такой ситуации? Наверное, лучше всего “забить” на попытки Рабиновича напеть Паваротти и “самоучиться” по первоисточникам – тем более, что ситуация с ними сегодня лучше, чем десяток лет назад. Например, SICP достаточно неплохо переведена, и теперь не придется вычленять “разумное, доброе, вечное” из кривого пересказа. Не надо “плеваться” от того, что эта книга – всего лишь “вводный курс” программирования. В свое время, например, кто-то обратил внимание на возраст присутствующих в аудитории на видеолекциях (в интернете выложены видеозаписи лекций по этому курсу) – и там было немало вполне взрослых людей, возможно даже и с опытом работы.

Более того, из-за особенностей применяемого диалекта Lisp, в SICP уже в конце первой главы переходят к вполне содержательным задачам – то есть демонстрирующим не какие-то конструкции языка, а различные подходы к программированию. Это отличает ее от других “вводных курсов”, где берется какой-то язык программирования (раньше дико модным был Pascal), подробно изучаются его конструкции, а из “программирования” до обучающихся доводится лишь одна истина – что, оказывается, можно набрать на клавиатуре какой-то текст, затем нажать нужные кнопки и компьютер волшебным образом выполнит то, что хотел программист.

Что меня особенно удивило – я ни разу не видел более краткого описания ООП, чем один-единственный абзац в SICP (в начале 3 главы):

Существует мощная стратегия разработки, которая особенно хорошо подходит для построения программ, моделирующих физические системы: воспроизводить в структуре программы структуру моделируемой системы. Для каждого объекта в системе мы строим соответствующий ему вычислительный объект. Для каждого действия в системе определяем в рамках нашей вычислительной модели символьную операцию. Используя эту стратегию, мы надеемся, что расширение нашей модели на новые объекты или действия не потребует стратегических изменений в программе, а позволит обойтись только добавлением новых символьных аналогов этих объектов или действий. Если наша организация системы окажется удачной, то для добавления новых возможностей или отладки старых нам придется работать только с ограниченной частью системы.

Между прочим, волшебные слова “инкапсуляция, наследование и полиморфизм” в книге не встречаются ни разу. В любой “нормальной” книжке утверждается, что якобы они и составляют так называемое “объектно-ориентированное программирование” (которого не существует – но это отдельная тема), а здесь удалось обойтись вообще без них.

Разумеется, что все рассматриваемые в SICP подходы к программированию можно показать и с использованием других языков. Например, встречаются решения задач оттуда на Common Lisp (это, правда, не считается – так как он все равно достаточно близок к Scheme), Python, Javascript и даже на C# – в общем, “на чем угодно”. Правда, ни один из этих языков (за исключением, разве что, Common Lisp) не подходит для того, чтобы продемонстрировать все эти подходы сразу.

Теперь к недостаткам – благо “хвалебных” отзывов о SICP и без меня предостаточно. Можно было бы начать с классического “Не покупайте эту книгу“, но у меня к SICP другие претензии. Меня, как математика, поражают вольности с численными методами. Любой программист считает себя непревзойденным специалистом в этой области – но это далеко не так. Не последнее место в формировании этого заблуждения занимают книги по программированию, в которых численные методы рассматриваются в отрыве от их “содержания”, как обычные алгоритмы.

Например, в главе 1.3.1 приводятся формулы численного интегрирования, и утверждается, что “определенный интеграл … можно численно оценить с помощью формулы” (”the definite integral … can be approximated numerically using the formula “) – при этом не раскрывается ни законность этой оценки (что можно “простить”), ни ее точность. Правда, вычисляются два приближения для одного интеграла, меньшее значение переменной dx соответствует большей точности – и только! В упражнении 1.29 приводится формула Симпсона, утверждается, что она представляет собой “более точный метод численного интегрирования” (в чем эта точность заключается – не объясняется), а затем предлагается проинтегрировать с ее помощью кубический многочлен – якобы это должно “доказать”, что она “более точна”. Удивительно, но результат оказывается ближе к истинному значению – но это не сходимость, как в первом случае, а просто свойство формулы Симпсона – она дает точное значение при интегрировании кубических многочленов.

Чуть дальше появляются более “страшные” вольности. Например, в “определении” производной (оно необходимо для метода Ньютона) предлагается заменить стремящееся к 0 dx каким-то “очень малым” значением. Сказать, что это приближение, видимо, религия не позволяет.

В конце раздела 1.3 находим упражнение 1.45 – от которого я пришел в ужас. Сообщается, что метод Ньютона не работает для некоторых функций, например, для извлечения корня n-й степени. Предлагается использовать многократное “торможение усреднением” (average damping – этот термин я не встречал нигде, кроме SICP), а “кратность” его применения установить – держитесь – экспериментально! Да, читатель SICP, скорее всего, не сможет доказать полученное утверждение – но предложение “экспериментально” доказать математическое утверждение, согласно современным представлениям, дико само по себе. Может, не стоит вообще давать такие задачи?

Практически весь раздел 1.3 посвящен численным методам в том или ином виде – и везде есть какие-то “косяки”. Да, большинство читателей их не заметит – но здесь я не могу разделять их восторгов по поводу книги. Тут требуется несколько более высокий уровень строгости в изложении. В целом книга крайне хороша с “программистской” точки зрения, но как только речь заходит о математических вопросах – то начинается “тушите свет, сливайте воду”. Численные методы – хорошая демонстрация для абстракций, связанных с использованием “функций высших порядков” (для которых, правда, в математике придуманы свои термины – например, “функционал” или “оператор”), но они требуют все же несколько другого подхода.

Продолжение, как говорится, следует.

Запись опубликована в блоге Шуры Люберецкого. Вы можете оставлять свои комментарии там, используя свое имя пользователя из ЖЖ (вход по OpenID).

Tags: книги, программирование
Subscribe

Comments for this post were disabled by the author