Специализни шаблонца! (udpn) wrote,
Специализни шаблонца!
udpn

Отрывочно про веб

Добрый вечер+03:00, дорогой читатель. Сегодня я хотел бы поговорить про веб-разработку.

Этот пост был написан довольно давно, и я надеялся его как-то дополнительно причесать, но у меня не хватило сил поднять эту штангу. Так что вот.

Все, наверное, слышали, про такую игру как испорченный телефон. Она описывает именно то социологическое явление, когда изначально правдоподобные данные становятся абсурдно не похожи на оригинал в процессе передачи информации по цепочке людей. А вы слышали доклад Уильяма Танниклифа в Канадской государственной типографии в 1967 году? Я вот не слышал, и даже не смог найти стенограмму. Но почему-то считается, что именно Танниклиф был первым, кто сформулировал принцип разделения представления и содержимого, используемый сейчас для того, чтобы оправдать разделение HTML и CSS.

Если я правильно понимаю, то в этой трактовке за представление отвечает CSS, а за содержимое — HTML. Любой здравомыслящий читатель, способный разделить логичные суждения от собачьего бреда, понимает, к какой категории отнести эту мысль. HTML не отвечает за содержимое.

За него отвечал бы XML, если бы веб вовремя перешёл на XSLT. Да, сейчас ещё есть следы от начала развития XML в вебе: есть XHTML, есть processing instruction xml-stylesheet. Проблема в том, что из JS на странице оригинальный XML стандартным образом получить уже нельзя. Скорее всего, такой подход исключил бы необходимость во всех этих MV*-фреймворках, которыми пестрит веб. "Скорее всего" потому что XSLT Тьюринг-полон, и многие вещи, которые бы мы ожидали видеть происходящими автоматически, вроде сохранения фокуса на input при обновлении XML-DOM, уже не были бы доступны. Всегда можно было бы сделать well-behaved подмножество, но в этом направлении все полимеры уже просраны.

Сейчас я бы мог верстать практически все страницы, используя только div и ещё несколько тегов, всё остальное бы лежало в CSS. Осталось бы некоторое дерево, которое можно было бы считать отвечающим некой реальной структуре данных, представляемых страницой. Но некоторые из этих div мне пришлось бы написать только из-за того, что в CSS просто пока что нет нужных селекторов или свойств. Борьба комитета стандартизации с попыткой вводить ещё больше селекторов и свойств напоминает рыбака, активно черпающего воду из своей прохудившейся лодки. Ничто не сможет исправить тот факт, что CSS это не нормальный Тьюринг-полный язык.

Кстати, даже несмотря на то, что широко распространено мнение, что CSS не Тьюринг-полон, это, скорее всего, не так. Учитывая, что даже крайне простые вещи вроде Rule 110 полны, представляется крайне сомнительным, что в CSS с жирной как тюлень спекой нельзя найти хоть какой-нибудь вычислительный контекст. Комитет стандартизации явно и недвусмыслено с этим борется, конечно, поэтому я потратил добрых 16 часов на поиск такового контекста, подготавливая материал для этого поста, но так и не смог привести рабочий пример. Где-то так же обстоит ситуация с тем, что комитет стандартизации С++ явно пытался сделать так, чтобы порядок объявлений не влиял на семантику программы, но нихрена у них не получилось. Даже частные члены класса можно без всякого undefined behavior воровать. Впрочем, вот, как обстоят дела.

