Thursday, June 28, 2012

Язык программирования

Intro
  Тысячи языков, сотни платформ, десятки парадигм, зачем? почему? Каждый, кто сталкивался с миром программирования наверняка задавался этими вопросами, так было и со мной. В этой заметке я вкратце напишу о том как появляются, развиваются и умирают языки программирования. О том, как появляются программы. О связи реального, воображаемого и виртуального миров.


  Эта заметка - моя попытка объяснить явление "язык программирования" с точки зрения психологии и философии. Я предполагаю что у вас уже есть некоторый опыт программирования и вы в общих чертах представляете "как это происходит".

Оглавление
Intro
  Вы уже прочитали.
Термины
  Определение нескольких важных терминов, которые пригодятся далее.
История
  Немножко истории.
Представление мира
  Немножко психологии.
Мышление, математика, программирование
  Много философии.
Программист
  Это человек, который пишет программы.
Модель языка и формализация некоторых понятий
  Ещё философия.
Жизненный цикл языка
  Всё что имеет начало, имеет и конец.
Outro
  Несколько слов, на прощание.

Термины
  Объект - философская категория, если определять её в пределах эпистемологии, выражающая нечто, существующее в реальной действительности (то есть независимо от сознания) — предмет, явление или процесс, на которые направлена предметно-практическая и познавательная деятельность субъекта (наблюдателя). При этом в качестве объекта может выступать и сам субъект. В качестве субъекта выступает личность, социальная группа или всё общество(вики).
(!)В этой заметке будут использоваться три дополнительных термина с уточнением типа объектов: реальный объект, мысленный объект и программный объект, причём последние два типа объектов это подмножества первого, также будет упоминается термины физический объект и информационный объект, но они особо не нужен в нашем случае.
  Элемент - синоним "объекта", при использовании подразумевается что этот объект часть модели или множества.
  Модель - это упрощённое представление реального устройства и/или протекающих в нем процессов, явлений(вики).
(!)В этой заметке будет использоваться в значении "конструкции из взаимосвязанных объектов", не обязательно абстрактное, но обязательно из более чем одного.
  Программист - пользователь ЯП.
  Разработчик - создатель ЯП.
  Объективно или объективная точка зрения - беспристрастная точка зрения гипотетического наблюдателя, который видит мир "таким, какой он есть" (познавшего дзен:)), без субъективных искажений, и использует в рассуждениях только формальную логику (разумеется, я могу только представлять, как нечто выглядит с объективной точки зрения, и использовать формальную логику только для очень простых случаев, для более сложных вынужден использовать абстрактную логику, которая потенциально склонна к ошибкам ("чёрт в деталях"), потому читая "объективно", вам следует понимать "по моему мнению, объективно"). Абстрактно это можно представить как точку зрения того, кто видит весь лабиринт с верху.
  Субъективно или субъективная точка зрения - точка зрения обычного человека, с его ограниченными знаниями, искажённым восприятием и ошибками абстрактного мышления(в частности в этой заметке моя). Абстрактно можно представить как точку зрения человека проходящего лабиринт.

История
  Здесь я намного углублюсь в историю, чтобы дать общее представление о том, как так получилось, что сегодня мы имеем то, что имеем. Эта история о том, откуда появились и как развивались языки программирования.
Математика
  Это началось очень-очень давно, так давно что даже Гугл не помнит когда. Тогда люди только научились считать и записывать числа, то есть научились создавать абстрактное описание объектов реального мира. С накоплением опыта использования цифр люди поняли, что с ними можно выполнять те же операции, что и с реальными объектами. Так были созданы абстрактные представления и способы записи – сначала для сложения, вычитания и цифры "ноль", затем умножения и деления. Так появилась математика.
  Математика так и осталась бы забавой для чудаков и была бы со временем забыта, если бы не приносила ощутимой практической пользы. "Полезность на практике" означает, что нечто позволяет человеку сделать больше, затрачивая при этом меньше усилий. Математика позволяла, например, древним торговцам быстрей и проще вести бухгалтерию, а строителям пирамид – экономить огромное количество человеко-часов за счёт предварительного проектирования.
  С развитием человечества также развивалась и математика, находились новые соотношения и способы описания, появлялись новые методы и средства. Со временем математика выделилась в отдельную науку, ещё позже разделившись на теоретическую и прикладную. На сегодня математика является мощным набором инструментов, для решения самых разнообразных задач и продолжает развиваться.
  Пожалуй, математическую нотацию можно считать самым первым языком программирования. Хотя такое утверждение не будет корректным, так как термин "ЯП" всё-таки относится к компьютерам, но, тем не менее, мат. нотация была прообразом первых и есть прообразом многих современных ЯП.
Программирование
  По мере того как прикладная математика развивалась и всё больше входила в повседневную жизнь людей, расчёты становились всё больше и сложнее, занимали всё больше времени и требовали всё большей скрупулёзности от считающего. Но, тем не менее, при всей своей сложности, они легко сводились к простейшим операциям вроде сложения и вычитания.
  С развитием техники появилась возможность реализовать простейшие математические операции с числами в виде механических устройств, "вычислительных машин". Дальнейшим развитием таких машин стала способность выполнять несколько простейших операций подряд. Затем появилась возможность программировать последовательность операций, то есть математик мог задать произвольную последовательность операций вместо того чтобы конструировать новую машину. Эволюция вычислительных машин привела к созданию концепции "машины Тьюринга". Ввиду универсальности и простоты реализации вычислительные машины, основанные на этой концепции, получили на сегодня наибольшее
распространение.
  С появлением первой программируемой машины появился и первый язык программирования этой машины. Долгое время ЯП представлял из себя то, что сейчас называться "машинным кодом", то есть, грубо говоря, просто последовательности из цифр – номеров операций, выполняемых машиной. Но программы становились всё больше и сложнее, и запись их в машинных кодах становилась всё более трудоёмкой. Это привело к появлению первого абстрактного слоя над машинным языком, называемого "ассемблер". Сложность программ и, как следствие, количество абстрактных слоёв над машинным языком растёт и по сей день.
  Хотя языки низкого, машинного уровня, такие как, например, Ассемблер или Си, сегодня в основном или частично вытеснены более высокоуровневыми, и почти перестали развиваться. Они, тем не менее, не потеряли актуальность и занимают свою специфическую нишу.
Математическое программирование
  Изначально вычислительная машина была создана для помощи математикам (в основном прикладным). Поэтому некоторое время развитие языков программирования шло исключительно вслед за развитием математики. Основной, подчас даже единственной, их задачей было связывание языка мат. нотации и машинного языка. Проще говоря, языки программирования стремились от машинных кодов к похожести на язык математики. И, как и сама математика, математические языки программирования продолжают развиваться и сегодня.
  Хотя первые мат. языки, например Fortran, использовались в основном для реализации вычислений, они были всё же ближе к машинным языкам, нежели к математической нотации. Характерная особенность первых мат. языков в том, что они имели исключительно числовые типы данных, например целые числа, дробные числа и т.п., и ограниченный набор простых операций над этими типами. То есть математикам всё ещё приходилось проделывать значительную часть работы "на бумаге". Со своим развитием мат. языки вобрали новые концепции и методы, как из математики, например лямбда исчисления, так и из практической области, например структурное программирование, работу со строками и т.п.
Практическое программирование
  С самого начала математические языки содержали некоторое количество служебных возможностей, не относящихся напрямую к математике, например, выделения памяти, команды ввод-вывода и т.п. Также по своей сути они являлись алгоритмическими, то есть описывали некоторую последовательность действий. Люди не могли не заметить, что этих возможностей вполне достаточно для решения многих практических проблем без трудоёмкого построения мат. моделей. Так от ветки мат. языков отделилась ветка языков, стремящихся от машинных кодов к похожести на естественные языки и практичности.
  Как и первые мат. языки, первые практические были ближе к машинным языкам, имели ограниченный набор возможностей. Но с развитием они становились всё проще, всё доступней для не операторов ЭВМ, обогащались такими новыми приёмами и парадигмами, как, например, структурное программирование, объектное программирование, а также заимствовали их из математических языков. Сегодня практические языки идут по пути всё большего абстрагирования от машины и являются наиболее популярными и используемыми.
