Субъективное применение языков
Если вы хотя бы немного близки к IT-области, то знаете, что языков программирования на свете существует целая куча. Их придумывают и придумывают, придумывают и придумывают, и нет им конца…
Однако если вы уже имеете некоторый реальный опыт программирования на нескольких разных языках, то должны понимать, что не задача выбирается под язык, а язык под задачу. Вот и рассмотрим разные классы этих задач, а заодно и мой субъективный выбор, какой из инструментов подходит лучше, а так же их плюсы и минусы.
Осторожно, тема холиварная, и все что под катом - только мое имхо!
Основной мой профиль - веб-разработка. Разных интерфейсов к чему бы то ни было по протоколу HTTP я наклепал уже довольно много, и технологий перепробовал тоже немало. Однако “сделать сайт” - слишком широкое понятие, поэтому они тоже бывают разные:
Сайты на готовых CMS. Для типичных и шаблонных вещей есть куча готовых, стабильных и достаточно расширяемых решений, и абсолютное большинство из них на PHP. Этот язык отличается своей относительной простотой и очень низким уровнем вхождения (что облегчает написание модулей/хаков к этим CMS). Благодаря наилегчайшему деплою и отличной стабильности в продакшне он идеально подходит для задач “ - Нужен блог через пять минут! - Да не вопрос, апач+пхп из пакетов и вордпресс, бац и работает”.
Простейшие веб-инструменты на коленке. Встроенный шаблонизатор (да что там, весь язык и есть шаблонизатор на стероидах), отсутствие необходимости думать об архитектуре и деплое дают возможность применять этот же PHP для задач “одна формочка из двух полей для записи в мускуль”. Сговнякал в один php-файл запрос к мускулю, сдобренный скопипастенной из ближайшего веб-ресурса версткой, и готово. Работает и есть не просит. Однако тут начинаются минусы: если вдруг форма вырастает до десятка полей, десяти таблиц со сложными связями и разными способами отображения, систему становится сложно поддерживать. Тут же вылезают другие недостатки пыха вроде совершенно неконсистентного именования функций и порядка их параметров, недостаточно развитого ООП (до 5.3, а у некоторых сисадминов даже минорный апдейт 5.2 на системах без пакетных менеджеров становится проблемой).
На этом сфера разумного применения PHP заканчивается, и на смену ему приходит Ruby.
Ruby, а точнее написанный на нем фреймворк Ruby on Rails - это лучшее на данный момент виденное мной решение для разработки сложных сайтов под ключ. Деплоить несколько сложнее, чем php, но увеличенное на полчаса время деплоя экономит килограммы нервных клеток программистам и сутки, недели и месяцы рабочего времени. Я даже не могу описать восторг, который я испытал, когда начал изучать эту платформу. Там все прекрасно и просто работает. Попробуйте сами!
Но Ruby не только web-язык, это еще и отличный язык общего назначения. Одной из его сильных сторон является построение DSL - миниязыков, описывающих предметную область. Это позволяет описывать простым, ясным и легкочитаемым языком действия, объекты и логику, которые в других языках будут потеряны среди обвязки и вспомогательного кода. У меня на одном сервере из компактного DSL в пол-экрана собираются многокилобайтные конфиги прокси, фаервола, dns и еще кучки сервисов. Собственно рельсы - в какой-то мере DSL для описания веб-приложений.
Однако за такую динамичность приходится платить - и в этом случае платой стала производительность. Интерпретатор Ruby ветки 1.8 действительно далеко не эталон быстродействия, но в ветке 1.9 с этой проблемой определенно что-то делают. Осталось только дождаться её (ветки 1.9) повсеместного распространения. В общем, Ruby не так хорошо подходит для задач, где нужна вычислительная-исполнительная мощность, вроде обработки больших объемов данных.
И тут на сцену выползает Python. Выползает потому что змея, а не потому что он тормоз, как раз наоборот :). У него очень быстрый интерпретатор, несмотря на довольно высокую динамичность. Но он не позволяет черно-магических трюков вроде модификации системных верхнеуровневых объектов, как это часто бывает в Ruby. А еще он очень легко расширяется на C++, и содержит кучу специализированных заточенных под конкретные задачи алгоритмов и структур, что еще повышает быстродействие при правильном их подборе.
Python так же прекрасно справляется с задачами автоматизации общего назначения, и во многом благодаря его поистине огромной стандартной библиотеке и философии “с батарейками в комплекте”. Практически все стандартные задачи решены, половина в стандартной библиотеке, а другая половина в доступных модулях, которые ставятся одной командой из системного репозитория или общего репозитория python-дополнений. Более того, есть просто офигительный фреймворк Twisted для построения асинхронных приложений, взаимодействующих с сетью. Он дает возможность как обрабатывать каждое событие самому, так и предоставляет мощные абстракции, в которых заботишься о логике, а не о деталях реализации. Есть у питона и аналог и прямой конкурент рельсов - Django. Выбор среди джанго и рельсами очень непрост, и, скорее всего, будет зависеть только от вашего вкуса, потому что свои задачи оба этих инструмента выполняют на 5+. Прекрасно, но почему же многие от питона плюются, как верблюды? Да просто у него синтаксис не как у всех. Чего стоят только одни отступы. Отступы? Да, отступы играют важную роль, и в отличие от других языков эта роль не просто декоративная, а самым что ни на есть прямым образом влияющая на ход исполнения программы. Здесь нет признака конца блока кода, а фактором, выделяющим этот блок, является увеличение индентации (сдвига от левого края). Кончились отступы - кончился и блок кода. А еще программист на Python постоянно чувствует себя Капитаном Очевидность. Тут явно всё: явно импортируются в область видимости другие модули, явно даже передается в метод класса параметр self, который аналог this в си-подобных языках. А еще… хотя ладно, забудем про питон. Давайте следующего.
Следующим у нас Bash. Строго говоря, это и не язык вообще. Это просто интерпретатор команд, к которому сбоку присобачили переменные и управляющие конструкции. Да и называется он не bash, так называется просто самый распространенный интерпретатор и диалект семейства shell-подобных языков. И лого у него я не нашел. Тем не менее, задачи для него имеются, и немало. Это интеграция существующих программ. Та самая философия Unix, когда у тебя много маленьких программ, делающих каждая свое дело, и надо их прицеплять одну к другой для выполнения более сложной задачи. Вот связующим звеном между программами и будет bash. Тут каждая строка есть запуск некоего процесса, передача его вывода на ввод другому посредством пайпа “|”, простейшая подстановка переменных в параметры запуска процесса, и в общем-то все.
Вот надо вам вытащить из веб-страницы некоторую строку по регулярке в файл, в других языках понадобится подключать библиотеку для работы с сетью/вебом, открывать соединение, получать страницу, потом проверять содержимое, открывать файл, и писать туда. А в bash? есть уже готовая программа для скачивания страниц, готовая программа для фильтра по регуляркам, и встроенная возможность вывода перенаправления в файл.
wget $url -O - | grep $regexp > $file |
Одна строка против пол-экрана кода. Круче некуда. Хотите повтор подключения в случае неудачи? В языке общего назначения придется обернуть программу в цикл, добавлять проверки, а в bash добавил ключ к wget и вуаля. Но как только приходится вылезти за пределы возможностей конкретного звена-программы в цепочке, или логика становится сложной и нелинейной, программирование на bash превращается в ад. Пробелы и кавычки в параметрах? Познайте все сложности экранирования. Сложные условия? Попробуйте разобраться в синтаксисе. Многократные вызовы и циклы? Почувствуйте оверхед запуска новых процессов. Ошибки? Не надейтесь на адекватные сообщения о них.
Perl. Язык общего назначения с неплохой динамикой. Но… дальше одни “но”. И из-за этих “но” все задачи, которые можно решить на перле, лучше решать на руби или питоне. Поехали:
Синтаксис. Это что-то с чем-то. На первый взгляд помесь си и шелла, но потом, как выясняется, используются все символы на клавиатуре. Ходят слухи, что 90% случайных последовательностей ascii-символов будут являться валидной программой на perl, особенно если сбалансировать открывающие и закрывающие скобки. Если ruby подталкивает писать код, который можно прочитать вслух и это будет правильным предложением на грамотном английском языке, а питон подталкивает к ясному и однозначному изложению логики, то перл подталкивает на написание страшных конструкций, которые выглядят как зацензуренное ругательство. Вы видели легендарный однострочник, выполняющий rm -rf ? Write-only language. Хотя надо признать, что Ruby унаследовал несколько таких страшных синтаксических перловых черт, но они там только в качестве альтернативы более удобным и понятным ООП-методам, да и догадаться что руби их поддерживает, не так просто.
Черная магия. Если магия есть и в руби, то там она белая. А тут… каждая вторая функция, если ей ничего не передать, работает с некоей “дефолтной переменной” $_. Другая половина функций имеет кучу побочных эффектов вроде установки глобальных переменных, флагов интерпретатора или еще чего.
Стандартная библиотека, а точнее её отсутствие. Расширений, которые можно поставить извне - много, но если они не упакованы вашим дистрибутивом, то это кранты. Абсолютно не управляемая штука.
Совершенно страшное комьюнити. Половина неадекватов, которые автоматизировали только свой домашний сервер, совершенно незнакомых с понятиями “сопровождение”, “документация”, “командная разработка”.
Возраст. Перл замер в развитии много лет назад. ООП? Костылем в лучшем случае. Паттерны? Однострочники легче писать. Исключения? open “>file” or die(“Can’t open file. Guess why.”);
Единственное премущество - его почему-то все-таки знает куча народу, и найти эникейщика со знанием перла проще, чем эникейщика с питоном или руби.
C/C++. На самом деле, C++ не есть “си с классами”. Впрочем, на эту тему много других холиваров. Компилируемый язык, довольно близкий к железу. Ручное управление памятью, ручные вызовы чего угодно. Можно прямо в код нафигачить ассемблерные вставки, если думаете обогнать компилятор по качеству кодогенерации и вам не жалко потерять относительную платформонезависимость. Применяется там, где приходится взять детали реализации под свой ручной контроль в угоду быстродействию. На самом деле, время программиста дороже процессорного времени, поэтому применять его стоит только в уж совсем критичных случаях, и то в качестве модулей к более высокоуровневым динамичным языкам. Ну, если вы конечно не пишете свои драйвера/операционки/модули ядер/интерпретаторы, но я считаю, что и тех и других уже предостаточно, они прекрасного качества и не нужно плодить сущностей.
Javascript. Напоследок вернемся к вебу. А веб у нас в последнее время очень динамичен, и код исполняется не только на серверной стороне, но и у клиента. А у клиента браузер. А в браузере Javascript. И не вздумайте путать с Java! Общего у них только четыре буквы в названии. Собственно, это стандарт де-факто. Других языков практически никто из браузеров не поддерживает (разве что IE с vbscript), поэтому для клиент-сайда выбора просто нет. Язык в общем-то неплох для этой задачи, и есть неплохие фреймворки наподобие jQuery, эту самую задачу сильно упрощающие. Но не единым клиент-сайдом жив яваскрипт. Умельцы благодаря встроенной асинхронности пишут на нем быстрые сетевые сервера разного рода. Но я, если честно, не пробовал, и меня устраивает Python с Twisted в этой области.
За рамками обзора остались много других языков, с которыми я не знаком. Среди них:
Java, а так же много других языков на её платформе-виртмашине, вроде groovy. Саму яву я недолюбливаю за её многословность. Вы видели листинги? Это километры, сотни экранов кода, интерфейсов, шаблонов, наследования, десятки ключевых слов в каждом объявлении… Где искать бизнес-логику посреди этой обвязки? Куда больше я предпочитаю ясность и краткость моих фаворитов Ruby и Python. А что до платформы, то у меня предубеждение, что это жуткий тормоз. Отчасти это от того, что она старается быть максимально архитектурнонезависимой, отчасти это впечатление от тяжелых написанных на яве вещей вроде эклипса и нетбинса. Может я просто не умею её готовить, и надо просто указать ключ “–work-as-fast-as-possible” и все начнет летать.
Lisp. Язык старый, но не теряющий актуальности. Впрочем, основное применение, судя по интернету - это скриптование Емакса, а я вот предпочитаю vim. Ах да, там еще скобок столько, что заядлые смайлофаги обзавидуются)))))).
Visual Basic и прочие бейсики. Единственное их применение в моих глазах - скриптование других приложений, вроде как VBA для майкрософтовского офиса.
.NET и все языки в его инфраструктуре: ASP, С#… к сожалению, вся эта, без сомнения, прекрасная братия завязана на продукты Microsoft и его Windows, а я заядлый юниксоид. Да, есть mono, но он нестабилен, неполон и вообще костыль.
Итак, несмотря на всё, что я понаписал, совет только один: думайте сами и оценивайте подходящесть инструмента-языка под конкретную задачу, которую вам надо решить. Удачного выбора!