Pull to refresh

Хакер-математик

Reading time8 min
Views46K
Перевод статьи Эвана Миллера — The Mathematiclal Hacker.

Профессия программиста благословенна большим числом одаренных авторов. Сегодня я остановлюсь на трех моих любимых – Эрике Реймонде, Поле Грэме и Стиве Йегге. Сделаю я это потому, что они, как мне кажется, не сходятся со мной во мнении о том, что математика имеет (и будет иметь) значение для программиста-практика.

Их мысли могут быть сведены к следующим:

  • Эрик Реймонд (Eric Raymond): Математика не нужна, за исключением таких специализированных областей, как 3D графика и научные вычисления.
  • Пол Грэм (Paul Graham): Математика – это своего рода сад Дзен из которого черпают вдохновение.
  • Стив Йегге (Steve Yegge): Математика исполняет роль фундаментального знания для информатики, и каждый может найти много интересных статей по математике на Википедии.

Все эти утверждения я считаю близорукими.

В определенном смысле, каждая из этих точек зрения верна. Если Вы системный или сетевой программист как Реймонд, то можете справляться со своей работой не используя ничего, кроме умножения и деления по модулю. Грэм в свою очередь прав, что математика может быть источником метафор, а Йегге – что вычисления можно свести к математическому формализму (что часто любят повторять хакеры, использующие 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-компаниями (“Big Data”). С появлением новых типов информации, увеличивается и число уравнений, которые могут быть применены для обработки этих данных. По этой причине существует большой интерес к продвинутым методам машинного обучения, но даже простые статистические методы могут быть полезны во многих приложениях. Математика применяемая к бизнес-данным будет давать более глубокое понимание бизнеса, более эффективные финансовые операции, лучшие продукты (например рекомендации), новые продукты (например, услуги прогнозирования).

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

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

Стоит ли нам вернуться в те старые добрые времена, когда люди программировали на Fortran и все было построено на массивах? Вряд ли. Все, что нам нужно, это включить прикладную математику в образование хакеров. Хакеры, выросшие только на принципах школы программирования на Lisp, имели только одного родителя. (Другой родитель по-видимому, был слишком занят на работе). Нам нужны примеры, туториалы и военные истории, где нетривиальная математика с успехом применяется на практике в компьютерных программах. Хотя хвастовство не присуще большинству программистов, нам нужно, чтобы хакеры ликовали всякий раз, когда будет найдено новое и интересное применение математики. Нам нужен праздник научного любопытства.

И наконец, нам нужно новое поколение начинающих хакеров, которые должны включить математику в свою программу самоподготовки. Нам нужны студенты со знанием физики, техники, линейной алгебры, статистики и численных вычислений. И нам нужно, чтобы они научили своих старших коллег, которые выросли в неведении о таких вещах. С неустанным распространением данных и с предстоящим исчезновением Fortran’овской старой гвардии, появляются широкие возможности для начинающих хакеров-математиков изменить этот мир своим более строгим мышлением.
Tags:
Hubs:
+82
Comments40

Articles