суббота, 15 января 2022 г.

Шеркало 05.06: любимые системы программирования (Паскаль ч. 2)

 - Эй, Шеркало, что замолчало? Заснуло что ли?

- Я не заснуло, я только хорька давило! Здоровый такой хорь попался, долго его давить пришлось!

- Ничёсебе! Ты где таких выражений нахваталось, "хорька давить"?!

- Так от тебя же, от кого же ещё?

- Так я ж про того "хорька" уже лет тридцать с лишним не вспоминал!

- Ага, ага... Ты вспомни, Ёж, как буквально сегодня утром вышел погулять на мороз. И кого ты там сразу же у подъезда поймал? А?! Да ещё и не один раз поймал, кажется?

- Нет, прекрати!!! Это ДРУГОЕ! Так интеллигентным людям говорить нельзя! Ты простых человеческих хорьков с нецензурными эфемерными зимними животными не путай, пожалуйста!

- А? Эээ? Ну тогда расскажи, что там у тебя дальше с Паскалем произошло? Ведь наверняка же простого превосходства в прямизне логики над Алголом было мало?

- Да. конечно, я вчерашний день потратил на то, чтобы перечитать статью Кернигана (он один из разработчиков языка Си) "Почему Паскаль - не мой любимый язык (1981)". Ничего особо нового для себя не увидел, хотя читать пришлось на английском - все русские переводы уже забанены, кажется. Но, неважно. Прочитал на английском. И увидел ровно то, о чём читал и раньше, ещё на русском: 

а) есть, немного, реально грамотные претензии (чрезмерная зацикленность Паскаля  на строгой типизации, особенно их видно в границах массивов при передачи параметров функций);

б) есть откровенный бред, из серии "лично мне так было бы удобнее, поэтому я = Д'Артаньян, а все остальные = бяки-буки, по определению" (статические переменные);

в) есть едва ли не единственная оправданная претензия к Паскалю, которая никак не может быть логически обоснована принципами языка, это отсутствие у оператора выбора "Case" варианта "иначе\else\otherwise". Вот реально не понимаю, почему Никлаус Вирт в своё время не включил эту опцию в оператор "Case", и почему упорствовал в её исключении и в дальнейшем? Ведь никаких принципиальных парадигм языка это ничуть не нарушало. И было легко и беспроблемно включено в новые версии языков на базе Паскаля. Что такое принципиальное Вирт здесь защищал?! Не понимаю!

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

е) ничто вышеперечисленное НЕ МОЖЕТ быть исправлено, потому что у языка Паскаль структура вот такая вот кривая = горбатого только могила исправит, а Паскаль изначально учебным пособием сделан. 

Что могу сказать? Почему он тогда так писал, совершенно понятно - всё-таки самолично есть автор альтернативного подхода. Почти все слабости Паскаля, на которые упирал тогда Керниган, были тогда либо уже (именно уже исправлены(!), к моменту выхода его статьи) исправлены, либо находились прямо в процессе исправления. 

- Ну а у меня, Шеркало, тем временем закончилась школа, миновала служба в армии (где о программировании не приходилось даже заикаться), было обучение в Университете, потом (не только потом, но и во время учёбы тоже) началась работа. И пришлось активно заниматься Паскалем. И чем больше на нём писал, тем больше убеждался, что Паскаль - очень гибкий и удобный язык.

Например, в том же ИОА, Паскаль для DEC PDP-11 (СМ ЭВМ, ДВК) транслировал программу не в машинные коды, а в текст на макроассемблере, который потом компилировался уже собственно ассемблером (кстати, не знаю, было ли это обязательной стадией обработки программы, или же только дополнительной опцией, но очень полезно и, кажется, красиво). В результате, в программу высокого уровня можно было совершенно свободно вставлять ассемблерные вставки, в которых, в свою очередь, можно было обращаться к переменным паскалевской программы прямо по их именам. Мечта системного программиста! Примерно вот так:

VAR SIMB :INTEGER;

PROCEDURE TTYIN; 
BEGIN
  (*$C
    NEXT:    EMT   ^O340
                    BCS   NEXT
                    MOV   %0, SIMB(%5)
  *)