В общем
  И по сей день эти два основных подхода развиваются, продолжают "ветвиться" в очень тесном сотрудничестве, заимствуя друг у друга удачные (и не очень) решения. Поэтому невозможно точно определить, к какой области относится некоторый из современных языков. Можно лишь сказать, что язык более удобен для математиков или же, наоборот, для практиков.
  Эта глава не претендует на точность и системность, так как развитие языков программирования больше похоже на эволюцию жизни, столь же многообразно и непредсказуемо, трудно поддаётся строгой классификации и описанию.
 
Представление мира
  Эта глава очень важна для понимания написанного далее, например с помощью концепции "субъект-объекты" строится представление языка программирования и опыта программиста как множеств объектов, а с использованием концепции "эмоциональной окраски" ведутся рассуждения о продвижении и распространении языков. Потому вам стоит потратить немного времени на более глубокое ознакомление с ней.
  Одна из фундаментальных концепций в психологии делит реальный мир на две части, на субъект(мыслящего наблюдателя) и объекты(то за чем наблюдает наблюдатель). Объект это всё что угодно, что может быть выделено субъектом как отдельная сущность. Иначе говоря объекты составляют окружающую реальность субъекта, потому далее я буду называть их "объектами реальности" или "реальными объектами". Проще говоря, субъект это вы, тот, кто читает эти строки, а объекты это всё, что вы можете видеть, слышать или чувствовать иным способом, и определить как отдельную сущность, например буквы в словах, которые вы сейчас читаете, это объекты, вы можете их видеть и можете выделить(курсором) каждую из букв.
  Множество всех объектов реальности можно разделить на физические и информационные:
Формально говоря информационные объекты находятся в физическом мире, представляя из себя, например состояние нейросети мозга, состояние ячеек памяти компьютера, линии краски на бумаге и т.п. Так что можно сказать: "реальный мир" и "физический мир" это одно и тоже. Но я разделил эти понятия, так как для человека, с его субъективной точки зрения, реальность не ограничивается физическим миром.
  У каждого из нас есть своё представление о мире, называемое "субъективной картой мира", объекты составляющие эту карту, далее я буду называть "мысленными объектами". Не смотря на то что мысленные объекты рождаются и процессируются "в голове", они могут существовать и вне субъективной карты, например будучи записанными в виде текста или зарисованными. Множество мысленных объектов, является подмножеством реальных объектов и относится к классу информационных объектов, например, объекты: яблоко, образ яблока в голове и 3D-модель яблока в компьютере, это три разных объекта реального мира, несмотря на то что два последних являются отражением первого.
  Большинство мысленных объектов является отражением реальных объектов, но есть и те которые нечего не отражают, назовём их "фантазийными объектами". Мысленный объект-отражение может отражать например чувство, слово, действие, нечто придуманное другим человеком(к примеру летающего макаронного монстра), другой (собственный) мысленный объект(к примру понятие о "понятии"), в общем всё что угодно, это отражение будет на столько точным, насколько хорошо был исследован человеком реальный объект. Фантазийные объекты получаются путём конструирования из других мысленных объектов (при конструировании, карта мира используется в качестве алфавита). Фантазийные объекты это именно те которые человек сконструировал сам, если, например рассказать о таком объекте другому человеку, в его субъективной карте построится объект-отражение ф. объекта принадлежащего первому (рассказчику).
  Всякий мысленный объект имеет множество связей(как бы ссылок), с другими м. объектами. Некоторые из связаных объектов отражают свойства реального объекта(такие как, например, вес, размер), некоторые отражают причинно-следственные отношения и т.д., всё это и есть субъективная карта мира.
  Возьмём для примера объект "чайник": 
  Большинство людей, включая меня, мыслит мыслями обличёнными в словесную форму, но при необходимости, почти всегда, могут легко представить(визуализировать) словесные конструкции, однако есть и те, кто, например использует в основном мышление визуальными образами. У каждого из этих способов есть свои преимущества и недостатки, но сейчас это не важно.
  Многие из мысленных объектов связаны с чувствами, "эмоционально окрашены", то есть, мысли содержащие такие объекты, вызывают некоторые чувства/эмоции. Чувства могут быть очень сложными, но в общем случае сводятся к приятно/неприятно. С какими именно чувствами будет связан мысленный объект, обычно зависит от эмоционального состояния человека на момент создания объекта. Со временем обычно эта связь теряется(забывается), а также может измениться, иногда даже на абсолютно противоположные чувства. Чувства это очень древний и фундаментальный механизм (см. лимбическая система), задачей котрого является контроль(управление/направление/ограничение) процессов мышления. А так как "программирование" это также мысленный процесс, его понимание невозможно без понимания работы "чувственной системы".
  Модель мышления, описанная в этой главе, является экспериментальной, на самом деле я, разумеется, не знаю "как думают люди", то есть нет ни каких гарантий, что "это работает"(что выводы полученные при помощи этой модели верны). Тем не менее, я буду использовать её в дальнейших рассуждениях, будьте внимательны. 

Мышление, математика, программирование
  Абстрактное представление позволяет значительно уменьшить количество информации об объекте, сократив её до минимума, необходимого для работы с этим объектом. Этот метод уже очень давно используется природой для сохранения представления объектов реального мира в памяти животных. В ходе эволюции люди развили эту возможность и дополнили её новыми средствами работы с представлениями(например, воображением).
  Абстрактное представление может быть не только мысленным, это может быть, например, физический макет или рисунок на бумаге, но в этой главе речь именно о мысленном, математическом и компьютерном представлении объектов реального мира.
  Абстрактное представление имеет фундаментальный недостаток, называемый "потеря значимых деталей". 
Мысленное представление
  Суть мысленного представления в том, что мысленный объект хранит только те свойства реального объекта, которые были "исследованы" человеком при решении каких-либо задач, связанных с ним, или из любопытства. Так как исследовать и отразить, все свойства реального(особенно физического) объекта сложно, мысленное представление практически всегда является абстрактным. Также при использовании мысленного объекта, например, для планирования, учитываются только те из известных свойств, которые важны в контексте решаемой задачи. Например, если решается задача "положить чайник в коробку", совершенно неважно, из какого материала он сделан. То есть над мысленным объектом, являющимся абстракцией реального, создаётся ещё один абстрактный слой, ещё один, уже более "легковесный", мысленный объект. В зависимости от задачи таких слоёв может быть несколько. 
  Мысленное абстрактное представление имеет два недостатка. Первый, фундаментальный недостаток самого метода - это "потеря значимых деталей", а второй – это низкая точность абстрагируемых свойств, т.е. свойств, приносимых в мысленный объект.
  Чем выше уровень абстракции, тем больше скрывается свойств, и тем меньше вероятность успешного использования мысленного объекта. К примеру, если объект используется для прогнозирования, то чем он абстрактнее, тем меньше вероятность, что прогноз сбудется. Для примера представьте такую ситуацию: вы подобрали точно подходящую по размеру коробку для чайника, но забыли о том, что у чайника ещё есть подставка со шнуром. В то же время, чем более абстрактен мысленный объект, тем меньше ресурсов для него требуется, что даёт, при конечных возможностях мышления, работать с более сложными реальными объектами. Т.е. уровень абстрагирования – это всегда компромисс между возможностями человека и сложностью абстрагируемого объекта.
  Для решения проблемы потери значимых деталей придумано много методов и приёмов, например "метод полной(завершённой) абстракции", "метод точного подбора свойств" и т.д., а также методы позволяющие "вносить" мысленные объекты вне мышления, например, записывать или реализовывать в виде макета, тем самым как бы увеличивая размер доступной человеку памяти. Однако ни один из них не решает проблему полностью, а за использование многих из них приходится платить значительной растратой сил и времени.
  Чем ниже точность абстрагируемых свойств, тем хуже повторяемость результатов использования мысленного объекта, например, если объект используется для проектирования, то чем меньше точность его свойств, тем больше вероятность того, что при реализации проектируемого объекта, будет допущена ошибка. Для примера представьте, что вам опять нужно подобрать коробку для чайника, так, как ранее вы уже это делали. Вы сразу прикинули на глаз размер и сочли, что он такой же, как и у предыдущего, потому вы взяли такую же коробку, но вот беда, этот чайник немного больше. Увеличение точности ограничено физическими возможностями людей, например, для лучшего определения размера "на глаз" требуется более высокое разрешение сетчатки и большее расстояние между ними(для лучшего определения глубины). Эволюционно человек получил возможности, достаточные для выживания в естественной среде. Но со временем этого стало не хватать, решением проблемы недостаточной точности и стала математика.
