Старик Дарвин был прав? Языки программирования и «Происхождение видов»
Однажды мы с коллегами задумались вот о чём. Существует хронология языков программирования — список дат «с начала времён». Понятное дело, что каждый из них появился под влиянием собственных условий и для выполнения конкретных задач. Но ведь между языками есть тесные связи, и часто эти связи — эволюционные. А кто у нас главный по эволюции? Правильно — Чарльз Дарвин. Именно к его дню рождения 12 февраля мы и решили подготовить эту статью.
Подобная статья на Хабре уже есть, и она довольно интересная. Мы решили развить и дополнить тему. Для этого возьмём основные факторы эволюции, описанные в «Происхождении видов» Чарльза Дарвина, и попробуем провести параллели между эволюцией языков программирования и эволюцией живых существ.
Не воспринимайте эту статью слишком серьёзно. Это одна большая метафора, которая позволяет взглянуть на вещи под другим углом.
Наследственная изменчивость
Суть этого принципа состоит в том, что в процессе жизни у существ возникают мутации, которые могут передаваться по наследству. Это обуславливает постепенные изменения одного вида: формы тела, строения органов чувств, окраски и т. д.
И тут самое время вспомнить знаменитую диаграмму O«Reilly. Несмотря на то, что она заканчивается 2004 годом, на ней наглядно показано, как языки связаны между собой и кто чей потомок. Например, Python не был изобретён с нуля. В его основу легли наработки языка АBC, над которым ранее трудился «отец» Python Гвидо ван Россум. Из языка Modula-3 он заимствовал реализацию модулей и исключений. В нём можно встретить элементы Algol-68, C, C++, SmallTalk и др. В версии 2.0 появились list comprehensions, пришедшие из языков Haskell и SETL. И это только одна история. В прошлом других распространённых сегодня языков можно найти не меньше интересных предков. Но ведь и у предков была своя изменчивость. Например, тот же Modula-3 ведёт свою историю от Pascal.
Каждый из них в своё время соответствовал определённым требованиям, например:
отсутствие привязки к конкретной платформе;
простота для пользователей, отсутствие лишних деталей (их обработкой занимается машина);
возможность заметить и обработать ошибки в коде;
нефатальность ошибок для всей системы и др.
Соответствие языка подобным требованиям — знак его адаптивности к изменившимся условиям среды. Среди этих условий может быть что угодно: новые платформы, требования рынка, тренды в разработке и даже просто случайное стечение обстоятельств.
Так, например, насчёт происхождения языка C ходит несколько легенд. Согласно одной из них, Деннис Ритчи и Брайан Керниган любили играть в одну игру на сервере Bell Labs, которую потом понадобилось перенести на офисный компьютер. Для него пришлось написать операционную систему, но когда её стали переносить на другой компьютер, оказалось, что система написана на ассемблере. Это и сподвигло коллег создать высокоуровневый язык, позволяющий переносить ОС с одной машины на другую. Не знаем, имеет ли эта легенда что-то общее с реальностью, но это неплохая иллюстрация изменившихся условий среды. Возникла острая потребность — появился язык.
Естественный и искусственный отбор
Естественный отбор — это основной эволюционный фактор, отвечающий за то, чтобы выживали только наиболее приспособленные, а неприспособленные погибали. Что ж, в программировании долго искать не придётся.
Для современных проектов почти не используются такие языки, как COBOL, Algol, LISP, Pascal, Fortran, Ada и др. Причина их ухода в целом одна — они перестали отвечать современным требованиям. Например, COBOL был слишком сложным и требовал больших вычислительных мощностей, а также имел мало общего с синтаксисом прочих языков. А Pascal, несмотря на простоту освоения и удобство, проиграл в конкурентной борьбе C, который оказался более гибким языком, с большим количеством возможностей и приближённостью к железу.
Так же как и в реальной жизни, отбор в среде языков программирования может быть не только естественным, но и искусственным, когда люди специально создают новые решения, призванные заменить старые. Причём реальная необходимость может заменяться настойчивым желанием компаний внедрить на рынок свой язык.
Генная инженерия в этой области представлена новыми языками, призванными, по задумке авторов, исправить все негативные стороны предшественников.
В 2014 году компания Apple презентовала Swift. К слову об изменчивости, он вобрал в себя элементы C#, Python, Object-C, Haskell, CLU и некоторых других языков. Swift должен был ускорить и упростить разработку, быть быстрее (выше, сильнее и так далее) Objective-C. Но привело ли это к исчезновению последнего? Нет, он продолжает активно применяться, а изучать Swift начинающим часто рекомендуют не вместо, а вместе с Objective-C.
Ещё один пример — Dart от Google, который позиционировался как замена JavaScript ещё в 2011 году. Тут, думаем, даже и комментировать нечего. Открываем рейтинг языков программирования (например, этот, основанный на запросах) и видим Dart на 37-й позиции, тогда как JavaScript уверенно держится в десятке.
Борьба за существование
Это один из важнейших эволюционных факторов, включающий в себя внутривидовую и межвидовую борьбу, а также борьбу с неблагоприятными условиями среды.
Конкурируют ли между собой разные языки программирования? Отчасти. Например, Python долгое время соперничал с С, Java и JavaScript… в рейтингах. В отчёте GitHub 2021 года он занимал вторую строчку. А в индексе TIOBE, составленном на основе данных поисковых запросов, в 2021 году он попал на третье место, к концу года сместился на второе, а в январе 2022-го занял верхнюю позицию. Другие рейтинги периодически удивляют новостями из серии «Древнейший язык программирования восстал из мёртвых» (статья 2021 года про Fortran, который на тот момент взлетел на целых 30 строчек вверх).
А что с внутривидовой борьбой? Признаем, что не совсем корректно называть разные версии Python одним «видом», так как их различия довольно существенны. Тем не менее, это стадии развития одного и того же языка, которые до определённого момента обладали обратной совместимостью. Переход с Python 2 на Python 3 был непростым для многих. Третья версия не полностью совместима с кодом, написанным на Python 2. И если проект живой и вносить изменения в код можно, то переход может вызвать затруднения, но, скорее всего, не станет камнем преткновения. Но в legacy-проектах, у которых есть только поддержка, переход может затянуться на годы. К счастью, большинство библиотек переписаны на Python 3, который в итоге всё же побеждает в борьбе.
Изоляция
Обособленность одних популяций от других (например, на островах) является мощным эволюционным фактором, влияющим на видообразование. Уникальными в биологическом смысле являются многие растения, животные и птицы с изолированных континентов, островов, водоёмов, пещер и т. д. Виды, попадая в подобную среду, начинают развиваться независимо от всего остального мира.
Есть ли аналоги в программировании? Тоже да. Быстрое развитие смартфонов и смарт-часов создало такие изолированные «острова» для кода. В области мобильных приложений свою нишу, помимо Java, заняли Kotlin и Swift. Хотя их изоляция, конечно, условная. Например, Swift расширяет ареал: на нём уже можно писать приложения для Windows, macOS, Linux.
Критика дарвинизма
Параллели с развитием языков программирования можно провести не только между принципами дарвинизма, но и между некоторыми пунктами их критики.
Например, креационизм. Почему мы вообще говорим о каком-то развитии, если у большинства языков есть авторы? Джеймс Гослинг, Бьёрн Страуструп, Деннис Ритчи, Гвидо ван Россум когда-то действительно либо заложили основы, либо целиком описали их особенности. Но не стоит забывать, что эти люди — не теоретики. Они практикующие программисты, которые работали с разными языками на протяжении своей карьеры. Тот же Гослинг не планировал создавать новый язык во время работы в Green Project, а пробовал адаптировать для нужд проекта C++, но в конечном счёте сделать этого не получилось. Одной из основных особенностей языка должна была стать независимость от железа, поэтому Гослингу пришлось вспомнить о UCSD Pascal, который имеет такое свойство. И это просто один из примеров. Получается, что сферических творцов в вакууме не существует. Современные языки программирования так или иначе вобрали в себя элементы ранее существующих, переосмыслив их под новые требования и задачи.
Ещё один из аргументов противников дарвинизма состоит в том, что у живых существ есть чрезмерно сложные органы и системы (например, глаза). С одной стороны, не верится, что они могли возникнуть путём небольших случайных изменений, а с другой — непонятно, как они могли давать преимущество в борьбе за выживание на самых ранних этапах, когда самого органа ещё не было. И если уж мы проводим параллели, то программирование — неплохое доказательство того, что сложные структуры как раз и создаются путём мелких длительных изменений. Несмотря на то, что язык C++ — свободный, существует целая сложная система его стандартизации и соответствующий международный комитет. Стандарт обновляется с 1998 года, в последние годы значительно чаще. С 2016 года в России существует рабочая группа по развитию C++, которая собирает предложения по стандарту, организует их обсуждения, а также готовит материалы к защите в Комитете ISO C++. Собственное законодательство внутри одного языка — что может быть сложнее? Но это продукт его естественного развития, что видно по истории стандартов.
Кстати, Дарвин связан с программированием не только вот так опосредованно, но и напрямую. Его именем назван язык программирования — Darwin programming language. Он предназначен для биоинформатики и вычислительной биологии. Этот язык действует как своего рода калькулятор, помогающий обрабатывать данные о геномах биологических видов. Не знаем, насколько широко он сейчас используется, но название символичное.
Итог
Что мы хотели сказать этой статьёй? Что языки программирования — живые системы, которые формируются под воздействием среды. Что общие изменения языка определяются накоплением малых случайных изменений. Что в этих изменениях участвуют буквально все, кто работает с конкретным языком. И даже те, кто не работает напрямую — проджекты, дизайнеры, UX и CX, да и сами пользователи, наконец. Наверное, каждому стоит в качестве профилактики вспоминать об этом, когда после релиза весь отдел разгребает множество задач или когда мозг начинает плавиться от чужого кода.