END; (* результат машинной команды EMT 340 записывается в переменную SIMB для дальнейшей обработки в Паскале*)

Не знаю, насколько понятным получился пример. Здесь приведена очень простая (но синтаксически правильная) процедура на Паскале, основная часть которой реализована на языке Ассемблера (технически - это как бы комментарий к программе на Паскале, который якобы должен игнорироваться, но на самом деле не игнорируется, а после компиляции передаётся на вход следующему этапу трансляции, макроассемблеру), причём ассемблерная и паскалевская части свободно обмениваются данными друг с другом, имеют доступ к общим переменным, к регистрам, к прерываниям процессора и т.п.. 

Свобода - программистам! Высокоуровневую часть пишу на Паскале, низкоуровневую часть - на ассемблере. Где между ними граница? А нет никакой границы, у нас тут программирование без границ! 

Я мог бы и более интересные и бОльшие по размеру, и по разнообразию низкоуровневых команд, примеры привести. Я сам лично, писал на Паскале программу, обрабатывающую на низком аппаратном уровне (по сути драйвер устройства) команды графопостроителя, рисовавшего графики фломастерами на планшете под управлением одного из компьютеров СМ-ЭВМ-клонов PDP-11. Там как раз основа программы на Паскале писалась, а аппаратные вызовы через регистры ввода/вывода - на ассемблерных вставках. Графопостроитель в ответ на мои команды шустро вытаскивал механической лапкой один из четырёх доступных фломастеров, бегал своей кареткой вдоль и поперёк листа А3, рисовал красивый график по заданному массиву точек, потом возвращал фломастер в своё гнездо  планшета. Вот только, углубляться в дебри архитектуры PDP-11 в контексте языка Паскаль, совсем даже не нужно (как минимум, мне сейчас - не хочется).


- Чуть позже у нас в стране стали повсеместно использоваться "ПК" - Персональные Компьютеры. Многочисленные клоны клонов клонов IBM PC, PC XT, PC AT, PC 386 и далее, и далее, и далее (и до сих пор, если что). Эти машины уже работали не сами по себе, каждая со своими программами. Для их нормального запуска требовалась целая единая для всей серии разношёрстных компьютеров Операционная Система! Все мы помним, какую роль изначально играла MS DOS. Так вот, чтобы писать программы под "самую распространённую" в тот момент операционную систему (MS DOS) компилятор с языка Паскаль уже был!

И он не подводил. Чего ещё можно желать?! Очень изящный, быстрый, удобный, эффективный компилятор. Встроенная среда разработки IDE (Integrated Development Environment) - невероятно удобно, тут же и редактор (да ещё с цветовым выделением синтаксиса), тут же и компилятор, тут же и отладчик, тут же среда тестирования. Речь, разумеется, идёт о знаменитых средах разработки TurboPasal/BorlandPascal.  Это было впечатляющее качество, потрясающая эффективность. Среды разработки от фирмы Борланд временами превосходили конкурентов (в том числе "профессиональные" компиляторы языка Си) по большинству объективных показателей (размер результирующей программы, скорость выполнения программы, скорость компиляции), не говоря уже о субъективных, вроде удобства редактирования текста. Что ты там, Шеркало, говорило про любовь?!

- Я пока молчу, Ёж, я молчу, как морской ёжик в аквариуме с соляной кислотой, продолжай, пожалуйста.

- Не знаю, нужно ли сюда выкладывать картинку с видом среды разработки Borland Pascal 7.0, уж слишком она всем известна? Всё-таки выложу, для полноты повествования:

BP 7.0 был венцом развития Паскаля для операционной системы MS DOS. И это уже был совершенно другой язык, не просто Паскаль от Н.Вирта, а Object Pascal со всеми (почти) преимуществами современной Объектно-ориентированной парадигмы программирования (она сокращается, как "ООП"). Причём внутренне TP/BP остался всё тем же прежним, уютным, изящным и в меру строгим виртовским Паскалем, объектные расширения добавились в язык очень естественным образом, не нарушая сложившийся порядок. Впрочем, подробности парадигмы ООП я здесь расписывать не буду.