Математическое представление
  На заре своего развития математика описывала только свойства реальных объектов, такие как, например, количество, размеры, вес, и имела всего несколько простейших операций. В таком виде она используется практически всеми людьми и сегодня. Позже люди научились описывать не только сами свойства, но и взаимосвязи этих свойств в виде формул. Этот метод был особенно востребован в инженерном деле и в естественных науках, в которых принято таким образом записывать закономерности реального мира. За долгое время использования был выработан простой и краткий синтаксис для записи математики на бумагу или иные физические носители.
  Суть математического(в частности числового) представления в том чтобы "оцифровать" свойства реального объекта, т.е. представить их в виде численного отношения к некоторому эталону, принятому за единицу. Например, если принять за эталон ширину ладони("одна ладонь"), можно измерить любое расстояние, переставляя ладони в притык одна к другой, и представить это расстояние в виде числа перестановок ладоней. При необходимости можно "восстановить" свойство реального объекта в реальном мире, воспользовавшись числовым представлением и эталоном. Объединив несколько оцифрованных свойств объекта и, если необходимо, их соотношений, вы получите математическую модель реального объекта. С полученной моделью можно работать в уме, и, благодаря мощному мат. синтаксису, можно легко сохранить например, на бумаге, что, в свою очередь позволяет работать с более громоздкими моделями, не прибегая к злоупотреблению абстракцией.
  Элементы математики, числа, отношения, операции и т.д. относятся к подмножеству мысленных объектов, так как сами по себе, без использующего их человека, не имеют смысла. Можно сказать, математическое представление является надстройкой над мысленным представлением, решающей проблему неточности, и дополняющее его методами и приёмами, расширяющими возможности. Потому я не выделил математику в отдельный "мир".
  Пример с чайником:
  Математическое абстрактное представление решило проблему недостаточной точности. Но этот подход создал ряд дополнительных проблем, свойственных только ему. Таких, как проблема "красивой математики", когда разработчик математической модели стремится к тому, чтобы сделать её красивой по его субъективному мнению, жертвуя при этом соответствием модели моделируемому объекту. Или проблема "кажущейся точности", когда следуя убеждению "математика – точная наука", например, пренебрегают погрешностями реального измерительного оборудования или нагромождается чрезмерное количество слоёв абстракции. К тому же этот подход никак не решил фундаментальную проблему "потери значимых деталей", так как по-прежнему ограничен возможностями мышления человека. Эту проблему сегодня пытаются решить при помощи программного представления.
Программное представление
  Я считаю вычислительную машину если не самым, то по крайней одним из самых больших достижений человечества. Впервые за всю историю человечества было создано нечто способное "думать" подобным человеку образом, без его непосредственного участия. Казалось-бы какое отношения к "думать" имеет, например, примитивная машина-арифмометр, на подобии системы "Железный Феликс", однако до её изобретения никто и ничто, кроме человека не мог выполнить даже банальное сложение/вычитание. Это уже не просто усовершенствование мышления, это попытка "вынести" его во вне, реализовать в виде внешнего устройства, хотя-бы частично. От древних арифмометров до современных полностью автоматизированных предприятий и робототехники, "мыслящие машины" продолжают эволюционировать, и я уверен однажды сравняются в своих возможностях с людьми. Однако сегодня, в большинстве своём, это довольно примитивные устройства, неспособные к самообучению, а потому выполняющие только то, что было запрограммировано человеком. Тем не менее, эти устройства уже заполонили мир людей, и их численность продолжает возрастать. Очевидно, их огромное количество и разнообразие стало одной из причин столь большого количества разнообразных методов и инструментов их программирования.
  На сегодня "внедрение" компьютеров идёт по двум основным направлением. Первое, это компьютеры/программы, предназначенные для расширения мышления, например, калькуляторы, позволяющие забыть о таблице умножения, или, например, САПРы, позволяющие уволить девять из десяти инженеров без потери производительности. Второе направление – это замена реальных устройств, например, печатных машинок сегодня уже не выпускают. Разница между этими направлениями в том, что, в первом случае в компьютер переносятся в основном сконструированные мысленные объекты, а во втором в основном переносятся мысленные объекты, являющиеся отражением реальных.
  Программное представление это все сущности, что существует в компьютерной памяти или предназначаются для неё(к примеру распечатанные листинги программ), далее я буду назвать их "программными объектами". Программные объекты это либо отражение мысленных объектов, созданных человеком при помощи каких-либо инструментов, например нарисованные при помощи графического редактора или описанные с помощью языка программирования, либо объекты, попавшие в память компьютера посредством каких либо специализированных средств ввода, например сканеров, камер, датчиков и т.п., либо объекты сконструированые самим компьютером(к примеру скомпилированные бинарные файлы). Программные объекты, образуют "программное представление", это подмножество реальных объектов, относящееся к классу информационных объектов(см. главу "Представление мира").
  Все люди используют язык(речь) для описания объектов реального мира, и с раннего детства осваивают метод записи языка в виде текста. Потому не удивительно, что именно описание программных объектов при помощи текста получило наиболее распространение, как наиболее естественный и доступный для большинства людей способ. Далее речь пойдёт в основном об программных объектах, созданных при помощи языков программирования, т.е. описанных при помощи текста, так как заметка именно о языках.
  Программное представление это отражение объектов реального мира в памяти компьютера. В зависимости от уровня абстракции, это могут быть, например, числа в ячейках памяти, конструкции из объектов ООП и т.п. Как и все другие объекты реального мира, программные объекты имеют своё отражение в мышлении работающих с ними людей, т.е. представлены мысленными объектами. Обратите внимание, в этой статье в основном идёт речь о мысленном представлении программного представления, то есть о том, каким это программное представление видит человек, а не о том, как оно реализовано в компьютере.
  Из-за "нереальности" и сложности программных объектов их мысленное представление часто бывает очень субъективно, например инженер, работающий в САПР, может представлять деталь, которую видит на экране, как физический объект, а программист – как структуру данных. Вам не стоит забывать, что написанное в этой статье – это моё, субъективное представление, но я надеюсь, оно совпадает с общепринятым. Субъективность понимания виртуального мира – это одна из причин огромного разнообразия методов и инструментов его создания.
  Основной задачей языков программирования было и остаётся упростить, сделать более удобным и быстрым, преобразование мысленных объектов в программные и наоборот. Этого пытаются достичь за счёт приближения языков программирования к языкам, используемым людьми, т.е. перекладывая всё большую часть работы по преобразованию на компьютер.
  Все современные компьютеры произошли от устройств, созданных для помощи в математических расчётах, потому изначально программное представление являлось в основном отражением математического представления. То есть при таком подходе к созданию программных объектов(программированию) сначала строится математическая модель реального объекта, а затем по мат. модели описывается программная модель при помощи какого-либо языка программирования. Компьютер позволяет "оживить" программную модель, освобождая математиков от рутинных вычислений. Сегодня это также востребовано, так как многие проблемы лучше решаются мат. средствами.
  Раньше цена преобразования мат. модели в программную была велика, так как требовалось сначала "вручную" представить её в виде последовательности примитивных мат. операций, поддерживаемых компьютером. Затем добавить некоторое количество служебных операций, делающих возможным выполнение мат. модели в компьютере и только затем переносить, при помощи примитивных языков вроде ассемблера. Сегодня развитие математических языков программирования позволяет переносить мат. модель в компьютер без значительных преобразований, с минимальными усилиями.
  Пример преобразования мысленного представления в математическое, а затем в программное(программа проверяет, влезет ли чайник в коробку):  
  Со временем сложность объектов переносимых в компьютер всё нарастала, что приводило к увеличению числа программных объектов и их усложнению, справляться с программированием становилось всё трудней. Первым решением этой проблемы стало структурное программирование. Этот подход позволяет организовать программную модель в структуру, сходную со структурой моделируемого объекта, и частично абстрагировать её от машинного уровня чисел и операций над ними, заменив их вызовами подпрограмм и обращениями к записям(record).
  Развитием структурного программирования стало объектно-ориентированное программирования. Этот подход вводит дополнительный слой абстракции, позволяющий сократить и упростить(по сравнению например с процедурным программированием) значительную часть математического представления, требуемого для переноса реальных объектов в компьютер. Это становится возможным благодаря тому что во многих случаях в компьютер прямиком приносится мысленное представление, минуя построение математического, таким образом, сокращая требуемое количество усилий для преобразования мысленного объекта в программный. Математическое представление и остальные аспекты внутреннего устройства программного объекта в ООП инкапсулируется(скрывается) в классах/типах. То есть программист может работать с программным объектом, не вдаваясь в подробности его внутреннего устройства, может представлять его не как запись со значениями или библиотеку с функциями, а например, как абстрактное отражение физического объекта, или придумать какой-нибудь свой, удобный для него, образ.
  Пример создания программного представления, при помощи ООП-подхода:
  Наблюдается тенденция приближения ЯП к языкам людей, естественным, как например разговорный, сленгам, принятым в определённой области, или искусственным, как, например, математическая нотация. Это позволяет программистам без дополнительных преобразований сразу переносить мысленные объекты в компьютер, описывая их привычными терминами и способом. Например, при использовании ООП-подхода, сначала необходимо преобразовать мысленный объект в ООП-объект и во время работы с преобразованным объектом помнить и учитывать, что это прежде всего ООП-объект, а при использовании более высокоуровневого ЯП об этих условностях можно забыть и считать что программный объект это (почти) точное отражение мысленного. Т.е. программист на таком высокоуровневом ЯП может даже не знать о существовании ООП, не говоря уже о том чтоб знать используется ли оно в недрах конкретно этого языка, а просто описывать задачю в знакомых и понятных ему терминах, привычными для него способами. Но, ввиду примитивности компьютеров, такие высокоуровневые языки имеют чрезвычайно ограниченные возможности, обычно не выходящие за рамки некоторой узкой предметной области, т.е. с их помощью возможно переносить только объекты, относящиеся к данной области.
  Пример высокоуровневого языка:


