Ошибка
тысячелетия:
почему
и за что я не люблю HTML
Эта работа обязана своим появлением на свет назревшей
необходимости основательно проанализировать ряд системных недостатков, присущих
современным технологиям “всемирной паутины”, т.е. World Wide Web. Поэтому, в определенном смысле заголовок не вполне
корректен, ведь в список основных Web-технологий, помимо HTML, следовало бы включить и HTTP, CSS, JavaScript (JScript, ECMAScript…), DOM, XML/XSL и многое
другое. Однако, выбор заголовка для статьи определило
то, что в запутанной системе "паутинных" технологий именно HTML можно
считать ключевой и положившей фактическое начало феномену WWW. И все «производные» Web-технологии трудно считать самостоятельными в
прикладном или идейном плане: они являются попытками расширить возможности
базовой технологии — или, как кажется мне, попытками залатать изначально имевшиеся
в ней прорехи.
Стоит также сказать пару слов о том, что заставило
меня взяться за рассмотрение этой темы. Дело в том, что я — системный программист,
и долгое время интересовался проблемами «паутины» мало, и в основном с точки
зрения теории. Практическим Web-программированием мне пришлось заняться скорее по
стечению обстоятельств. Не сочтите за самонадеянность, но когда сталкиваешься с
новой для себя предметной областью, появляется возможность взглянуть на нее
свежим взглядом, как бы со стороны (на что профессионалы в данной области, по
иронии судьбы, зачастую абсолютно неспособны). Думаю, нет необходимости специально
пояснять, что все, сказанное ниже, отражает исключительно мою (возможно,
предвзятую) точку зрения. Читатель вправе делать свои выводы.
Почему мне не нравится HTML, да и Web-технологии в
целом? Начнем с начала.
А начинается любой формальный язык (алгоритмический,
или, в случае HTML, декларационный) с синтаксиса. К синтаксису обычно
предъявляются простые требования: он обязан
быть недвусмысленным, последовательным и логичным, легко поддающимся
компьютерному разбору, но при этом столь же легко доступным программисту —
для визуального восприятия и редактирования. Можно сказать, что синтаксис языка —
это первое, что видит программист, глядя на исходный код программы.
Что в первую очередь бросается в глаза при взгляде на
любой фрагмент HTML-кода? Правильно — чудовищное
количество угловых скобок. Если название языка LISP остряки в свое время расшифровывали как "Lots of Superfluous Parentheses" («уйма избыточных скобок»), то HTML вполне
подошло бы название «уйма избыточных уголков». Правда, в LISP на самом
деле лишних скобок не бывает (каждая несет смысловую
нагрузку, обозначая начало или конец спискового примитива) — в то время
как «уголки» в HTML, по сути, не несут никакой. Несомненное
второе место по популярности занимают «слэши» (/) закрывающих тэгов. То, что открывающие и закрывающие
элементы HTML-кода сделаны столь
трудноразличимыми визуально, крайне
осложняет его чтение и понимание. Еще одно сомнительное «достижение» творцов HTML — корявый синтаксис метасимволов, вроде
или &.
Но, все-таки, самая впечатляющая (на мой взгляд) особенность
HTML — это комментарии типа <!-- комментарий --> (а
других не предусмотрено). Иными словами, чтобы добавить в код страницы простейшее
пояснение, необходимо дополнительно ввести еще семь (!) символов. Полагаю, что среди
компьютерных языков (живых) это несомненный рекорд — большинство прекрасно
обходится для комментариев одним или двумя символами.
Однако, все это еще не самое плохое. Хуже всего то,
что создатели HTML (видимо, обоснованно опасаясь
того, что от ввода всех тэгов пальцы программиста могут превратиться в синяки)
решили сделать большинство закрывающих тэгов необязательными. Но стоило ли наступать на хорошо знакомые грабли?
Самое тяжелое заболевание любого формального языка — это размытость
синтаксиса и наличие необязательных
конструкций. Напротив, давно и хорошо известно, что четкий и строгий синтаксис дисциплинирует, существенно упрощая
процесс кодирования и отлова ошибок.
Наверное, каждый программист в начале своей карьеры неоднократно
обижался на компилятор с
любимого языка ("какой он злой, ругается из-за пропущенной точки с
запятой"). Позднее, приобретя некоторый практический опыт, программисты
начинают понимать, что если компилятор перестанет «ругаться», делать это
придется им самим, причем намного более крепкими словами. Но вот, наконец-то,
сбылась мечта идио… — простите, мечта начинающих:
появился язык, в котором понятие «синтаксическая ошибка» не предусмотрено в
принципе. Пиши, что хочешь, и все равно не ошибешься! Какой бы бред вы не
загрузили в браузер, он его как-нибудь да поймет — он ведь умный…
Уместно задать вопрос: неужели нельзя было изобрести
простой, наглядный и лишенный неоднозначностей способ структурной разметки HTML-кода? Очевидный пример того, как это можно было бы
сделать, подсказывает тот же LISP. Так, вместо
<P><B><I>Ошибка тысячелетия</I></B></P>
значительно проще и удобнее было бы писать что-нибудь
вроде:
P (B (I (“Ошибка тысячелетия”)))
И обратите внимание на кавычки вокруг строки текста!
Мне кажется, что значительно лучше явно разделить собственно текст (т.е. «данные»)
и элементы его форматирования («код»), для чего в языках программирования спокон
веку используют кавычки, чем изобретать заведомо корявые способы внедрения
управляющих элементов в сам текст. Кстати, отсутствие четкого синтаксического
разделения между «кодом» и «данными» оборачивается серьезной брешью в
безопасности, когда источник текстового контента
является ненадежным (скажем, пользователь, пишущий сообщения в гостевую книгу
или форум). Обычно для предотвращения таких проблем приходится вручную
реализовывать проверку пользовательского ввода на сервере (с дополнительной
трансляцией отдельных символов в соответствующие HTML-коды и пр.) — т.е. выполняется дополнительная
работа для решения проблемы, от которой легко можно было б избавиться изначально.
Завершая разговор о синтаксисе, вспомним еще о том,
что у HTML-тэгов бывают и атрибуты —
ничего плохого в этом не было б, если б их синтаксис был более продуманным и
логичным. Было б обоснованным требование заключать в кавычки текстовые или
строковые значения (скажем, в <title>
или <href>) —
но свежие стандарты, вроде XHTML, требуют,
чтобы в кавычках было все, включая и числовые
значения (height=”20”) и символические
константы (align=”left”). Мне это представляется явным абсурдом.
Если вы считаете, что я драматизирую ситуацию,
представьте себе язык программирования с синтаксисом выражений, созданным по
образу и подобию HTML. Иными словами, представьте
себе, что вместо
((A+B) * (C-D)) / 2
вам пришлось бы писать что-нибудь вроде
<expr><expr>A<add>B</expr><mul><expr>C<sub>D</expr></expr><div>2
Для завершения аналогии представьте себе также, что о
любых ошибках, допущенных в подобных конструкциях, компилятор скромно
умалчивает (конечно, исключительно из гуманных соображений, чтобы не
травмировать вашу хрупкую психику). Представили?
Перейдем, однако, от вопросов синтаксиса к семантике,
которая за ним стоит. Рассматривая HTML как
средство описания структуры форматированного гипертекста, прежде всего,
бросается в глаза то обстоятельство, что язык полностью игнорирует различие
между физическим и логическим аспектами форматирования. Поясню.
У текста имеются физические
атрибуты отображения: гарнитура, кегль и цвет шрифта (<font>, <font size=…>, <font color=…>),
его жирность (<b>), курсив (<i>), подчеркивание или перечеркивание (<u>, <s>) и др. Помимо них, есть
еще логические или стилевые атрибуты
разметки: например смысловое выделение фрагментов (<em>, <strong>), заголовки и
подзаголовки (<h1>..<h6>), списки и словари (<ul>, <ol>, <dl>) и множество других видов
выделений, про которые уже мало кто помнит (<address>, <code>, <cite>, <kbd> …). Несомненно, было б лучше, если б различие между
логической и физической разметкой было б отражено более явно (особенно,
учитывая производный характер первой). Было б еще лучше, если б существовало
различие между тэгами, задающими атрибуты фрагментов текста (<font>, <b>, <i>, …) и тэгами, эффект которых распространяется на целые абзацы.
Хуже то, что предлагаемые физическими атрибутами
средства форматирования текста очень ограничены. Важнейшим атрибутом шрифта,
конечно, является гарнитура. Да, ее
можно задать (даже не одну, а целый список) — но все это может оказаться
бесполезным, если заданного шрифта (шрифтов) на компьютере у клиента просто
нет. Значительно проще было б решить проблему, просто передавая клиенту необходимый шрифт вместе с самим документом… вот
только этого как раз сделать было нельзя (до недавнего времени: лишь в HTML 4.1 и CSS 2 механизм
загрузки шрифтов появился).
Кегль шрифта — не менее важный его атрибут. Подход к его
заданию в HTML является своеобразным: задаются (<font size=…>) только
7 (!) типоразмеров шрифта, причем их соответствие реальным кеглям определяется
исключительно настройками и/или личными пристрастиями браузера. (Без средств CSS явно
задать кегль шрифта никак не удастся.)
Ну а те, кто имел дело с профессиональными полиграфическими
технологиями, могут вспомнить, что у шрифтов и текстов бывают еще и другие
немаловажные атрибуты: интерлиньяж, отступы и межабзацные
интервалы, плотность (трекинг), сдвиг относительно
базовой линии, кернинг для символьных пар, определенный контроль над гипфенацией (расстановкой переносов) и т.п. Надо ли
говорить, что всего этого в HTML не
предусмотрено вообще (а в CSS добавлено
очень немногое из приведенного списка). А может быть, я зря занудствую —
ведь все это было в мире скучных бумажных изданий… а
тут у нас, как никак, технология XXI века! Поэтому, даже как-то неудобно
напоминать, что и цвет тоже можно задавать по-разному (кроме столь любимой HTML цветовой модели RGB, ориентированной только на видеодисплеи, существуют
еще CMYK, CIE, Lab, Pantone…), и что
для точного управления цветопередачей бывает еще гамма-коррекция и цветовые
профили.
Однако, публикуемые в Сети
материалы состоят не только из текста. Полезно вспомнить, что формат HTML изначально
предназначался, в первую очередь, для материалов научной направленности. Поэтому невозможно не удивиться тому, что в
рамках формата не предусмотрено базовых средств, например, для математических формул. Правда, есть
надстрочные и подстрочные индексы (спасибо) — но где удовлетворительные средства
для описания (хотя бы) дробей, индексных сумм/произведений, интегралов,
определителей и матриц? Язык для научных
публикаций, в котором формулы и уравнения приходится готовить с помощью
внешних средств и вставлять в текст в виде растровых изображений — это, вежливо
выражаясь, нонсенс.
А ведь, кроме формул, в научных публикациях
(и не только в них, разумеется) очень часто необходимы схемы, графики,
диаграммы, гистограммы и т.п.
Их было бы просто создавать, если б имелись хотя бы базовые средства для векторной графики. Отсутствие последних в
рамках стандартного HTML нельзя ни объяснить, ни оправдать какими-либо разумными
соображениями. Похоже, что вся векторная графика, которая доступна Web-дизайнеру — это разделители типа <hr> и рамки таблиц, а более сложные объекты реализуемы
только через растровую графику. (Относительно недавно, наконец, появился SVG, призванный решить эту проблему — но опять таки,
как внешнее средство, слабо
интегрированное с другими Web-компонентами,
и когда SVG войдет в массовое применение, никто не знает.)
Все перечисленные недостатки HTML выглядят особенно
очевидными при сравнении с другими программными технологиями, также решающими
задачу форматирования текста. Любой текстовый процессор (например, MS Word) имеет, как
ни странно (в силу того, что текстовые процессоры работают интерактивно, от них
резонно ожидать большей ограниченности) существенно более богатый набор средств
форматирования текста. Ну а статические языки разметки, как правило, предлагают
еще больший набор возможностей.
Например, все, кто имел дело с научными публикациями,
прекрасно знают про систему TeX (созданную когда-то самим Дональдом Кнутом). По своей
идеологии, это, как и HTML, язык
разметки текста — но на этом сходство кончается. Ведь TeX неизмеримо
красивее и мощнее: без проблем создаются самые сложные математические формулы, весьма
нетривиальные объекты векторной графики, диаграммы и блок-схемы, имеется бездна
экзотических шрифтов и символов, да и собственно форматирование текста
реализовано намного лучше — на уровне профессиональных издательских систем.
Другой пример — набор технологий, применяемых для
создания руководства (man pages) в UNIX-системах. Конечно, они существенно уступают TeX — но, по своему, тоже
неплохи. Сам базовый язык разметки текста (nroff/troff) имеет мощные механизмы макрорасширения, обеспечивающие
качественное форматирование текста. Есть препроцессоры, позволяющие вставлять в
документ и табличные структуры (tbl), и математические формулы (eqn), и простые объекты векторной графики (pic). При этом также обеспечивается высокая
масштабируемость технологий и средств вывода — результат
может быть выведен с адекватным качеством на большой набор устройств, от простейших
текстовых терминалов до высококачественных PostScript-принтеров.
Вывод напрашивается сам: по многим критериям
Web-технологии не выдерживает конкуренции не только с современными
средствами — но и даже с теми, что были в разработаны (и активно
употреблялись) более десяти лет назад! Где изобретатели HTML были эти
десять лет, мне решительно неясно.
Отдельная печальная тема — вопрос о кодировке текста. Впрочем, об этом уже
написали столько, что просто не хочется повторяться. Ну что поделаешь: разработчики
HTML в свое время забыли,
что на нашей планете еще попадаются языки помимо английского
и алфавиты помимо латинского (а вспомнили об этом поздновато, когда проблема
уже стояла ребром, и разработчики браузеров и сайтов решали ее как придется).
Результат известен: бесконечные религиозные войны на
темы «ставить мета-тэг CHARSET или без него только лучше» или «кто должен определять
кодировку документа — сервер, клиент или они оба» продолжаются по сей день.
Нельзя отрицать лишь то, что образовавшийся хаос придал процессу блуждания по
Сети дополнительную напряженность и драматизм. До сих пор, заходя на новую (не-англоязычную) страницу, мы замираем в ожидании:
договорятся сервер и браузер о кодировке, или опять будем любоваться «кракозябрами» на экране? Кстати, нередко упомянутые кракозябры появляются и при посещении прекрасно знакомой
страницы. Как конечному пользователю, мне неизвестно, кто в этом виноват, да и
не очень интересно: я просто не могу рассматривать технологию, которая подобное
допускает, как качественную
технологию.
Если говорить о собственно верстке текста, то ее
возможности, реализуемые в рамках HTML,
малоудовлетворительны. Прежде всего, как-то управлять размещением текста на
экране позволяют лишь таблицы и фреймовые структуры. Таблицы (изначальным
предназначением которых было, вообще-то, структурирование табличных данных, а
вовсе не решение задач дизайна) являются механизмом, перегруженным
разнообразными атрибутами, опциями, дополнительными тэгами и пр. В этом
хаосе все время путаются даже опытные Web-дизайнеры,
а эффект от взаимодействия противоречивых атрибутов часто бывает плохо предсказуем.
Примерно то же можно сказать про фреймсеты (и фреймы,
встроенные в документ). Этот (сам по себе мощный) механизм слишком плохо
интегрирован с уже имеющимися средствами: он усложняет навигацию, мешает
нормально перезагружать страницу и сохранять ее на диск и т.п.
Удовлетворительной возможности создания перекрывающихся фрагментов текста в HTML как не было, так и нет. В Netscape 4.0 предпринималась попытка ввести слои (<layer>) — она, к сожалению, не имела успеха. Наконец, о
возможности создания текстовых окон непрямоугольной формы (или, скажем,
объединения взаимосвязанных окон в цепочку с перетеканием текста) я просто
помолчу. Конечно, можно возразить, что HTML — это, все-таки, не InDesign или QuarkXPress. Но стоит ли тогда претендовать на роль
универсального языка форматирования документов?
Признаюсь, меня всегда восхищала изобретательность Web-дизайнеров в борьбе с придуманными для них
трудностями. Вместе с тем, даже на самых
профессиональных сайтах нередко встречаются проблемы: то колонки перекосит, то
рекламный баннер куда-нибудь уползет, то верстка развалится по какой-нибудь еще
причине. Вообще-то желательно четко понимать, что само понятие «Web-верстка» звучит как заведомая нелепость. Потому что термин «верстка» изначально предполагает
размещение текста (имеющего определенный кегль, интерлиньяж и другие
метрические параметры) и графических элементов (определенного размера) во
вполне определенных местах листа бумаги. В рамках дисплейной модели HTML (когда неизвестны заранее ни метрические параметры
текста, ни размер области, в которой он размещается) о какой верстке вообще
можно говорить?
Корень проблем, несомненно, лежит именно в крайне
неудачном подходе к идеологии
форматирования экранного вывода. Идеология большинства текстовых
процессоров предполагает наличие листа бумаги с предопределенным форматом:
размерами, полями и т.п. Аналогичный подход принят в языке графического
вывода Postscript и прямо происходящем от него формате документов PDF. На фоне этого ограниченность дисплейной модели HTML просто удручает: размещением текста по умолчанию управляют
текущие размеры окна браузера — т.е. разработчик сайта просто не имеет
прямого контроля над одним из важнейших аспектов визуализации! Если разрешение монитора
у пользователя слишком низкое, текст может на нем просто не поместится (или
будет переформатирован самым уродливым образом), если слишком высокое —
текст может оказаться совершенно нечитаемым и т.д. Многие разработчики сайтов
даже не пытаются воевать с этими трудностями — на их сайтах можно видеть сообщения
о капитуляции, вроде “Best viewed in
800*600”. (Даже не стоит говорить о том, что ультимативное требование держать
окно браузера раскрытым во весь экран обессмысливает саму идею современного
многооконного интерфейса.)
О такой возможности, как увеличение или уменьшение
масштаба просмотра, я просто помолчу. Масштабировать можно лишь собственно
текст (в IE аж на пять уровней, от
"самый крупный" до "самый мелкий"), причем
только если кегль текста не задан в документе жестко (см. выше). А если Вы хотите
увеличить масштаб графики… ну, никто
не мешает сохранить ее на диск, и потом посмотреть на нее в вашем любимом Image Viewer'е.
(Для сравнения взглянем хотя бы на Adobe PDF: жесткий формат страницы
совершенно не препятствует произвольному изменению размеров окна и масштаба
просмотра документа.)
До сих пор мы рассматривали вопросы, касающиеся внутренней структуры Web-страницы. Есть смысл поговорить и о
внешней — о системе логических взаимосвязей
между отдельными подстраницами, образующими Web-сайт как структурное
целое. В рамках традиционной Web-модели их связывает лишь хаотическая система
гиперссылок. Такой подход нельзя признать удачным. Навигация по сайту была бы
намного проще, если б здесь была предусмотрена какая-то иерархия.
Можно видеть немало удачных примеров такого подхода. Все,
кто имел дело с Unix-системами, хорошо знакомы с
системой TexInfo (фактический стандарт
документации для программ Free Software Foundation).
В этой системе каждый документ состоит из множества элементарных фрагментов
текста, или узлов (nodes), организованных в виде дерева (для каждого из них определены
предыдущий, следующий и родительский узлы). При работе с TexInfo запутаться невозможно — всегда известно, в каком именно месте в структуре
документа вы находитесь. (Заметим, что при этом реализованы
и обычные гиперссылки, позволяющие мгновенно перейти к произвольному узлу
документа.)
Более знакомый обычному пользователю пример — стандартная справочная система Windows, реализованная в виде файлов *.hlp. В ней обычно также предусматривается иерархия
разделов документа (и есть окно навигации, позволяющее легко в ней
ориентироваться). Наконец, можно вспомнить и про систему Gopher (кстати, бывшую во многом идейной предшественницей WWW), организованную по принципу «гипертекст + иерархические
меню». Во всех рассмотренных случаях иерархическая и сетевая модели навигации очень
удачно дополняют друг друга. Почему же аналогичная идея не нашла реализации в среде
WWW?
Увлекшись метафорой "паутины", создатели HTML явно
не думали о том, что в незавидной роли мухи оказался именно пользователь. Ему
не пришлось бы путаться среди гиперссылок, если бы система навигации изначально
была бы построена на более четких принципах. Кто-то из известных Web-разработчиков (кажется, А. Лебедев) справедливо замечал,
что традиционная модель навигационного интерфейса, предлагаемая браузерами в
виде кнопок «вперед», «назад», «домой» и пр., контринтуитивна. Т.е. хорошо, что
эти кнопки есть — плохо, что они делают совсем не то, что подсказывает
здравый смысл. Кнопки «вперед» и «назад» должны переходить на следующий или
предыдущий логический раздел (или «узел») в текущем документе. Конечно же, также
должна быть кнопка «вверх», чтобы перейти на родительский узел. Кнопка «домой» должна обеспечивать переход на
начальную («корневую») страницу текущего
сайта (так от нее сразу появится польза). Наконец, совсем не помешало бы дополнительное
окно, показывающее структуру сайта в целом, и позволяющее мгновенно перейти к
любому разделу. А запоминать историю просмотренных страниц тоже полезно —
но при правильно организованной структуре Web-страницы это дело второй или десятой важности (и имеющее
больший смысл в рамках «паутины» в целом).
Помимо упрощения навигации, логическое структурирование
сайта помогло бы решить ряд смежных проблем — так, оно могло бы сделать намного
продуктивнее работу роботов-индексаторов поисковых систем, и предоставило бы
надежный механизм полного скачивания сайта, для пользователей, которым
необходимо посмотреть его в офф-лайн режиме.
Немаловажными для любой компьютерной технологии
являются такие аспекты, как модулярность (modularity) и неизбыточность (reusability). Как с ними обстоит дело в среде WWW? Совершенно неудовлетворительно.
Хотя в это трудно поверить, но в течение долгого времени
просто не существовало средств стилевого форматирования документа помимо стандартных
стилевых тэгов (при том, что во всех без исключения текстовых процессорах
галереи стилей присутствуют с незапамятных времен). Наконец (вместе с HTML 3.0) появился такой механизм, как CSS (Cascading Style Sheets). Прежде всего, это означает, что Web-разработчикам пришлось осваивать еще один язык
описаний (который похож на HTML лишь многословием и зыбкостью синтаксиса, в остальном же вполне оригинален).
При всем этом, понятие «стиля», реализованное в CSS, в сущности, не выходит за пределы простейшей
комбинации набора стандартных атрибутов форматирования. Думаю, что Web-разработчику хотелось бы иметь в своем распоряжении
что-нибудь помощнее. К примеру, хорошо
бы работать со стилями типа «заголовок статьи» (с набором параметров типа
«автор», «заглавие» и т.п.), или «стандартная таблица» (с предопределенными
форматами ячеек, заполнителей, рамок и разделительных линий и пр.).
Безусловно, это намного упростило бы разработку и сопровождение сайтов, страницы которых оформляются стереотипным образом (а также могло
бы существенно оптимизировать процесс загрузки этих сайтов, но об этом чуть
ниже). Может быть, это правильнее называть уже не определением стилей, а макроподстановками?
Но важно не то, как это называть, а то, что ничего подобного просто нет.
Самым существенным недостатком мне представляется отсутствие
даже такой простой возможности, как повторное включение фрагментов HTML-кода (наподобие директив #include C-препроцессора).
(Я подчеркну, что речь идет о реализации такого механизма на клиентской стороне. Все серверные
технологии (SSI, PHP, ASP) это,
конечно, позволяют — но это не очень радует. Есть ли смысл
в многократной передаче через сеть одного и того же фрагмента кода, который мог
бы лежать в кэше браузера и включаться в любой документ
по первому требованию?)
Надо сказать, что многие из затронутых проблем отчасти
преодолимы путем манипуляций с контентом документа через
скрипты и средства DOM. Но при этом, увы, придется иметь дело уже с
проблемами этих технологий, которые мы вкратце и рассмотрим.
Неудачи JavaScript начинаются с названия. Абсолютное
большинство книг по этой технологии начинаются с разъяснения, что Java и JavaScript —
это совершенно разные языки, а изобретатели JS (Netscape) и
изобретатели Java (Sun) —
совершенно разные компании. Мне кажется, было б уместнее название JavaBasic, т.к. если из Java позаимствованы структуры потока управления и отдельные
моменты синтаксиса, то из разных диалектов Basic — многое другое. Сам Basic трудно считать удачным прародителем (проблемы этого
языка слишком хорошо известны), и JavaScript
оказался не лучше, а в некоторых отношениях еще хуже. Я говорю, прежде всего, о
реализованной в этом языке модели
типизации (а, по сути, о практическом отсутствии таковой).
Существующие языки программирования демонстрируют
разные идеологии типизации данных. Традиционным для процедурных языков подходом
(реализованным в С и С ++, Паскале, Java, ADA, многих
других языках) является строгая типизация:
все переменные (также как и функции, компоненты структурных типов данных и т.п.)
предварительно и явным образом декларируются, и попытки выполнения некорректной
операции (не соответствующей заявленным типам операндов) выявляются еще на
этапе компиляции. Конечно, такой подход несколько ограничивает свободу
программиста — зато и борьба с ошибками существенно упрощается. Язык PERL (и
разработанный мною AWL) демонстрирует иной (в определенной
степени противоположный) подход, который можно назвать контекстной типизацией. Переменные в этих языках не декларируются, зато
большинство операций жестко задают тип для своих операндов — например (в PERL) бинарная операция ‘.’
(конкатенация) требует, чтобы операнды были строковыми скалярами, а операция
‘+’ (арифметическое сложение) — числовыми. Если фактический тип операнда не
соответствует предполагаемому, автоматически
выполняется приведение типов, так что
тип результата операции является вполне определенным.
Язык JavaScript
демонстрирует третий подход к типизации, который иначе чем анархическим не назовешь. Предекларирование переменных не предусмотрено, при том, что большинство операций
никак не ограничивает типы операндов — бинарный «+» и складывает числа, и сцепляет
строки. При полном отсутствии какой-либо типизационной
дисциплины — надо ли объяснять, насколько подверженным непредсказуемым ошибкам
становится JavaScript-код?
(Если вас удивляет то, что какой-нибудь из известных
вам сайтов, активно использующих JS, работает не особенно надежно, проведите простой эксперимент:
зайдите на него, предварительно включив трассировку JS-ошибок (в русском IE из меню «Свойства обозревателя» ->
«Дополнительно» -> «Показывать уведомление о каждой ошибке сценария»). После этого вы будете удивляться лишь тому, что этот сайт способен как-то
работать вообще…)
Впрочем, у JavaScript
есть одно большое достоинство: его реализация между браузерами различается
относительно слабо. Этого, увы, никак нельзя сказать про DOM (Document
Object Model) —
набор соглашений, в соответствии с которыми скрипт-код
интерпретирует внутреннюю объектную иерархию
документа. Похоже, что здесь никаких стандартов не существовало, т.е. у
разработчиков браузеров были развязаны руки, чем они и воспользовались сполна. Не
буду долго говорить — приведу в качестве примера фрагмент JS-кода (взятый с одного известного сетевого портала, и
лишь слегка модифицированный для наглядности):
if (document.layers){
// …работать
с DOM Netscape 4.0
else if
(document.all) {
if (navigator.userAgent.indexOf ('Opera') != -1) {
// …работать с
DOM Opera
else
{
// …работать с DOM
IE 4, 5, 6
}
else if (document.getElementById) {
// …DOM W3C compliant (Netscape 6.0/Mozilla и т.д.)
}
Полагаю, что комментариев не нужно. После долгого
глубокомысленного молчания сейчас, похоже, W3C остановился на
последнем варианте DOM (как всегда, выбрав самый
многословный из имеющихся). Теперь чтобы получить элемент документа с
идентификатором ID, нужно document.getElementById("ID")
(просто document.ID
почему-то недостаточно).
До сих пор, однако, мы не рассматривали самый важный
аспект WWW-технологий: их функционирование в глобальной сетевой
среде, предоставляемый Интернетом. Не нужно объяснять, насколько принципиальна
налаженность взаимодействия клиент-сервер и эффективность передачи данных между
ними. (Если б хотя бы это было бы реализовано качественно, многие другие
недостатки можно было б простить.) Для того, чтобы
оценить качество реализации, посмотрим внимательнее на протокол HTTP.
Первый очевидный минус — отсутствие явных
процедур регистрации и дерегистрации пользователя на сервере (большинство других Интернет-протоколов, например Telnet и FTP, этого
требуют). Поскольку HTTP-сервер лишен возможности узнать,
что пользователь прекратил работу с ним (даже если пользователь закрыл окно/окна
сайта, сервер об этом никак не информируется), отслеживание пользовательских
сессий со стороны сервера очень проблематично. Это оборачивается большим
минусом, если необходим, например, сбор статистики о визитах пользователей на
сайт.
Еще более серьезную проблему
я вижу в том, что идеология «один запрос — один Web-объект», которой
придерживается HTTP, не позволяет организовать трафик между клиентом и
сервером оптимальным образом. К примеру, многим Web-страницам требуется большое
количество мелких элементов графики в форматах GIF или PNG —
их имело бы смысл загружать не по одному, а разом, за один HTTP-запрос.
С другой стороны, большой структурированный текстовый документ имело бы смысл скачивать
по частям (например, по главам или разделам), причем асинхронно. Заметим, что
структурная природа HTML-документа на уровне протокола никак не проявляется.
Например, нельзя скачать отдельный фрагмент текстового документа, если
остальные уже имеются у клиента. А ведь это было бы исключительно полезным в
случае, когда содержимое документа меняется относительно редко и/или
инкрементальным образом, что весьма актуально для многих типов сайтов (Web-форумы,
чаты, гостевые книги и т.п.). Представьте себе, насколько «инкрементальная»
передача данных ускорила бы загрузку подобных страниц и уменьшила бы общий
трафик в сети! (Кстати, реализовать такой подход было б нетрудно: для этого
достаточно снабдить каждый узел документного дерева пометкой времени (timestamp), и дополнить протокол
набором команд, позволяющих загружать (в один или несколько приемов) только
содержимое узлов, обновленных после определенного момента.)
Возникают также некоторые
замечания в адрес Web-клиентов — например, управление процессом
загрузки данных со стороны пользователя также могло бы быть организовано более
гибко. Когда сайт грузится, большинство браузеров ограничиваются показом одинокой
полоски, показывающей прогресс (что, учитывая многопоточность
процесса загрузки, выглядит весьма нелепым). Было б намного практичнее, если
для каждого загружаемого элемента страницы показывался бы собственный индикатор
загрузки (а также имелась бы возможность немедленно прервать или приостановить этот
процесс — если, скажем, данной картинкой я любоваться совершенно не хочу).
Конечно, при более структурном подходе к процессу скачивания
это же замечание относится к документу в целом — если меня интересуют,
например, несколько разделов большой статьи, должна быть возможность загрузить
только их, отказавшись от загрузки остального содержимого. Но, как бы конкретно
все предложенное не было реализовано, совершенно неприемлимой
я считаю ситуацию (увы, вполне нормальную при работе с WWW сегодня), когда загрузка Web-документа
просто прерывается на середине, без сообщений об ошибке и каких-либо объяснений
причин.
Предложенные выше идеи отнюдь не выглядят излишней
роскошью, если принять во внимание как чудовищную загруженность Сети (а что
будет через десяток лет?), так и ограниченную пропускную способность каналов у большинства
ее пользователей. Если же реализовать дополнительно несколько вполне очевидных
идей — например, псевдокомпиляцию HTML-контента в какую-нибудь более
компактную разновидность двоичного кода с последующим его сжатием каким-нибудь
алгоритмом поточной компрессии, вроде LZW —
то общемировой объем WWW-траффика, на мой взгляд, может быть уменьшен на порядок. Я даже не говорю о том, что упакованный
таким образом контент занимал бы намного меньше места
в кэшах на клиентской стороне. Не вполне понятно
также, кто мешал реализовать один кэш с единой архитектурой для всех браузеров?
Было б хорошо иметь одну программу — скажем «кэш-сервер», или, «локальный прокси-сервер», услугами которого могли бы пользоваться все
веб-клиенты, установленные на компьютере. Ни для
одной современной многозадачной ОС реализация этой идеи не представляет
проблемы.
Впрочем, пора подвести определенные итоги. В сущности,
высказанные выше соображения вполне тривиальны. Профессионалам «паутины» (от Web-дизайнеров до Web-программистов) недостатки используемых технологий
известны значительно лучше, чем мне. Корни их, безусловно, лежат в проблемной
истории WWW. Ни в коем случае я не хочу обвинить в сложившейся
ситуации создателей «всемирной паутины», начиная с Тима Бернерса-Ли (хорошего,
наверное, физика). Просто не вредно вспомнить, что он создавал не «технологию
будущего», а простенький, написанный буквально «на коленке» инструмент для
обмена с коллегами научными статьями через Интернет. Почему эта технология
получила «приз зрительских симпатий», обойдя своим вниманием лучше задуманные и
лучше реализованные альтернативы (например, дальнейшее развитие Gopher, HYPER-G, XANADU, список
можно продолжить…) можно только предполагать. Скорее всего, дело в том, что
использовать HTML-браузеры можно было
бесплатно, в то время, как альтернативы стоили
небольших, но денег. Потом на HTML сделали ставку
крупные компании — и ее победа стала историческим фактом.
На самом деле, это грустно. HTML, вкупе с производными
от него Web-технологиями, можно смело присвоить звание «PL/1 Интернет-эпохи». Если кто-нибудь еще помнит PL/1 (или даже имел с этим языком дело), то не будет
спорить, что сходство заметно — такой же многословный и корявый синтаксис,
такая же неряшливость в семантике, такое же обилие явных анахронизмов
«совместимости ради», такая же сильная подверженность
ошибкам. И, что интересно, при этом — столь же мощная поддержка со стороны
гигантов компьютерного бизнеса (ну, разве что, вместо Sun, Microsoft и Netscape в те
времена были IBM, Honeywell, Unisys
и другие). На чем эта поддержка
основывалась? Исключительно на слепой уверенности, что программная технология,
в которую уже вложены миллионы долларов и которой пользуются миллионы
пользователей (не получившие, впрочем, особого выбора), в принципе не может
быть плохой, а потому в нее нужно вкладывать дальше и больше. Все-таки
реальность поправила титанов компьютерной индустрии, а средства,
вложенные в разработку программ на PL/1 оказались, по большому счету, выброшены на ветер. Стоило
появиться Паскалю, С и другим современным языкам — и PL/1 был забыт человечеством как кошмарный сон.
Не ждет ли HTML ждет та же участь? Истории
свойственно повторяться. У технологии, отягощенной таким количеством
недостатков и наследственных проблем, вряд ли есть серьезные шансы стать
«технологией будущего тысячелетия». Скорее уж, это крупная ошибка прошедшего.