Перевод статьи Эвана Миллера — The Mathematiclal Hacker.
Профессия программиста благословенна большим числом одаренных авторов. Сегодня я остановлю свое внимание на трех моих любимых — Эрике Реймонде, Поле Грэме и Стиве Йегге. Сделаю я это потому что они, как мне кажется, не сходятся со мной во мнении о том, что математика имеет значение (и будет иметь) для программиста-практика.
Их мысли могут быть сведены к следующим:
- Эрик Реймонд: Математика не нужна, за исключением таких специализированных областей, как 3D графика и научные вычисления.
- Пол Грэм: Математика является своего рода садом Дзен из которого черпают вдохновение.
- Стив Йегге: Математика дает базовые знания компьютерной науки, и каждый может найти много интересных статей по математике на Википедии.
Все эти утверждения я считаю близорукими.
В ограниченном смысле, каждая из этих точек зрения верна. Если Вы системный или сетевой программист как Реймонд, то можете справляться со своей работой не используя ничего, кроме умножения и деления по модулю. Грэм в свою очередь прав, что математика может быть источником метафор, а Йегге — что вычисления можно свести к математическому формализму (что часто любят повторять хакеры, использующие Lisp).
Все они сходятся в одном: с точки зрения решения повседневных рутинных задач, математика по существу бесполезна. Программисты на Lisp (как нам говорят) должны быть благодарны, что математика использовалась для разработки лямбда-вычислений, но сегодня математика больше форма личного просветления, нежели инструмент, с помощью которого можно что-либо сделать.
Это мнение ошибочно. Оно стало распространенным потому, что можно быть продуктивным и хорошо компенсируемым программистом — даже первоклассным хакером — без знания науки или математики. Но я думаю, что большинство программистов, которые всерьез воспринимают то, чем они занимаются, должны разбираться в вычислениях (настоящих), линейной алгебре и статистике. Причина этого не имеет ничего общего с “программированием” как таковым — компиляторами, структурами данных и всем остальным — а, скорее, связана с ролью программирования в экономике.
История бизнеса двадцатого века представляет собой серию преобразований, посредством которых отрасли, которые “не нуждались в математике” вдруг оказались сильно зависимые от нее. Статистический контроль качества поднял на новый уровень промышленность, экономика сельского хозяйства преобразовала фермерство, дисперсионный анализ произвел революцию в химической и фармацевтической промышленностях, линейное программирование изменило лицо управления цепочками поставок в логистике, а уравнение Блэка-Шоулза сделало рынок из ничего. Совсем недавно “Moneyball” методы перебрали на себя управление в спорте. И существует еще множество таких примеров.
Какова же связь этих нововведений и компьютерного программирования? Рассмотрим определение Эриком Реймондом слова “хак” (hack), такого желанного и являющегося смыслом существования любого уважающего себя хакера: хак — это невероятно хороший и, возможно, времязатратный кусок работы, делающий именно то, что нужно. В таком понимании, математика была “хакерской” деятельностью на протяжении более ста лет.
В конце концов компьютер был изобретен для решения математических задач, а не для выполнения компиляторов и текстовых процессоров. Автоматизированное решение проблем в машиностроении, горнодобывающей промышленности, сельском хозяйстве, транспортной и оборонной сфере представляет огромную ценность для общества на протяжении последних семидесяти лет. Я рискнул бы поспорить на триллион долларов, что если учитывать поражение Германии из-за достижений линейного программирования, и капитуляцию Японии из-за успехов численных вычислений, то значение будет неизмеримо.
Тем не менее, наши великие авторы-хакеры редко упоминают такого рода математические “хаки”. Причина, я думаю, в том, что “хакерская литература” в большинстве своем написана программистами на Lisp, а они зачастую пребывают в неведении о возможностях прикладной математики. Хотя я благодарен за то, что у нас так много хороших статей, написанных Lisp-программистами, и все же склоняюсь к тому, что они рисуют искаженную картину того, чем является нынешнее программирование и чем должно стать. Читая Рэймонда, Грэма и Йегге складывается впечатление (а все они считают себя Lisp-хакерами), что конечная цель программирования — это сделать программу более мощную, нежели те, которые ей предшествовали, обычно добавляя слои абстракции. Назовем это “школа программирования на Lisp”.
Существует еще одна школа, которая не очень хорошо представлена в литературе на протяжении многих лет, но которая, несомненно, произвела более положительное влияние на экономику. Назовем ее “Школа программирования на Fortran”. Которая, как я считаю, хорошо обобщена доктором Адамом Розенбергом, называющим себя последним бизоном промышленной математики. Вместо того, чтобы рассматривать математику, как продвинутый инструмент, зарезервированный для чрезвычайно специализированных компьютерных приложений, школа программистов на Fortran рассматривает компьютер, как продвинутый инструмент для выполнения математических операций. Исторически сложилось так, что программисты школы Fortran работали в промышленности или государственных учреждениях с более техническим уклоном (NASA, оборонное ведомство и т. д.). Они часто высмеиваются Lisp-программистами за их неумение пользоваться рекурсией. (Смотрите сатирическую статью Real Programmers Don't Use PASCAL и если Вам покажется, что это не честно, смотрите Dr. Rosenberg's Style Guide).
Насмешки, я думаю, должны быть направлены совсем в другую сторону. В отличии от традиций Fortran (который может гордиться тем, что “отправил человека на Луну” и поддерживает критически важные инфраструктуры в банковской сфере, коммуникациях и т. д.), культура Lisp почти умышленно игнорирует математику. Это игнорирование замаскировано разговорами о формализме и инстинктивным преклонением перед лямбда-вычислениями, которые как Сумма Теологии, являются замкнутой вычислительной Вселенной, которая проливает мало света на окружающий мир.
Чтобы оценить, как активно незнание математики увековечено в культуре Lisp, рассмотрим традиционное введение в рекурсию в любом функциональном программировании. Это всего два варианта — вычисление чисел Фибоначчи и вычисление факториала.
Самое распространенное решение в учебнике — рекурсивное: вычисляем значение числа на основании числа, стоящего перед ним, а стоящего перед ним — на основании числа, стоящего перед числом, стоящим перед ним и так далее, пока не достигнем “базового случая” имеющего определенное решение. Это классический пример дидактического программирования, демонстрирующий предполагаемую полезность рекурсивных методов.
“Расширенные” обсуждения могли бы рассматривать такие инженерные соображения, как поведение хвоста вызова или возможность запоминания результатов.
Но редко в этих обсуждениях вы можете найти обоснованные математические соображения. Если цель состоит в вычислении чисел Фибоначчи или факториала, то правильное решение не рекурсивная функция, а знание математики.
Вычисление чисел Фибоначчи можно следующим образом реализовать на С:
long int fib(unsigned long int n)
{
return lround((pow(0.5 + 0.5 * sqrt(5.0), n) - pow(0.5 - 0.5 * sqrt(5.0), n)) / sqrt(5.0));
}
Ни рекурсия ни даже цикл не требуются, поскольку аналитическое решение было найдено еще в семнадцатом веке. Точно также, если требуется вычислить факториал, программист должен уметь использовать системные лог-гамма функции, как показано в следующем коде на С:
long int fac(unsigned long int n)
{
return lround(exp(lgamma(n + 1)));
}
Опять же, рекурсия не требуется для тех, кто знает что факториал на самом деле является частным случаем гамма-функции. (Реализация лог-гамма функции как правило является полиномиальной аппроксимацией, на вычисление которой тратится постоянное время).
Несмотря на эстетические достоинства, приписываемые функциональному программированию, я нахожу приведенные решения более изящными, чем их рекурсивные аналоги. Они выполняются за постоянное (а не линейное) время, и они легко адаптируются для работы с входящими данными с плавающей точкой. Более того, они подталкивают программиста задаться вопросами: почему уравнения Фибоначчи содержат квадратный корень с пяти? Что значит взять факториал фракции? Эти вопросы имеют увлекательный ответ, который не так легко осмыслить, руководствуясь одним только рекуррентным соотношением.
После написания своего рекурсивного решения, программист на Lisp скорее всего задаст следующий бессмысленный вопрос: как я могу уменьшить эти две функции до оной?
Проблемы с традициями программирования на Lisp связаны с тем, что они слишком сосредоточены на задаче программирования — компиляторах, абстракции, редакторах и т. д. — а не проблемах вне программирования. Я предполагаю, что догматики школы программирования на Lisp — Реймонд, Грэм и Йегге — “не нуждаются в математике”, потому что тратят свое время на то, чтобы сделать код более абстрактным. Такое
Хотя первые годы двадцать первого века говорят в пользу философии школы программирования на Lisp, я предсказываю, что середина века будет принадлежать программистам Fortran’овской школы, которые способны успешно применять математику для решения практических задач. Очень заманчиво заявлять, что для решения большинства задач в программировании “не нужна математика”, но это верно ровно на столько, на сколько верно и то, что производство и управление цепочкой поставок или бейсбол не нуждаются в математике. Высшая математика кажется совершенно ненужной для современных практиков, но только до тех пор, пока не выяснится, что математические понятия — это правильный путь для решения проблемы здесь и сейчас. После этого математика становится жизненно необходимой.
Есть две причины, по которым я оптимистически настроен относительно будущего математики в компьютерном программировании. Первая связана с ростом объема данных, генерируемых Web-компаниями (“Большими Данными”). С появлением новых типов информации, увеличивается и число уравнений, которые могут быть применены для обработки этих данных. По этой причине существует много интересных передовых методов машинного обучения, но даже простые статистические методы могут быть полезны во многих приложениях. Математика применяемая к бизнес-данным будет давать более глубокое понимание бизнеса, более эффективные финансовые операции, лучшие продукты (например рекомендации), новые продукты (например, услуги прогнозирования).
Вторая причина связана с тем, что среднестатистический покупатель имеет теперь больше информации, чем когда либо до этого, и математика поможет навести в ней порядок или хотя бы сделать ее более привлекательной. Области применения, которые традиционно считались “научными вычислениями” (например, географические информационные системы или обработка изображений) теперь представляет интерес для рядового пользователя, который имеет свою коллекцию цифровых снимков с данными геотегинга. Instagram, к примеру, был построен на нескольких уравнениях, преобразовывающих цветовые каналы изображения. Понимание математики может помочь программисту в решении практических проблем для пользователя, а также наделит его бесценным опытом.
В конце концов, математика не помогает в понимании компьютерного программирования. Речь идет не о поиске метафор или о понимании “основ”, которые никогда не будут применены на практике. Математика, скорее, это инструмент для понимания строения мира: движения планет, построения структуры данных, восприятия цветов или любой из множества вещей, которые могут быть более понятны, если применить к ним уравнения. А это уже на прямую касается работы хакера — выяснить, как работает кусок кода, который будет использоваться снова и снова.
Стоит ли нам вернуться в те старые добрые времена, когда люди программировали на Fortran и все было построено на массивах? Вряд ли. Все, что нам нужно, это включить математику в образование хакеров. Хакеры, выросшие только на принципах школы программирования на Lisp, имели только одного родителя. (Другой родитель по-видимому, был слишком занят на работе). Нам нужны примеры, туториалы и военные истории, где математика с успехом применяется на практике в компьютерных программах. Также хвастовство не должно являться естественным для большинства программистов, нам нужны хакеры, которые будут ликовать только в том случае, когда будет найдено новое и интересное применение математики. Нам нужен праздник научного любопытства.
И на конец, нам нужно новое поколение начинающих хакеров, которые должны включить математику в свою программу самоподготовки. Нам нужны студенты со знанием физики, техники, линейной алгебры, статистики и численных вычислений. И нам нужно, чтобы они научили своих старших коллег, которые выросли в неведении о таких вещах. С неустанным распространением данных и с предстоящим исчезновением Fortran’овской старой гвардии, появляются широкие возможности для начинающих хакеров-математиков изменить этот мир своим более строгим
Автор: desperius