Программист
  Программы пишут люди, и называются они "программистами". С самого появления этой профессии и по сегодня основной задачей программистов является конструирование программного представления.
Мышление программиста
  В целом мышление программистов, как и специалистов других инженерных специальностей, не отличается от мышления обывателя, однако дополнено некоторыми специфическими знаниями и навыками. По мере обучения у программиста формируется некая "программиская" модель мышления(опыт), состоящая из набора мысленных объектов, являющихся отражением объектов, относящихся к предметной области "программирование". Среди объектов модели понятия о элементах программного представления(например переменные, операторы, типы, функции, классы и т.п.), и навыки конструирования из них(алгоритмы, паттерны, парадигмы и т.п.).
  С одной стороны, чем больше число элементов в программисткой модели, тем больше стандартных решений стандартных проблем известно программисту, и соответственно он не будет тратить время и силы на их поиск. А в случае не стандартной проблемы сможет, опираясь на богатый опыт, сгенерировать больше решений(из в принципе возможных для конкретной проблемы) и выбрать лучшее из них.
  С другой стороны, с увеличением числа элементов модели, становится всё сложнее добавлять("встраивать") новые, т.е. обучаться. И особенно сложно изменять/заменять существующие т.е. переучиваться. Сложнее, так как в первом случае необходимо связывать новые элементы с уже имеющимися в модели (чем больше элементов тем больше связей требуется добавить), а во втором не только связывать с уже имеющимися но и разрушать уже устоявшиеся связи(что потенциально может привести к серьёзным проблемам в плоть до полного разрушения модели) попутно "наводя порядок"(т.е. восстанавливая логическую целостность опыта, например устраняя возникающие взаимоисключающие и дублирующиеся знания). Усложнение расширения/изменяя модели приводит к явлению "закостенелое мышление", т.е. когда человек избегает новых знаний и старается как можно чаще применять существующий опыт вместо поиска нового, оригинального решения. Но не смотря на все трудности учиться необходимо (хочу заметить что форсированное, а потому не качественное, обучение лишь создаст гору информационного мусора, и приведёт к разным неприятностям вроде "взаимоисключающих параграфов" и им подобным), также необходимо хотя-бы пытается найти оригинальное решение, даже в случаях когда, казалось бы, выбор очевиден(это не даст атрофироваться вашему воображению). 
  Объективно то, какие конкретно объекты войдут в програмстскую модель мышления конкретного программиста зависит от его судьбы(совокупности всех событий и обстоятельств, относящихся к конкретному человеку). А так как судьба каждого человека уникальна, его программистская модель также будет уникальна. Но, тем не менее, она обязательно будет содержать некоторый базовый/необходимый набор объектов, а также будет состоять в основном из популярных на момент обучения элементов, так как популярные элементы с большей вероятностью "попадут на глаза" программисту.
  Субъективно, "программирование" (как и прочие мысленные процессы) контролируется чувствами (удовольствие/неудовольствие). В общем случае можно сказать, что программист, в своей деятельности стремится к тому, что приносит удовольствие, и от того, что приносит неудовольствие. Факторы, вызывающие чувства, весьма индивидуальны и изменчивы, кому-то нравится развитие и поиск, кому-то спокойная и размеренная работа, кому-то большая зарплата и т.д. Но, так или иначе, эти факторы определяют область интересов программиста, и, как следствие, значительно влияют на формирование его "программистской" модели мышления.
  Уникальность модели мышления каждого программиста, это одна из причин столь большого разнообразия решений в этой области, в том числе и разнообразия языков программирования.  
  Программист использует элементы модели для конструирования программ(программного представления). Можно сказать, что программист использует модель в качестве алфавита для построения программ. Конструирование начинается в уме с создания мысленного представления будущего программного представления, затем оно переносится в компьютер при помощи языков программирования(есть и иные способы, но в этой заметке о ЯП), т.е. становится программой. И наоборот, читая код и документацию, программист строит мысленное представление программы. Чем элементы программистской модели мышления ближе к элементам модели решаемой задачи, тем меньше программисту приходится затрачивать усилий на преобразование мысленного представления в программное.
  По моим наблюдениям, мышление большинства людей имеет словестную форму, возможно это более экономично/эффективно(позволяет "перебирать" большее число образов) по сравнению с мышлением образами или возможно потому что привыкают к этому с детства. Те же, у кого преобладает образное мышление, например люди работа которых связана с образным представлением(механики, электронщики и т.д.), могут легко преобразовать образы в слова. Вероятно потому текстовое представление программ получило наибольшее распространение, как наиболее естественный и удобный способ записи. По себе могу сказать, при наличии достаточного опыта мысли выражаются в коде без значительных усилий, подобно тому как они выражаются в тексте на естественном языке. Однако представление в виде образа, например алгоритма в виде графа или модулей в виде диаграммы, значительно упрощает чтение и понимание программ, особенно больших, так как образное(в частности графическое) представление позволяет передавать и обрабатывать(обдумывать) гораздо больший объём информации за тоже время, по сравнению с словесным.