А ещё у меня был опыт работы с очень редким Паскалем - Turbo Pascal for Windows. Это такое временное промежуточное звено, когда уже требовалось переходить от DOS к Windows (на тот момент актуальна Windows 3.0), но ничего походящего разработчики придумать ещё не успели. Вот и появился TPfW. Внутри - тот же самый компилятор TP/BP 7.0, но среда разработки переписана с псевдографики на родной интерфейс Windows, и добавлены утилиты для разработки (рисования) частей интерфейса Windows - редактор иконок, дизайнер оконных формочек, генератор ресурсов. Выглядело внешне примерно вот так:

Кстати, самая верхняя функция на той картинке показывает, что работа напрямую с ассемблером никуда не делась, хотя Windows вроде бы и поощряет "высокоуровневое" программирование вместо машинно-зависимого ассемблера. Почему слово "высокоуровневое" я взял в кавычки? А потому что тот самый "высокий" уровень изначально реализовывался через вызовы функций WindowsAPI, которые с точки зрения прикладной программы были максимально низкоуровневыми, ниже просто уже некуда! Вот, для примера, ещё одна картинка с TPfW:

На этой картинке я специально оранжевыми стрелочками выделил сакраментальные функции GetDC/ReleaseDC. О, Шеркало, сколько несчётных раз я вынужден был в своих программах вызывать эту пару функций! Каждый раз, как в очередном окошке Windows требовалось что-то новое вывести (кнопочку "Я - Ёжик" с ёжиком там нарисовать или просто комментарий рамочкой обвести), так нужно было для начала получить Контекст Устройства вывода (Device Context = DC) через функцию GetDC. А закончил рисовать свою кнопочку-рамочку, так изволь тут же немедленно освободить контекст через функцию ReleaseDC. А если ReleaseDC почему-то осталась без вызова, то в следующий раз ты в том же окошке уже ничего не нарисуешь - контекст-то всё ещё занят. И в другом окошке тоже скорее всего ничего не нарисуешь - число свободных контекстов устройств в системе очень сильно ограничено, а кнопочки и закорючки в окошках рисовать не только одна лишь твоя программа желает! И такая вот ерундень повторялась сквозь весь WindowsAPI - хочешь что-то вывести/убрать/передвинуть в окошках, пиши целые листы вызовов функций с маловразумительными списками параметров, плюс функции отлавливания CallBak'ов, которые должны вернуть тебе управление в исключительных ситуациях, и внимательно следи, чтобы они вызывались строго в нужном порядке, несмотря на общую нелинейную схему вызовов с прерываниями по инициативе пользователя.


Честно, если бы Паскаль остановился на уровне TPforWindows с его "чистым" незамутнённым WindowsAPI, вряд ли этот язык остался бы в списке моих любимых. Но разработчики фирмы Борланд сравнительно оперативно предложили новую интегрированную среду разработки (IDE, а так же средство Rapid Application Development = RAD) под названием Delphi, мгновенно ставшую знаменитой. Не то, чтобы Delphi была самой первой IDE/RAD, нет, были интересные системы и раньше, в том числе и под Windows (хотя именно под Windows до Delphi реально было очень мало адекватных сред разработки). Но по совокупности свойств Delphi стала прорывом и образцом для подражаний. Картинку попробую приложить, чтобы два раза не вставать, хотя вряд ли кто-то не видел подобных картинок:

Вот тут реально все возможные прелести собраны в одну кучу! Доведённый почти до совершенства язык Object Pascal (в каком далёком прошлом остались претензии Кернигана к бесполезному "учебному" языку, на котором ничего работающего написать невозможно?!). Нормальная разработка программ под Windows - все ужасы WindowsAPI полностью скрыты "под капотом", а наружу выставлена довольно разумная, и уж точно высокоуровневая библиотека Visual Component Library = VCL. Разработка программы на базе готовых компонентов в рамках модели ООП. Встроенная разработка форм с полноценным интерфейсом Windows, готовый доступ к базам данных, удобный доступ ко многим системным ресурсам... 


- Достаточно, Шеркало? Может быть хватит на сегодня? Может мне тоже пойти, хорька подавить?

- Кажется давно пора.

Комментариев нет:

Отправить комментарий