?

Log in

No account? Create an account

Стой под стрелой

Поступки и мысли, о которых могу вспомнить не краснея

Previous Entry Поделиться Next Entry
Расширяемость
усы2
tonsky

Ковырялся я тут на досуге во внутренностях react.js, и вот что я хочу сказать вам о JavaScript вообще.

Я познакомился с JS когда это был вполне себе простой и понятный язык. Раз: любому объекту в любой момент можно добавить любое свойство, и два: один объект может иметь прототипом второй, тогда свойства ищутся по цепочке. Всё. Конечно, эта кажущаяся простота нелегко давалась разработчикам компилятора, но нам-то, пользователям, было хорошо. Просто и гениально. Я как-то недостаточно наблюдал восторгов по поводу красоты концепции.

Реализация кое-где хромала, конечно. Свойство prototype, к примеру — не путать с идеей прототипов — настоящий бред. Если бы его быстренько — ну, в ES3 там, или раньше — зафиксили, народ бы не ныл и не просил классов. Ну или использование объектов как структуры данных-словаря, до сих пор эпичнейшие баги всплывают, типа того что на npm нельзя создать библиотеку с именем constructor. Мне кажется, именно из-за этого JS-программистов и следом вообще всю frontend-разработку не считают за «настоящее» программирование.

Но реализация — дело наживное. Главное, что языку больше ничего и не надо. Можно стандартную библиотеку доделать, добавить массивы и словари настоящие, и можно вполне писать. Питон как-то так и работает, и много что на нем можно сделать.

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

Ведь почему мы так любим Кложу? Потому что в ней принято делать открытые системы (с подачи Рича, конечно). Первое — библиотеки гоняют данные, и на вход, и на выход, и внутри. Данные, понятно, открыты, это не классы, их легко распечатать, легко поменять, сгенерировать в нужном виде — короче, библиотека никак не диктует, что и как вам делать с данными. Второе — протоколы, протоколом прикинуться легко. Третье — открытые неймспейсы, куда можно при необходимости залезть, посмотреть, поменять что-то. Позволяет, например, тестировать даже то, что для тестирования не предназначалось.

Это приводит к тому, что почти всегда библиотеку на Кложе можно понять и можно заставить делать то, что нужно. Очень трудно загнать пользователя в угол, если только специально не прилагать усилий. Это важно, и я рад, что Кложе-сообщество подхватило этот тренд.

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

Не надо так.



Да, не надо.

Но будут втаскивать, потому-что "учитывать ровно одну вещь" слишком напряжно для 99% процентов разработчиков. А проще чтобы по рукам, блять, по рукам ему, суке, компилятором.

(Удалённый комментарий)
На npm стопиццот библиотек в том числе и из-за таких вот умников https://github.com/blakeembrey/change-case

> Every method is also available on npm as an individual package.

> Общественное мнение склоняется к тому, что разработчику библиотеки виднее, что выставлять наружу, а что нет. Приватные свойства, закрытые лексические скоупы

Это всё не просто так же. В большом программировании есть такеи люди, которые вволю задействуют потроха библиотеки, и при замене этих потрохов в следующей версии библиотеки у них всё нахрен ломается. И обвинять в этом, как ни странно, будут авторов библиотеки. И потому что по мере того как js становится языком программирования, вероятность такой ситуацоо увеличивается. Так что привыкайте.

А какие вообще существуют мантры объяснения зачем разделения на public/protected/private ?

А вот комментом ниже объясняют :)

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

Ну так это проблема пользователей, нет? Завязался на кишки — обновись во время апгрейда библиотеки.

What Killed Smalltalk Could Kill Ruby, too.

Uncle Bob

Классная лекция, спасибо за ссылку! Интересно, конечно, ждет ли Clojure судьба Smalltalk. У Clojure лучше история с интеграцией в enterprise и с существующим кодом, но language wars, ×5 программисты и все такое имеется (возможно, в меньшей степени)

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

Примерно поэтому я категорически против того, чтобы Dart пошел в массы, да.

Александр

(Анонимно)
Что-то такое чувствие, что обман в посте

Если есть private, protected, public (не важно в каком виде), т.е. возможность скрыть реализацию, что помогает гарантировать совместимость, уменьшает сложность разработки и поддержки.

Зачем нужно постоянно лезть в кишки реализации?
А вот если мы отказываемся от этих public..., то что получаем в замен?

Re: Александр

Хм, я же вроде объяснил что. Я не говорю что разделения на публичное АПИ и приватное не должно быть. Я говорю что оно должно быть рекомендательным, как, например, в Питоне: компилятор и рантайм не делает никакой разницы между приватными данными и обычными, никакого доступа не ограничивает, все это просто намек разработчику.

Re: Александр (Анонимно) Развернуть
Про бессонных рубистов не понял. Что именно им не снилось? Там интроспекция и манкипатчинг пронизывают все феномены, как всепроникающее страдание дуккха нашу вселенную.

я протестую, мы не страдаем, мы получаем удовольствие)
реплу кложи до нашего pry ещё года два-три, судя по вкусам сообщества кложи

(Анонимно)
+1, тоже не понял

К тому же, скрыть реализацию в JS тоже можно без проблем, просто завернув кишки в замыкание.

Я не очень понял против чего ты именно.

JS в эпоху до модулей был известен тем, что с большой вероятностью что-то больше 200кб кода превращалось в кровавые кишки. Модули - таки благо, и позволили строить что-то масштаба реального приложения.

Если конкретно про реакт - то они на полдороги вроде одумались: ООП свое убирают, VDOM делают из простых хешей. Но открывать вообще всё внутренности - зачем?

Вроде да, я с 12-ой версией ковырялся.

> JS в эпоху до модулей был известен тем, что с большой вероятностью что-то больше 200кб кода превращалось в кровавые кишки. Модули - таки благо, и позволили строить что-то масштаба реального приложения.

Я вот этого не очень понимаю. Неужели чтобы сделать что-то масштаба реального приложения надо обязательно все инкапсулировать так, чтобы до внутренностей было не добраться?

А кто втаскивает? Committee? Лавры шайки четверых не дают спать спокойно?

1) Я согласен, что в целом с т.н. инкапсуляцией существует сильный перегиб, зачастую до идиотизма.

2) Но и повсеместная открытость всех данных иначе как киданием в крайность не назовёшь.

3) В прикладных приложениях например, финансах и тому подобное, без сокрытия данных на клиенте вообще никак.

4) Ещё бывают "детали реализации", которые в принципе никому не интересны, кроме автора. Имеет смысл закрыть. Но тут иногда сложно определить, что именно относится к этой категории

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

Нужно и так, и так.

Смотри, есть например две известных реализации промисов – Q и bluebird.

Q – прожорливая и небыстрая. Зато она параноидально защищена от мутаций и нештатного использования снаружи и не экспонирует внутренние методы. Это очень важно, если ты заранее не знаешь, что за код подпишется на твой промис.

bluebird напротив blazing fast and lean. В блюбёрде переписаны даже реализации массивов например – и они быстрее, чем нативные в js. Но блюбёрд экспонирует внутренние методы и не защищает промис – что сразу ограничивает его применимость – никакого подключаемого из неизвестных источников кода тут, конечно, быть не может.

В реальной жизни бывает нужно и так, и так. Более того, иногда в одном проекте нужно сразу оба подхода. И god bless js, что можно использовать сразу оба.

Ну запуск стороннего кода это очень специфичная и узкая задача, нет? Странно было бы чтобы ее аспект пронизывал дизайн всего остального, обычного, подконтрольного программисту кода.