Создание программного представления(с использованием ЯП)
  Программы создаются для решения каких-либо задач(в широком смысле слова), даже если пишутся забавы ради они решают задачу собственно получения удовольствия. Разработка программы всегда начинается с анализа задачи программистом, целью которого является получение сведений, например, причин и последствий задачи, текущего состояния и т.п. Результатом анализа является мысленная модель задачи, которая будет использоваться на всех последующих этапах.
  Следующий этап это конструирование решения задачи. Конструирование выполняется из объектов составляющих модель мышления(опыта), с целью создания объекта способного решить задачу(решения). В нашем случае таким объектом будет программа, и сконструирована она будет из объектов составляющих "программскую" модель мышления. В зависимости от задачи и от опыта программиста, эта работа может быть выполнена в один или много подходов. Например, если задача простая, можно сразу же придумать или использовать готовое решение, останется его только записать. Сложные задачи могут потребовать несколько подходов с перебором решений или даже применения методов декомпозиции и абстракции, с записью/чтением промежуточных решений, например построения блок-схемы для сложного алгоритма, и только затем представления его в коде. Очень сложные задачи решаются эволюционным методом.
  Пример создания программы заваривания чая(в зависимости от выбранного для реализации ЯП, способа мышления и опыта программиста, реальный процесс программирования может значительно отличаться от этого примера):
Картинки в левой части рисунка это как бы представление программиста о семантике синтаксических конструкций.
  Чем ближе ЯП к решаемой задаче, тем меньше программисту потребуется сил и времени на её решение, так как более близкий язык скрывает больше деталей, не относящихся напрямую к задаче, и следовательно, программисту не нужно о них заботиться. С дугой стороны чем ближе ЯП к задаче, тем уже область его использования.

Модель языка и формализация некоторых понятий
  Язык программирования(ЯП), в отличие от естественного языка, в первую очердь предназначен для передачи информации от человека к компьютеру, на что естественные языки(на сегодня) не способны. ЯП очень похож на естественный язык, он также имеет синтаксис(конструкции из слов) и семантику(значение/смысл словесных конструкций). В отличие от естественного, ЯП гораздо более формализован, то есть имеет точные, фиксированные правила построения словесных конструкций и строгое определение смысла каждой конструкции(формальные языки применяются, не только в программировании, например, существует язык записи мат. формул, язык записи химических формул etc.). Другое важное отличие в том что написанное на ЯП так или иначе преобразуется в некоторою информацию управляющую работой компьютера, то есть синтаксическим конструкциям соответствует не только смысл(мыленое представление) но и некоторая реализация(программное представление).
 Развитие языков программирования идёт по пути приближения к мышлению людей, каждый разработчик(кроме эзотериков, разумеется) старается сделать свой язык как можно более удобным и полезным, как минимум для себя.
Общая модель программирования и модель ЯП
  Представьте множество всех объектов, относящихся/используемых в области "программирование", от операторов до технологий, от спецсимволов до компиляторов и IDE, назовём всё это множество "моделью программирования".
  Языки программирования также являются элементами этого множества. Каждый язык состоит из элементов, назовём множество всех элементов модели программирования, относящихся к конкретному ЯП, "моделью языка программирования". Некоторые из элементов модели программирования входят в более чем одну модель ЯП, например оператор присваивания или императивная парадигма, такие элементы являются общими для нескольких языков.
  Мысленное отражение части элементов модели программирования есть "программистская" модель мышления, из предыдущей главы. Эта часть может относится к одному языку или к нескольким, в зависимости от того, сколько их знает программист. Как правило, программист знает только о части возможностей используемых языков, так происходит потому, что возможности большинства популярных ЯП сильно превосходят потребности отдельных программистов.
Vпрограммист, знающий только C++, P - программист, знающий C++, Haskell и немного Java.
  Многие элементы модели программирования являются общими для нескольких языков, поэтому, зная хотя бы один язык, проще изучить другой, так как часть элементов модели другого языка уже изучена при изучении первого, и чем больше элементов являются общими, тем проще изучать другой ЯП (например, программисту V будет легче изучать Java, чем Haskell).
Множество популярных элементов
  Представьте подмножество всех популярных на сегодня элементов из модели программирования, то есть таких, которыми владеет подавляющее большинство программистов, и которые используются в большинстве популярных языков.
Например, оператор присваивания или процедурное программирование.
  Множество популярных элементов постоянно изменяется, пополняясь новыми элементами и теряя старые. Новые или хорошо забытые старые элементы, по тем или иным причинам(например имея большую мощность или хороший пиар) становятся сначала модными, и, набрав популярность, попадают в множество. Спустя какое-то время элементы становятся привычными, а с появлением аналогичных новых элементов теряют популярность и вытисняются новыми из множества. Одни элементы быстро покидают множество, например OLE. Другие остаются популярными долгое время, например оператор присваивания, ООП и т.п. Этот процесс и есть эволюционное развитие предметной области "программирование".  
Мощность языка
  Представьте себе множество всех задач, решаемых при помощи всех языков программирования. Каждая из этих задач имеет некоторую цену(время, деньги etc.), которую необходимо заплатить за её решение. Многие из задач могут быть решены при помощи разных ЯП, иначе говоря, разные ЯП имеют некоторое подмножество задач, которые могут быть решены при помощи любого из них.
При прочих равных, цена решения каждой задачи зависит от того, насколько хорошо она решается конкретным ЯП. Таким образом, для множества общих задач более мощен тот язык, который позволяет решить эти задачи в среднем дешевле.
  Мощность ЯП зависит от предлагаемой им модели программирования, от того, насколько эта модель способствует удешевлению решения общих задач по сравнению с моделью другого ЯП. Наиболее важными в контексте мощности являются элементы модели, формирующие логику мышления программиста, такие как, например, парадигмы, паттерны, приёмы и т.п. Элементы оформления, например, синтаксис или IDE, менее важны, так как к ним программисты сравнительно легко привыкают (хотя, несомненно, плохо спроектированный синтаксис и отсутствие IDE усложнит работу и особенно обучение программиста).
  Объективное сравнение ЯП по мощности весьма сложная задача, не говоря уже о точном сравнении, поскольку на то, какой язык окажется более мощным для конкретной задачи, влияет очень много факторов, в частности, субъективных. Главные проблемы при оценке мощности языков это неодинаковое владение ими оценивающим программистом (частным случаем этой проблемы является эффект Блаба, когда программисту на Блаб некоторый другой язык кажется менее мощным только потому, что программист не владеет моделью другого ЯП в достаточной степени, и не может на нём создать решение лучше чем на Блабе) и эмоциональность оценки, когда недостатки симпатичного языка преуменьшаются, а достоинства – преувеличиваются. Существенной проблемой является также и  "предрасположенность" программистов к конкретным языкам, точнее, к ключевым элементам моделей языков, например, парадигмам. Каким бы мощным ни был язык, если его модель не "ложится" на модель мышления, программист не сможет использовать и, следовательно, оценить, эту мощь. Например, тот, кто мыслит по жизни "императивно", не поймёт и не оценит декларативные языки.
  Большинство современных программистов владеют более чем одним ЯП и стараются подбирать наиболее мощный язык, для каждой конкретной задачи. Не редкость, когда в проекте используется более одного языка. Как правило, один из них является основным. Однако использование нескольких ЯП влечёт дополнительные затраты на интеграцию их с основным языком проекта и друг с другом. Сегодня предпринимаются попытки так или иначе уменьшить эти затраты, например за счёт использования метапрограммирования, DSL или мультиязыковых платформ(например .NET). 