CSS явно сделан так, чтобы пройтись по списку всех правил один раз, не возвращаясь обратно. Типичная идея well-founded recursion. Проблема в том, что это относится только к ядру языка.

  • Во-первых, уже существует реализация Rule 110, требующая пользователя нажимать на кнопочки, чтобы передать состояние, сгенерированное на предыдущем этапе, в следующий. Даже в таком виде это приятно, поскольку подсказывает вектор для исследований.

  • Во-вторых, мы можем воспользоваться селектором focus. Если исчезает поле, на котором стоит фокус, то он переходит к следующему полю, и стили пересчитываются. Если возможно сделать так, чтобы focus циклически перемещался по набору полей, до Тьюринг-полноты рукой подать. Этот подход заработал не так хорошо, как мне бы хотелось, потому что в разных браузерах работал по разному. В Chrome все поля теряли фокус, а в Firefox фокус с точки зрения CSS стоял на невыделенном поле. Разобраться, как это должно работать, я так и не смог. Может, кто-то из вас осилит этот собачий бред.

  • В-третьих, state можно сохранять с помощью hover. Мы просто делаем так, что элемент, на котором сейчас стоит hover, скрывается с глаз долой, и попутно это тянет появление другого элемента, у которого тоже обрабатывается hover. Возможно, это не работает, поскольку текущий элемент под hover'ом это состояние нашей программы, а это количество конечно и зависит от того, сколько элементов у нас есть в исходнике. Но точно это хорошо работать не будет, потому что авторы браузеров решили оградить эпилептиков от говнодизайнеров, у которых на страницах в связи с hover появляется мерцание. (В этом примере попробуйте подвести курсор справа к тексту. Если у вас нет эпилепсии, конечно.) Фикс заключается в том, что hover не пересчитывается, если курсор не движется.

  • Наконец, есть media query, которые позволяют получить ширину окна. Засовывая media query внутрь iframe мы можем получить размер обрамляющего элемента, а это означает, что у нас появляется возможность зависеть от результата вычислений CSS наружного документа. Если при этом возможно было бы настроить потенциально бесконечное количество вложенных iframe, то мы получили бы Тьюринг-полноту. Впрочем, этот подход станет намного ближе, когда появятся element query.

Подводя итог: и почему нельзя было бы просто сделать нормальный язык программирования?

Вернёмся, наконец, к брехне про разделение обязанностей между HTML и CSS. Есть ещё такая точка зрения, что их стоило разделить хотя бы потому, что на клиенте так легче кешировать. Мол, CSS обычно переиспользуется в разных частях сайта. Тут я обычно задаю два вопроса:

  • А что, HTML не переиспользуется?

  • А что, если бы язык был один, то часть определений нельзя было бы закешировать?

Обычно после этих двух вопросов этот аргумент отпадает. Остаётся ещё один, относительно более серьёзный: так что мне, повторять style на каждом элементе, как это делалось в раннем вебе (cellspacing помните)?

А почему бы и нет? Давайте писать стиль на самом элементе. Вас не устраивает, что стили будут встречаться более одного раза? Code reuse падает? А что обычно делают люди, чтобы с этим бороться? Вводят бесчисленные селекторы? Или, может, всё-таки переменные, функции и, на худой конец, классы? Функции в случае HTML представить себе очень просто: все серьёзные веб-разработчики так или иначе уже пользуются шаблонами.

Что вы там раньше использовали, миксины в SASS/SCSS? Не напоминает наследование? Не напоминает про ФВП? Так зачем городить дополнительные абстракции, если всё делается старыми добрыми приёмами императивного и функционального программирования?

JS, конечно, тоже бесит. Этот ублюдок Эйха имеет ровно одну положительную сторону: красивый способ работы с событиями. Всё остальное там омерзительно: и коэрции с перегрузками, и прототипное наследование с return в конструкторах, где нельзя сделать прототип функционального объекта, кроме как стандартный Function, и где не работает нормально typeof, который вообще хорошему языку не нужен был бы. Оптимизации хвостовых вызовов нет. Зато есть JIT, работу которого понимают только разработчики, а почти все остальные программисты, даже из команды Google Closure, продолжают настаивать, что это панацея, и что JIT волшебно решит неразрешимую задачу и оптимизирует любой код.

Бесит то, что вообще что-то нужно писать. Я, например, люблю сидеть за компьютером ночью в тёмной комнате. Сейчас так и делаю, кстати. И вот, передо мной интерфейс ЖЖ с чистым белым фоном, освещающий всю чёртову комнату. Ребята, мне глаза режет. Что, прикажете каждому сайту имплементить систему смены фона?

Подобного рода проблемы решались и ранее. В Windows почти все кнопки, независимо от программы, рисуются одинаково, и это зависит от темы. Строки вроде "OK" и "Отмена" в текущей локализации прописаны в user32. Короче говоря, программе позволяют избавиться от того, что можно настроить и общесистемно.

