cd_riper (cd_riper) wrote,
cd_riper
cd_riper

Categories:

Delphi 6 -- старый и недобрый

Самое большое наказание для программиста -- сопровождение ужасно написанного кода. Хуже может быть только если этот код в придачу написан другим человеком.

Мне посчастливилось накануне 2011-го года на какое-то время окунуться в тяжелое наследие царского режима -- сесть за поддержку софтины, писанной на Delphi 6 лет этак семь назад. Очень жесткое такое legacy. Код, правда, писан мной, но утешением это служит слабым, так как за это прошедшие годы я очень сильно вырос как программист, а в далеком 2002-м я не только не понимал толком ООП (который прочувствовал только когда познакомился с C#), но и не до конца понимал Delphi, так как хорошие познания были только в области Turbo Pascal'я, а писать что-то под Windows я начал исключительно на основе справки и изучении чужого кода, имея в голове значительные пробелы в некоторых фундаментальных вопросах...



Итак, на какое-то время я перешел от VS2005 и C++ (на этой связке я плотно работаю последние три года) в Delphi 6.

Первое, что напрягает -- не очень продвинутая IDE и полностью другие хоткеи. В свое время IDE от Borland в плане возможностей и наворотов очень сильно опережали продукты от Microsoft (для которых и сегодня обязательно нужно ставить костыли вроде Visual Assist X), но разрыв в четыре года (Delphi 6 вышла в 2001-м) дает о себе знать. К сожалению, некоторые очень полезные вещи губит непродуманность каких-то сущих мелочей. Вот взять, к примеру, Code Explorer (окно показывающее в виде дерева все определения в текущем модуля -- классы, функции etc.) -- очень полезная штука, дык, эта скотина при смене текущего модуля сбрасывает свое состояние, показывая все символы в виде узлов свернутого дерева, и чтобы начать с ним работать нужно делать множество лишних кликов, разворачивающих узлы. Арргх!!

Следующий напряжный момент, это, понятное дело, синтаксические различия Object Pascal и C++. Тяжеловесные begin/end и procedure/function. Обратный порядок определений -- сначала идентификатор, а потом его тип. В 99% случае для оператора if забывал писать then. Синтаксис С, конечно же, значительно более компактный и лаконичный, и быстро переключиться с него не получается.
Прикол со строками, в которых первый символ имеет индекс 1, а не 0. Отсюда циклы не до Length() - 1, а просто до Length(). Для опытного программиста такие штуки это самый настоящий разрыв шаблона, слом вещей, которые зашиты в мозг просто на уровне рефлексов...
Вроде как нормальные массивы на уровне языка, вместо сишнего указательного суррогата. С одной стороны. С другой, для некоторых низкоуровневых штучек это не очень удобно.

Следующий уровень -- ограничения самого языка.
На фоне C++ язык Object Pascal имеет, пожалуй, только два преимущества.
Более богатый RTTI (для реализации которого в том же Qt городят целый зоопарк на основе meta-object compiler). И нормальная система импорта, ибо представить себе что-то страшнее включения заголовочных файлов просто невозможно. Да, и компилируются проекты просто фантастически быстро, плюсы и рядом не стояли... Вспомнил, правда, еще про одну штуку, которая мне очень нравиться -- возможность определять функции, вложенные в другие функции (кстати, в GCC эта штука есть как одно из нестандартны расширений компилятора).

Недостатков у языка -- воз и маленькая тележка. С чего начать?
Определение переменных. Ужасные var секции, невозможность определить и проинициализировать переменную там, где это действительно нужно.
Нечувствительность к регистру в идентификаторах -- поощряет бардак в коде. Я две минуты соображал почему не работает мой код, в котором я полю класса Info присваивал переданный в конструкторе параметр info. И даже, ссука, предупреждения не было!
Дурацкое ограничение -- forward для класса можно сделать только в рамках единой type секции. Отсюда дикая загаженость interface секции, ибо те классы, которые используются только под капотом классов интерфейсных, и которые я бы мог определить в implementation, я вынужден показывать в той же секции, где классы, предназначенные для пользователя.
Нет перегрузки функций (правда, есть параметры по умолчанию). Нельзя писать определение методов прямо в классе (с плюсами понятно, там дурацкий импорт, но ведь есть C#, Java).
Дикий головняк с управлением памятью! Объекты располагаются только в куче, Free надо не забывать вызывать руками. Ни тебе GC, ни тебе RAII. Просто жесть.
И напоследок -- полный пиздец с типизированными контейнерами. Примерно такой же, как был в Java (или C#) до появления generics. На уровне языка есть dynamic array, но пользоваться этим невозможно в принципе, ибо для самой простой и востребованной операции для контейнера -- добавление элемента в конец контейнера (с изменением размера оного) -- требуется писать две отнюдь не тривиальные строчки кода! Причем написать их один раз и вынести в функцию, естественно, не получится, т.к. templates/generics в языке нет, а значит вопрос с жесткой типизацией параметров для этой функции не решить в принципе.
Кстати, очень, очень дурной знак, когда некоторые вещи в библиотеках языка решаются не через средства самого языка, а через всевозможные хаки и нехорошие подпорки со стороны компилятора...

Попытаюсь диалектическим взглядом окинуть историю Delphi.

В свое время (правда было это давным давно, еще при MS-DOS) Borland делала потрясающие инструменты для разработчиков, и Microsoft в ту эпоху, со своими вечными бейсиками, и рядом не валялась.
Потом пришел Windows и встал вопрос, на чем лепить rich GUI приложения.
Понятно, что не С и Win32 API, хотя в ту эпоху героев, выбравших эту связку, хватало.
C++ и MFC? Очень сложный язык в связке предельно неудачным и ужасно низкоуровневым фреймворком.
Visual Basic? Очень простой и дуракоустойчивый язык в связке с визуальным редактором для GUI. Запад выбрал это решение, там VB был чертовски популярным, но сам язык настолько убог и ужасен, что только очень неприхотливый человек будет на нем что-то программировать сложнее хеловорлда.
Ну и Delphi -- самая мощная IDE в связке с языком, значительно более высокоуровневым чем C и значительно более серьезным, чем VB. Да и VCL для своего времени была очень мощная штука, хотя после Qt смотришь на нее другими глазами (компоновка виджетов, очень долгое введение unicode'а etc.).

В общем, на рубеже 2000-х Delphi был далеко не самым плохим продуктом для создания десктопных приложений определенной направленности. Почему именно Delphi победил на территории СНГ, а не VB? Хрен его знает, может потому, что у нас любили учить детей и студентов паскалю, а может из-за тотального пиратства, когда на стоимость инструмента всем было просто посрать и выбирали просто лучшее (как и лучшую операционную систему -- Windows).

Кстати, на Delphi написано очень много хороших и уважаемых мною программ. Например, лучший визуальный diff -- Beyond Compare. Или самая моя любимая программа, без которой я просто как без рук -- Total Commander (по ходу, TC до сих пор собирается с помощью Delphi 2!).
Из того, что еще приходит в голову -- FastStone Image Viewer, AIMP, Skype, QIP, The Bat!, Far Manager, и этот список можно продолжать до бесконечности...

Конечно, сегодня я смотрю на Delphi совсем другими глазами, чем 10 лет назад.
Мне кажется, что язык неприлично сильно заточили под GUI задачи и ОС Windows -- те же message methods, или интерфейсы только в контексте COM.
Сегодня меня очень сильно волнует вопрос кросс-платформенности того или иного используемого мной решения. А Delphi это никем не стандартизированная игрушка в руках одного конкретного вендора, очень сильно заточенная под Windows (нет, про Kylix я не забыл).

И под занавес я приведу небольшой отрывок из интервью одного из разботчика Beyond Compare, которое он дал в прошлом году.

Beyond Compare is written is Delphi. What would you say are the advantages and disadvantages of Delphi compared to other development ‘stacks’?
I think Delphi is still the best tool for developing a native Windows application quickly. It’s very easy to mock up interfaces and then fill them in with code. The resulting exes don’t have any external dependencies, which makes redistributing them easy. The VCL (UI framework) ships with source code, and that has permeated the community, so the vast majority of third-party components also include source.
(...)

If you had to do it all again, starting now, would you still choose Delphi?
Probably, but I would seriously consider C# or Qt. In our case we have a lot of experience with Delphi and we know the libraries, so starting from scratch in another language would be a significant barrier.


(полностью -- http://successfulsoftware.net/2009/02/01/interview-with-craig-peterson-of-beyond-compare/)



Адвокат по трудовому праву. Консультации, Трудовые споры.
Tags: c++, censored, programming
Subscribe

  • Про API

    Евгений Кирпичев затронул тему, о которой рано или поздно задумывается любой мало-мальски опытный программист -- тему о том, должен ли быть доступ к…

  • Судьба

    Советский Союз, хоть и вышел первым в космос, был крайне отсталым государством в IT отрасли -- в свое время было принято решение ни хрена самим не…

  • Загрузочное

    В этой заметке хочу написать об околозагрузочных вещах, которые мы делали в рамках нашего проекта на основе камня от Analog Devices BF-537 (семейство…

  • Post a new comment

    Error

    Comments allowed for friends only

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 33 comments

  • Про API

    Евгений Кирпичев затронул тему, о которой рано или поздно задумывается любой мало-мальски опытный программист -- тему о том, должен ли быть доступ к…

  • Судьба

    Советский Союз, хоть и вышел первым в космос, был крайне отсталым государством в IT отрасли -- в свое время было принято решение ни хрена самим не…

  • Загрузочное

    В этой заметке хочу написать об околозагрузочных вещах, которые мы делали в рамках нашего проекта на основе камня от Analog Devices BF-537 (семейство…