Порог вхождения
  Прежде чем программист сможет начать конструировать (писать) программы из элементов модели ЯП, ему необходимо создать мысленное представление некоторого минимально необходимого числа элементов языка, т.е. освоить базовый уровень, позволяющий использовать и оценить мощность модели языка. Как только программист освоил базовый уровень, он преодолел порог вхождения. Абстрактно можно представить объективную высоту порога ЯП как сумму трёх факторов: сложности, количества и популярности элементов, входящих в базовый набор. Субъективно (с точки зрения конкретного программиста) порог вхождения зависит от того, сколько из базового набора элементов модели ЯП ему уже известны, а также от субъективной сложности элементов, которые ему предстоит изучить. 
  Понятие "сложность" характеризует количество усилий/времени, затраченных на изучение и понимание объекта (элемента модели программирования в нашем случае). Чем дороже понимание объекта, тем больше его сложность. "Понять объект" означает встроить его в модель мышления, т.е. не просто создать его мысленное представление, но и увязать с другими мысленными объектами в достаточной степени для практического использования (для использования при конструировании программы в нашем случае). Цена понимания объекта индивидуальна для каждого человека и зависит от многих факторов, например, от того, сталкивался ли он ранее с подобными объектами, от используемых методов изучения, от IQ и т.д. Сложность увеличивается в случаях, когда новый объект конфликтует со старым (например, тот же синтаксис, но другая семантика), в этом случае придётся затратить дополнительные усилия на устранение конфликта. Объективную сложность объекта можно представить как усреднённую цену его понимания для всех понявших людей.
  Чем больше популярных элементов в языке, тем ниже его порог вхождения для людей, знающих хотя бы один ЯП. Также субъективно для программиста порог ниже, если следующий изучаемый ЯП содержит больше общих элементов с предыдущим, т.е. больше похож на предыдущей.
  Разработчики могут понизить порог вхождения, снабдив программиста(посредством документации) методами изучения ЯП, например аналогии с другими ЯП, аналогии с тем с чем человек часто встречается IRL, примеры распространённых алгоритмов, изложение на "простом" языке и прочее. Направив программиста по оптимальному пути при изучении, посредством организации структуры документации, например при помощи последовательности изложения материала или структуры сайта. Также можно значительно понизить порог вхождения снабдив ЯП грамотно разработанной интегрированной средой(IDE), нацеленной не только на помощь опытным программистам, но и на обучение новичков.
  Грамотно построив имидж(в особенности при помощи документации), разработчики могут добиться повышения интереса к ЯП. Более высокий интерес поможет программисту преодолеть более высокий порог вхождения.
Предметно-ориентированный язык
  Модель языка общего назначения предоставляет некоторый набор универсальных элементов(объектов) для конструирования программ. Это могут быть структуры, ООП-объекты, функции, паттерны и т.п. При конструировании программы программист присваивает универсальным элементам некоторый специальный смысл(отображает смысл реального объекта на программный), зависящий от предметно-прикладной области, в рамках которой создаётся программа. Например, если в предметной области есть действие "загрузить файл", программист реализует его в виде процедуры/функции/метода, выполняющей это действие, и соответственно, назовёт её "download_file". Или, например, в предметной области есть объект "список работников", он будет реализован в виде структуры/объекта с именем "list_of_workers". Недостаток этого подхода в том, что программисту необходимо проделывать двойную работу: во–первых, создать мысленое представление реального объекта, во-вторых, построить при помощи/из универсальных элементов модели ЯП программное представление мысленного объекта. Достоинство такого подхода – универсальность, то есть универсальным элементам может быть присвоен смысл из любой предметной области.
  Модель предметно-ориентированного языка частично или полностью состоит из элементов с заранее, на этапе разработки языка, присвоенным смыслом(предметных элементов), отражающим объекты предметно-прикладной области. При этом предметный язык, в отличие от, например, фреймворка или библиотеки, отражает не только семантику предметной области но и синтаксис(замечу, библиотеки и фреймворки при помощи идентификаторов также частично отображают синтаксис предметной области). Предметными элементами могут быть как универсальные элементы после присвоения смысла, например, объекты или функции, так и специально созданные, например специфические для предметной области, синтаксические конструкции. Достоинством такого подхода является облегчение работы программиста, он может не думать, что в действительности представляют из себя предметные элементы(не забивать голову лишней информацией). Недостатки это невозможность(или сложность) применения языка вне предметной области, приводящая к необходимости использования нескольких языков в больших проектах. Это в свою очередь, порождает проблемы взаимной интеграции языков и увеличивает цену разработки в целом, в сравнении, например, с использованием библиотек. Иначе говоря, предметная ориентация позволяет значительно увеличить мощность ЯП, однако ограничивает её рамками предметной области.
Императивное и декларативное программирование
  Императивная парадигма предполагает описание порядка действий(алгоритма), которые будут выполнены исполнителем с целью достижения некоторого результата. Декларативная парадигма предполагает описание непосредственно необходимого результата, т.е. исполнитель(в нашем случае это компьютер, являющийся по сути императивным) сам должен выбрать алгоритм достижения результата.

  Образное представление декларативной и императивной программы, на примере задачи "создать объект":

  При императивном подходе программист использует навык композиции действий(приказов), в последовательности. При декларативном, использует навык просто композиции любых объектов(в том числе и действий). Так что, если рассматривать эти две парадигмы как множества идей/понятий/техник, то, с точки зрения программиста, можно сказать что императивное программирование является подмножеством(частным случаем) декларативного, т.е. при ИП декларируется(описывается) последовательность действий.
  Несмотря на преимущества декларативного подхода(отсутствие промежуточного слоя абстракции, более краткая запись и т.д.), он используется гораздо реже чем императивный. На то, по моему мнению, есть две причины.
  Во первых это человеческий фактор. Подавляющее большинство объектов с которыми взаимодействуют люди не статичны, то есть изменяются. Так уж сложилось что эти изменения представляются людьми как последовательность переходов(действий/событий) от одного состояния к другому, например "чайник холодный" -> "чайник закипел". И соответственно процесс изменения объекта(т.е. привидение его из текущего состояния к желаемому, например из состояния "пустой чайник" к стоянию "кипящий чайник"), человеку проще всего представить как последовательность "переводов" объекта из одного состояния к другому("набрать в чайник воды" -> "нагреть чайник до кипения"). Также, в подавляющем большинстве случаев, когда человек хочет что-то сделать он делает это сам. Ввиду ограниченного набора возможных физических действий(вроде согнуть/разогнуть палец), для того чтобы сделать что-то сложное, неизбежно приходится комбинировать элементарные действия в последовательности(стоит отметить что мозг запоминает часто повторяющиеся последовательности действий, как бы упаковывая в процедуры, но это не имеет отношения к ДП). Иначе говоря люди прокачивают скил императивного "мышления"(композиции действий в последовательности) с рождения и на протяжении всей жизни. В тоже время декларативный подход(когда, например стоит задача описать нечто, что будет создано, при этом не задумываясь о процессе создания) IRL встречаются человеку гораздо реже(что интересно, задача "описать декларативно" решается человеком императивно:)).
  Во вторых это несовершенство декларативных моделей (ЯП) и инструментов. Их уровень на сегодня не позволяет полностью пренебречь вопросом "как сделать?", оставив только "что сделать?". Это заставляет программиста проделывать бóльший объём мысленной работы, ему приходится формализовывать и описание решения(чтобы его собственно записать) и алгоритм решения(чтобы сверятся с ограничениями средств описания), который будет сгенерирован по описанию. Не смотря на это, во многих случаях, декларативный подход позволяет описать результат более коротко(меньше букв), просто и понятно.
  Лично я считаю неуместным противопоставление этих двух парадигм. Думаю, вы согласитесь, что глупо описывать, например последовательность сигналов декларативно, а HTML страницу императивно. То есть это два инструмента, отлично дополняющих друг друга.

Жизненный цикл языка
  Как и всё в этом мире, языки программирования рождаются, живут и умирают.
