четверг, 15 января 2009 г.

Эволюция

Интересные наблюдения по поводу эволюции.

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

Ассемблер с энтузиазмом начали использовать выпускники высшей школы и многие из них тоже стали Настоящими Программистами. Программы на ассемблере однозначно переводились в машинный код и были почти также компактны и эффективны, как программы в машинном коде. "Почти" - потому что уже в те времена в некоторые умы проникла ересь: если компьютеры стали мощнее и программу в машинных кодах не надо вводить с помощью переключателей на передней панели, то зачем лишний раз напрягаться и оптимизировать код? Дальше - больше. Появился "макроассемблер".

Макроассемблер - это по сути связка некоего текстового препроцессора с транслятором. Текстовый препроцессор выискивал в тексте программы некие, известные ему, лексемы и разворачивал их в определенную последовательность лексем. Идея проста, как яблоко. Но яблочко оказалось с дерева познания Добра и Зла. Что после этого случилось в Эдеме -напоминать не надо. В общем некошерное оказалось яблочко. До появления макроассемблера программы были прозрачные: что написано на языке ассемблера, то и будет оттранслировано в машинные коды. "Макро" сильно напустило тумана. С одной стороны программы стали писаться быстрее, так как отпала необходимость по многу раз набивать почти идентичные участки кода. С другой стороны параметризованные макрокоманды стали восприниматься как "черный ящик": программисты стали забывать что там на самом деле делается и в какой код будет развернута та, или иная макрокоманда. Это стало началом конца эффективных и компактных программ.

Потом пришло время языков программирования высокого уровня. Поначалу многие трансляторы языков высокого уровня работали по сути как препроцессоры, генерируя сначала код на макроассемблере, который потом, уже проторенным путем, транслировался в машинный код. Но это уже был далеко не тот компактный и эффективный ассемблерный код, который писался вручную Настоящими Программистами: у программ появились прологи и эпилоги, а для сложения двух целых чисел вместо одной инструкции использовался вызов подпрограммы.

Настоящих Программистов складывающаяся ситуация не радовала. И они придумали "язык среднего уровня" - а именно С. Предполагалось, что он будет приближен к "железу" настолько, насколько это возможно для языка высокого уровня, и станет достойной заменой ассемблеру. Частично это удалось реализовать - трансляторы С давали действительно компактный и эффективный машинный код. Но ересь, зародившаяся еще на заре программирования, и здесь получила свое дальнейшее развитие: оказалось, что на любом языке можно написать плохую программу. А так как профессия программиста перестала быть уделом одиночек и стала массовой, то и доля плохих программ стала катастрофически возрастать.

Теоретики от программирования решили объявить войну ошибкам в программах. То есть решили исправить ситуацию, когда за написание программы сажают вчерашнего студента, изучавшего FORTRAN или С в промежутках между девочками, вискарем и марихуаной. Были изобретены множество языков от Паскаля до Ады, которые принуждали программиста придерживаться некоторой дисциплины при написании программ. Но за все надо платить. И кто может подсчитать сколько тысяч часов машинного времени было потеряно при проверке выхода индекса за границы массива? О какой эффективности здесь может идти речь?!

С++ уже не декларировался как язык "среднего" уровня. Это был полноценный язык высокого уровня, не лишенный красоты и элегантности. 90-е годы прошлого века.

Microsoft Visual C++. Microsoft Visual Studio 2008. Казалось бы что нового? Ну визуальная среда программирования... Ну библиотеки... .NET в конце-концов... А С++ - он и в Африке С++. Ан нет. Специалисты Microsoft измудрились и тут так приложить свою руку, что от классического С++ остались только базовые понятия. И то не все (например исчезло множественное наследование). Зато появилось множество новых ключевых слов. Классы стали пухнуть на глазах. Например, сколько памяти должен занимать экземпляр управляемого класса, который не имеет своих функций (т.е. "методов") и в качестве данных одну переменную типа char? 1 байт? 4, 8 или 16 байт? Концепция управляемой кучи привела к тому, что фактически появился новый язык программирования. Пока читаешь документацию, кажется что все достаточно логично. А когда начинаешь задумываться, какие процессы происходят при работе программы, что бы реализовать всю эту красоту - волосы начинают шевелиться.

А ведь когда-то 8 килобайт ПЗУ вмещали в себе целую операционную систему...