Почему же тогда сайты не начнут отдавать просто API? Уже просто по описанию функций, которые доступны в API, легко понять, как это должно выглядеть в интерфейсе. Для сложных сайтов можно добавить какие-нибудь легковесные рекомендации по их выводу. Ответов два:

Во-первых, до сих пор нет нормального стандарта на веб-API. REST крайне тяжеловесен и не позволяет делать вызовы с сервера на клиент. WebSocket ничего не говорит про формат отдельного пакета (хотя уже моменты вроде binary/text формата сообщения говорят, что WS это дерьмо, но об этом дальше). Хорошо работает связка WebSocket + ProtoBuf, правда, формат сообщений всё равно приходится описывать. Правильно это выглядело бы просто как одно общее приложение, где лежит код клиента и сервера, и где компилятор сам придумывает всю логику позади вызова c клиента метода, определённого на сервере, и наоборот. Для этого нужно, чтобы клиент и сервер были написаны на одном языке, а генератору нужна статическая типизация. Cерверный JS уже есть, статическую типизацию, наверное, может дать TypeScript.

Во-вторых, уже есть попытки делать что-то подобное. Все хотят пострелять по лягушкам в Германии лазером из космоса со спутника, создавая микроформаты, RSS/Atom, semantic web, pubsubhubbub, OpenID и прочие микроскопически частные способы делиться чем-нибудь относительно структурированным, не замечая леса за деревьями.

Отдельно хотелось бы поговорить про существующие протоколы. Вот вы читаете этот текст. Вы читаете его в исходном виде, или это уже его представление? Вы ведь не можете воспринимать напрямую номера символов, так? Любой текст на компьютере это представление данных в человекочитаемом виде. Тогда объясните, почему у протоколов вроде HTTP тот факт, что они обмениваются "человекочитаемым" текстом, вызывает предоргазменное состояние у их разработчиков? А сделать GUI поумнее нельзя? Ну ладно, вы можете утверждать, что текстового редактора вам достаточно. Ну сделайте стандартный редактор деревьев или стандартизируйте наконец-то формат описания протоколов, чтобы редактор мог подтянуть из файла или сети биекцию бинарного представления и текста, в чём проблема?

Отдельно гадок сам HTTP. Всем известен принцип single responsibility. Почему тогда HTTP занимается запросом страниц, отправкой данных, хранением персистентного состояния на клиенте (cookie), авторизацией, перенаправлениями, отчётами об ошибках всех сортов и ещё кучей всякого дерьма, полное описание которого даже в один RFC не влезло (7230-7237)? Изначально этот протокол вообще должен был использоваться для того, чтобы можно было редактировать страницы веба напрямую в браузере, что потом напрочь забыли, а недавно присунули какой-то нерабочий contentEditable взамен.

Не понятно вообще, зачем делать всякие URL и e-mail текстом, и потом морочиться с его разбором (ой, нерегулярный язык!), если можно это было сделать деревом, и потом его автоматически (де)сериализовать.

Анонимность, криптографические подписи и P2P тоже должны входить в состав новых стандартов веба.

Я вижу только один выход из сложившейся ситуации.

  1. Всё это говно полностью отправляется на помойку.

  2. W3C бойкотируется.

  3. Стандарты начинают разрабатываться с использованием научного метода.

  4. В первую очередь решается, как сделать так, чтобы никакие решения не уходили в legacy. ProtoBuf показывает хороший пример.

  5. В качестве основных языков веба вводятся байткод с содержимым по типу LLVM и статический язык программирования без небезопасных конструкций, но и без GC, JIT и прочих тормозов. В первый компилируются другие ЯП, которые люди хотели бы использовать для веба, второй используется по умолчанию.

  6. Программам на этом языке выдаются разнообразные API, в первую очередь -- canvas, заменяющий HTML.

  7. Создаются новые легковесные браузеры, их характеристики доказываются формально, особенно все части, связанные с криптографией и безопасностью.

  8. Для существующих браузеров предоставляются расширения, позволяющие ходить в новый веб.

  9. Если кто-то не хочет расширения, тому выдаётся HTML с Asm.js, полученный в результате компиляции чем-то вроде Emscripten.

Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 58 comments