Разработка языка
  Новые ЯП создаются из разных побуждений: для промышленного использования, как, например, Delphi или Java, для облегчения собственной работы автора, например, PHP, Ruby, С++, или просто для развлечения, например Brainfuck. Независимо от причин, новые ЯП в большинстве случаев создаются методом комбинирования элементов модели программирования(часто заимствуются у других ЯП) и лишь изредка дополняются какими-то принципиально новыми возможностями, например структурное программирование в Algol или ООП в Simula (замечу, "принципиально новыми" только в контексте ЯП, в действительности эти возможности также имеют свою историю развития).
  В целом развитие языков программирования это эволюционный процесс, а следовательно, он сложен для понимания и практически непредсказуем. Основной причиной эволюции языков являктся усложнение решаемых компьютером задач, не только за счёт их масштаба но и за счёт разнообразия(всё увеличивающегося, начиная с того самого времени когда компьютеры "покинули" лаборатории, где занимались в осносном только вычислениями). Более сложная задача требует более дорогого решения. Языки программирования в своём развитии стремятся(адаптируются) к понижению стоимости, т.е. увеличению выгоды(увеличению мощности).
  Кажется странным, но именно удачная комбинация а не принципиально новые возможности, больше способствует успеху ЯП. Например, ООП появилось ещё в Simula, и после неё было ещё в нескольких языках, но только комбинация С и ООП в С++, со всеми своими особенностями, сделала этот язык столь успешным. 
  При создании ЯП каждый разработчик следует некоторому набору принципов, которые считает верными. Именно этот набор принципов определяет, какие элементы будут включены в новый ЯП, а какие – нет. Что это за принципы, в основном зависит от специализации разработчика, например, если разработчик программирует на С++, то захочет чтобы его новый язык был похож на С++, или, например, если его специализация – математика, он захочет включить в ЯП элементы, облегчающие программирование математики. При таком подходе вероятность того, что ЯП станет популярен, зависит от того, насколько принципы разработчика совпадают с общепринятыми на момент создания языка. А так как мышление каждого человека уникально, и то, что нравится одному, может абсолютно не нравиться другому, вероятность эта не велика. В этом плане показательна история языков С++ и Haskell. Первый был создан человеком, занимавшимся "практическим" программированием, и в первые годы своего существования развивался, исходя из пожеланий его пользователей, потому в него вошли популярные в то время элементы модели программирования, что и определило его успех. Разработчиков второго увлекались академическими, далёкими от практического программирования вещами, и, соответственно, включили их в свой ЯП, что сделало его непопулярным среди большинства программистов.
  Если ЯП разрабатывается с некоторой конкретной целью, например для использования в какой-то предметной области (DSL), это добавляет к набору принципы, отражающие предметную область. Например, если в предметной области отсутствует или недопустимо циклическое выполнение, разработчик берёт за принцип "нет циклам", и исключает из модели языка элементы, при помощи которых можно организовывать циклы, такие как, например, операторы собственно цикла и безусловного перехода.
Продвижение языка
  Многие разработчики по тем или иным причинам стремятся распространить свой ЯП среди других программистов. Это могут быть коммерческие соображения(например, MS .NET), желание прославиться, узнать мнение других и прочие меркантильные причины. Средства, используемые для продвижения, также очень разнообразны и зависят от возможностей разработчика, от массированной рекламы за корпоративные деньги, до толстого тролинга на форумах. Хоть эти средства и необходимы в контексте задачи популяризации, ни одно из них не гарантирует успеха. Секрет успеха ЯП - продуманная модель и немного удачи(если вы конечно не гений, как Ритчи или Страуструп).
  Программисты также, в свою очередь стремятся опробовать новые для них языки программирования. Случаи перехода на новый ЯП, когда программист вынужден (например, по требованию работодателя) или преследует коммерческие интересы в т.ч. потенциальные, рассматривать не будем, так как они достаточно очевидны и слабо относятся к новым языкам. Что же заставляет программистов обращать внимание на новые, неизвестные ЯП? Каждый человек в той или иной степени наделён стремлением к познанию, любопытством, в том числе и программисты (думаю, из-за специфики профессии у программистов эта черта особенно развита). Чем бы ни оправдывалось это стремление, например, необходимостью расширения кругозора или развлечением, в его основе лежит интерес, "принуждающий" мышление к поиску нового.
  На выбор программиста с каким именно из новых ЯП ознакомится серьёзно(более чем посмотреть заглавную страницу сайта) в основном влияет имидж языка и первое впечатление. В небольшом количестве случаев программисты делают осознанный выбор, например "парадигма используемая в этом новом ЯП возможно будет полезна в моём проекте".
  Далее будем в основном рассматривать случаи когда ЯП разрабатывается не зависимым разработчиком или группой, то есть не имеет серьёзной финансовой поддержки. Так как финансово обеспеченные разработчики могут позволить себе мощный PR, не особо прибегая к ниже описанным хитростям.
  Имидж можно представить как множество субъективных оценок программистов, в том числе разработчиков языка. Чем более эти оценки эмоциональны и положительны, тем больший интерес будет вызывать ЯП. Начальный имидж формируется разработчиками, и несомненно, он будет положительным. В дальнейшем имидж дополняется другими программистами, ознакомившимися с ЯП, именно в это время новый язык может либо стать популярным, либо быть "похоронен". Иначе говоря, разработчиками необходимо не только создать хороший начальный имидж, но и создать соответствующий ему ЯП. Умелое формирование и управление имиджем это очень-очень значительная часть успеха любого продукта (яркий пример – деятельность компании Apple в последние годы(1998-2011)), но существуют и другие пути (пример тому MS Windows (монополизация)).
  Первое впечатление складывается "по одёжке", то есть по внешнему виду(синтаксису) и общим характеристикам ЯП, не вникая в суть. Ирония в том, что это ключевой момент в знакомстве с языком. Каким бы прекрасным он не казался разработчикам, если первое впечатление будет негативным, подавляющее большинство программистов сразу закроют вкладку браузера и забудут о новом ЯП. Первое впечатление весьма стойко: даже если ЯП ужасен(но впечатлил программиста), пройдёт довольно много времени, прежде чем программист забьёт на его изучение. Кроме того, оно очень зависит от эмоционального состояния(настроения) программиста на момент знакомства с ЯП.
  Первое впечатление это в основном эмоциональная оценка, но не полностью, например программист может оценить ЯП как слишком сложный, т.е. имеющий слишком высокий порог вхождения, и решить что на изучение языка уйдет больше времени чем он может себе позволить, ну или просто поленится. Формирование первого впечатления можно представить как накопление положительных/отрицательных впечатлений в процессе изучения нового ЯП.
  Многие элементы (мысленные объекты) модели мышления программиста (опыта) связаны с чувствами, т.е. вызывают при обдумывании некоторые чувства с некоторой интенсивностью, для простоты сведём чувства к удовольствие/неудовольствие (нравится/не нравится). Например, одним программистам нравится "скобочный" синтаксис, другим "отступной", третьим всё равно. Те, кому нравится скобочный, скорей всего будут игнорировать ЯП с отступным, или даже доказывать что отступной не труъ, преувеличивая его недостатки и преуменьшая достоинства. Также, вероятно, программиста не обрадует встреча с незнакомыми для него элементами, а чрезмерное их количество в модели может его серьёзно огорчить, так как сделает модель непонятной, т.е. создаст впечатление слишком высокого порога вхождения.
  Абстрактно можно представить настроение программиста как некий счётчик. Обдумывание нравящихся объектов увеличивает значение счётчика(на столько, на сколько, сильно нравится объект), обдумывание не нравящихся - уменьшает. Начальное значение счётчика это настроение, с которым программист начал знакомится с языком, это значение положительно, так как ЯП уже вызвал некоторый интерес. По мере изучения языка значение счётчика изменяется, и если оно переходит через ноль, программист теряет интерес. Как быстро это произойдёт и произойдёт ли вообще, зависит от начального настроения программиста и от того, каких(положительных/отрицательных) элементов модели ЯП ему будет больше встречаться по мере изучения(зная об этом, разработчики благоразумно размещают достоинства на самом видном месте, а недостатки прячут глубоко в документации;)).
  Если первое впечатление было в целом положительным, то программист продолжит изучать новый язык и, вероятно, захочет применить его где-нибудь на практике. Теперь вероятность того, что он изменит мнение о языке на противоположное, сравнительно невелика. Однако такое вполне возможно, например, после сильно неудачной попытки практического применения. Из образа, сформировавшегося при первом знакомстве, будет "разрастаться" мысленное представление модели ЯП, то есть от первого впечатления также зависит каким будет мысленное представление, в каких "направлениях" программист будет двигаться при исследовании языка. 
  Как и все люди, программисты стремятся к тому что так или иначе доставляет удовольствие, и от того что доставляет неудовольствие. Исходя из этого, не доставляющий ЯП не станет популярным. Что конкретно приносит удовольствие конкретному программисту, очень индивидуально, например кто-то радуется, когда на новом языке удаётся записать известный алгоритм, каким-нибудь хитрым способом, другой радуется премии за досрочное выполнение задания благодаря новому ЯП. Не учитывать это, полагаясь только на техническое превосходство(мощность) ЯП, это очень большая ошибка разработчика. Например, ошибочно предполагать, что язык проекта выбирает "умный" архитектор, потому как архитектор тоже человек, а уж если он умный, то не выберет язык, который не нравится программистам.
  В общем, конструирование популярного языка - задача очень и очень не тривиальная, и требует от разработчика не только технических знаний, но и глубокого понимания программистской среды, умения выделить из неё целевую аудиторию(нишу) и создать остро заточенную под эту нишу модель ЯП. Очень сложно подобрать элементы модели таким образом чтобы они с одной стороны "гладко" собрались в единую конструкцию и обеспечили значительное превосходство по мощности, а с другой - способствовали популяризации языка, то есть обеспечивали бы низкий порог вхождения и помогали поддержанию положительного имиджа. Потому что, каким бы мощным не был ЯП, если подавляющее большинство программистов не преодолеют порог вхождения, они не только не смогут воспользоваться его мощью, но и даже не смогут её оценить, то есть объективно более мощный язык проиграет менее мощному, так как субъективно будет казаться программисту бессмысленным и бесполезным. Это замкнутый круг, программист не увидит превосходство языка потому что не будет его изучать(предпочтёт язык с меньшим порогом вхождения), программист не будет изучать язык, потому что не видит превосходства(но видит высокий порог).
  Многие разработчики обвиняют в неудаче своего ЯП консервативность/инертность мышления программистов(привычки). На самом деле "привычки" явление не только неотвратимое, но и весьма полезное, так как помогают "автоматизировать" многое рутинные дела. Привычки не могут быть не консервативными, так как формируются из наиболее используемых, а потому наиболее популярных и долгоживущих элементов модели программирования. Эти элементы, можно сказать, формируют скелет программистской модели мышления, а потому цена их изменения наиболее высока. ЯП, разработанный без учёта привычек программистов, не получит распространения, так как почти наверняка будет иметь чрезмерно высокий порог вхождения.
Распространение языка
  Допустим, новый ЯП таки начал распространятся, найдя поддержку программистов, неважно как, благодаря мощному пиару или по приказу сверху (в рамках одной компании). Чтобы стать действительно популярным, ему предстоит преодолеть ещё много трудностей. 
  И, пожалуй, самая большая трудность состоит в том, что программисты, особенно наиболее многочисленные "промышленные", не любят менять инструмент разработки. Даже в тех случаях, когда им предоставляется такой выбор, не говоря уже о том, чтобы убеждать архитектора. На то много причин, не только лень и не понимание преимуществ другого ЯП, но есть и вполне объективные. Например, ознакомившись с языком, программист, даже если тот понравился, может сделать вывод, что у него нет возможности серьёзно его применять из-за бедности инфраструктуры, невозможности интеграции с текущими проектами, невостребованности основных фич и т.п. Иначе говоря, цена изучения и внедрения так высока, что использование нового ЯП не окупится в приемлемые сроки, или даже, что хуже, язык окажется совсем бесполезным для данного конкретного программиста, т.е. от его использования не будет никакой выгоды.
  Учитывая это, разработчик должен стремиться понизить цену изучения и внедрения, а также охватить как можно большую целевую аудиторию. Чтобы понизить цену изучения, необходимо делать модель ЯП более простой и более похожей на модели существующих и популярных языков. Чтобы понизить цену внедрения, необходимо обеспечить совместимость ЯП с существующими платформами и библиотеками. К сожалению, эти требования крайне негативно сказываются на мощности языка, упрощение модели не позволяет добавить в неё сложные приёмы и методы программирования, а совместимость накладывает ограничения на реализацию.
  Новый язык, модель которого сильно отличается от моделей наиболее популярных ЯП, т.е. элементы модели не попадают в множество популярных, будет испытывать значительные трудности при распространении. Однако если язык имеет хорошее соотношение порога вхождения и мощности и, как следствие, хороший имидж, он будет сам медленно распространяться. И возможно, в конце концов пополнит множество популярных элементами своей модели. А возможно, и не станет, например, потому что появится другой, лучший язык. Разработчик может ускорить процесс распространения, например, при помощи пиара или доработки модели языка в угоду пожеланиям программистов. Причём чем менее удачным получился ЯП, тем больше придётся приложить усилий для его распространения.
  Чем популярней язык, тем сложнее новому ЯП будет его вытеснить. Не только из-за большой базы кода, но и из-за армии привыкших программистов. Причём это работает также и для языков, ставших популярными в основном благодаря пиару, не имеющих превосходства по мощности. Тем не менее, вытеснение неизбежно, так как новые языки, не связанные требованиями обратной совместимости, развиваются гораздо динамичней.    
Развитие и забвение языка
  Если язык получил хоть сколько-то заметное распространение, высока вероятность, что разработчик продолжит работу над ним и, исходя из отзывов программистов, своего опыта и требований времени, будет вносить те или иные изменения в начальный дизайн, стремясь сделать его лучше. Это и есть эволюция ЯП.
  Как бы ни был хорош начальный дизайн, время не стоит на месте, программирование непрерывно развивается, и если новый язык будет стоять на месте, то очень быстро потеряет актуальность и, как следствие, популярность. Но беда в том, что чем популярней язык, тем больше на нём написано кода и тем более к нему привыкли программисты. То есть чем популярней язык, тем сложнее вносить изменения в его модель, как из-за технических, так и из-за эргономических проблем. Поэтому в основном изменения происходит за счёт расширения модели. Расширение также затрудняет дальнейшее изменение модели, так как становится всё труднее и труднее органично (не разрушая принятую структуру/логику) встраивать новые элементы в разрастающуюся модель ЯП. Со временем язык либо перестаёт эволюционировать, либо превращается в раздутого монстра. Например, разработчики Java выбрали путь консерватизма, в результата сегодня этот язык ругают за отсутствие новых фич, вроде замыканий или метапрограммирования. Разработчики C++, напротив, не сдерживали его эволюцию, в результате он прослыл чрезмерно сложным и избыточным.
  Каким бы популярным ни был ЯП, несмотря на усилия разработчиков, рано или поздно о нём забудут все, кроме историков. Он неизбежно проиграет в эволюционной войне более новым, мощным и не имеющим груза обратной совместимости языкам. Возможно, язык будет вытеснен в свою, специфическую нишу, как это было  Pascal'ем или происходит сейчас с pure C. Но даже в этом случае когда-нибудь, найдётся лучший язык для этой ниши, или же она перестанет существовать. Всё это не значит, что язык полностью исчезнет, наверняка все более или менее удачные элементы его модели будут использоваться в новых ЯП, продолжая таким образом эволюцию программирования. 

Outro
  Кое что из написанного выше реально, другое притянуто за уши, третье и вовсе выдумано, чтобы собрать всё в единую картину. Читая эту статью, относитесь к написанному критически. И помните, в действительности всё не так, как на самом деле. :)

No comments:

Post a Comment