?

Log in

No account? Create an account

Категория: it

Om, React и все-все-все

Замечательное описание. Я по своему роду занятий стараюсь в вебдев лезть настолько редко, насколько это вообще возможно (в частности, по многим из причин, описанных в этом посте), но прочитал с удовольствием.
Особенно отмечу рассказ про персистентное дерево, которое хранит состояние документа. Идеальная иллюстрация тем нытикам, которые «а нахрен сдались вообще эти ваши алгоритмы и олимпиады во Взрослой Жизни™».

Оригинал взят у tonsky в Om, React и все-все-все. Далее идёт текст оригинала.

React.js — это библиотека, недавно перевернувшая JavaScript-мир с ног на голову одной простой идеей: давайте оперировать не настоящими DOM-елементами, а JavaScript-классами, их изображающими. Синхронизацию этого симулякра с настоящим браузером отдадим библиотеке.


Оказалось, что если не трогать DOM, работать с объектами настолько дешево, что можно их даже не хранить, а всегда дергать функцию state → pseudo-dom, генерирующую каждый раз новый псевдо-дом. Это первое достижение React-а, сделать двухстороннюю синхронизацию данные-интерфейс односторонней. Мы всегда пишем, как из данных получить UI, и никогда не пишем, как один UI перевести в другой UI. На всякий случай еще раз: подход «а вот по этой кнопке скроем панельку» был хорош до определенного предела, пока сайт был в основном статический, с немного меняющимися частями. Сейчас же то, что рисуется в браузере при загрузке, и то, что там будет через 2 минуты, может не иметь ничего общего вообще. Поэтому подход «дайвайте опишем, как эволюционирует наш DOM» работает не очень из-за комбинаторного взрыва — слишком много способов, как он может эволюционировать.


Второе достижение React-а в том, что они реализовали концепцию «всё свое ношу с собой», придав компонентам адекватную стандартизованную структуру. Грубо говоря, в момент создания компонент сам себе нужные ресурсы выделяет и сохраняет в собственный стейт (таймеры, сокеты, листенеры), а в момент удаления — прибирает. Звучит банально, но здесь важен факт, что это есть. Ситуация аналогична проблеме неймспейсов — яйца выеденного не стоит, но в JS их забыли и каждый разработчик вынужден пускаться в собственную езду на лыжах по кирпичам. DOM-листенеры тоже, кстати, крепятся к компоненту, но уже самим react-ом. Это опять же важно для highly dynamic интерфейсов — руками за всеми ресурсами следить и замаешься, и не уследишь.


Получаем, что react-овские компоненты это такие маленькие самостоятельные кирпичики, которые действительно можно складывать в стену и они сами будут работать, не захламляя приложение в неожиданных местах типа регистрации в top-level listener или создаваемых, но никем не удаляемых setInterval.


В общем, я примерно всю революцию уже описал. Можно делать самодостаточные, переиспользуемые компоненты (у них честное воткнул-и-готово), очень простой и мощный data binding (произвольная js-функция state→dom, и не надо выкручиваться в ограничениях template bindinds, и вообще html с шаблоном не нужен), быстрая синхронизация с DOM. React.js маленький-легковесный и это, в целом, opinionless библиотека, которую можно совмещать с чем угодно. Используется Фейсбуком и Инстаграмом, куча баек про то, как интерфейс, переписанный на React, избавляется от проблем со скоростью отрисовки. Но главное, что с ростом количества динамических частей на странице код не начинает катиться в говно экспоненциально. В целом, прорыв уровня jQuery.


Теперь Om. Om — это ClojureScript-биндинг к React-у от David Nolen, главного коммитера ClojureScript, и первая вещь, которую надо про него понять — это не биндинг. Да, он использует React, оборачивает его в cljs интерфейсы, но на самом деле под этой (достаточно выгодной) этикеткой продает свои, совсем другие идеи.


Первая, и очень хорошая — зачем нам рендериться на любое изменение стейта, давайте рендериться один раз на requestAnimationFrame. Мы получим те же 60 fps и еще меньшую площадь соприкосновения с DOM, чем в React. За счет этого, например, он обогнал голый React в ToDoMVC перфтесте.


Вторая — это управление состоянием всего приложения. Если React в этом смысле был достаточно нейтрален (ну, ты, это, давай там сам как-нибудь сам), то у Om насчет состояния вполне четкие планы. Дэвид постаралася сохранить переиспользуемость компонентов и добавить несколько бонусов сверху. Если коротко, то состояние всех компонентов в Om — один большой atom, персистентная структура, а все компоненты получают view в эту структуру на то место, которое относится непосредственно к ним. Т.е. они получают такой handle (в терминах om — cursor), через который они могут читать кусочек этого большого дерева и писать в него. Если компоненту нужны подкомпоненты, можно создать под-курсор из своего курсора, например.


Эта простая идея дает два бенефита:


Возможность показывать в разных местах страницы одно и то же значение буквально. То есть, например, слева у нас таблица сотрудников (компонент table), и в колонке «пол» у них или Man, или Woman. А справа у нас text input для редактирования списка полов, и мы в нем меням Man на Male и в таблице все автоматом синхронизируется. Потому что оба компонента работают с курсором на одно и то же место в атоме. Из-за особенностей реализации text inputs в React можно даже сделать так, чтобы значение в таблице менялось по мере набора букв в text input.


Второй бенефит — это возможность работать с состоянием всего приложения как с чем-то цельным. Это персистентная структура, значит можно хранить историю состояний всего на 100 (например) версий назад, каждое состояние иммутабельное и все они разделяют кусочки, которые не изменялись. Элементарно прикручивается undo, причем на любую версию: ты просто говоришь om-у (а он react-у): давай сейчас вот это состояние рисуй, и react сам вычисляет оптимальный способ его нарисовать из текущего dom: где что удалить/добавить/подвинуть, чтобы получить целевое. Палитру History в фотошопе видели? Короче, бонус в том, что управление состоянием вынесено за скобки. Можно прикрутить логику синхронизации с сервером, undo, сохранение в localStorage — и всё это будет снаружи и отдельно, а не размазано по GUI-компонентам.


Там не всё идеально — документация мутная, курсоры излишне хитрожопо сделаны и не описаны (точнее, сейчас описаны, но это я доку написал), и вообще оно alpha. Но это уже, наверное, самый востребованный GUI-фреймворк на cljs — я думаю, из-за hype вокруг React + имени создателя. Я не то чтобы рекомендую, я скорее популяризирую хорошие идеи, плюс это еще такой спасательный круг тем, кто полезет в Om разбираться.


Вот здесь можно посмотреть на мои эксперименты: игра «41 носок» вживую, исходники.



Цели курса


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

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

  • Научить использовать полезные идиомы, свойственные функциональному подходу, вне зависимости от используемого языка и решаемой задачи.

  • Показать практическое насущное применение ФП. В числе примеров:
    • Алгоритмы параллельного и асинхронного программирования, которые сейчас являются одной из наиболее активно исследуемых областей в IT. В курсе им уделено особое внимание.
    • Принципы работы с объемными потоками/списками данных.
    • Парсинг текста, создание DSL (Domain Specific Language).
  • Познакомить с некоторыми математическими основаниями, на которых строится предмет Computer Science. Показать, что знания теории алгоритмов действительно применимы в практической разработке.


Предварительные знанияСвернуть )

ОрганизацияСвернуть )

Программа курсаСвернуть )

- - - - - - - - - - - - - - - - - -
Планируется к чтению вашим покорной слугой в следующем семестре на факультете ИПСА Киевского политехнического института.

В значительной мере основан на курсе Евгения antilamer Кирпичева, и на SICP, в числе источников также «ПФП», Brian McNamara, Харрисон, курс Дмитрия Сошникова и, конечно же, Guy E. Blelloch. Это не считая собственной практики ACM-олимпиад и алгоритмов плюс еще дюжины различных второстепенных источников.

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

Александр Степанов дал в Яндексе просто потрясающую лекцию. С чем-то можно спорить, чему-то — восхищаться, но смотреть всем обязательно!


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

— А о чем она?

— сложно сказать) начиналось все с того, что его попросили рассказать об обобщенном программировании. он взял пример Главного Алгоритма (тут нет иронии) - алгоритм Эвклида - и показал, как он менялся на протяжении 2500 лет. так сказать, наглядная иллюстрация идеи обобщения, шаблонизации и пр. это первая половина.
а во второй половине, когда исторический экскурс закончился, он плавно перешел к обсуждению идеи, как, по его мнению, правильно программировать вообще - основываясь на материале первой половины. и вот эта часть особенно офигенна, особенно учитывая, что с половиной его фраз хочется тут же согласиться и проповедовать массам, а с половиной спорить в штыки. то есть основной упор в рассказе идет на то, что программирование - это математика. и это он и показывает, доказывает, и рассуждает о текущем положении вещей в программировании и науках вообще.


Выдержки с рутрекераСвернуть )





Полный архив на Rutracker.Org
Давайте рассмотрим все алгоритмы, существующие на свете, и попытаемся узнать, можно ли автоматически, с помощью машины (т.е. опять же алгоритма) отвечать на какие-то вопросы, касающиеся тех или иных алгоритмов.

Рассмотрим два алгоритма и . Назовем их эквивалентными, если на одном и том же входе они оба либо не останавливаются, либо выдают один и тот же ответ.

Любой алгоритм имеет текст. Текст алгоритма — строка в некотором ограниченном алфавите. Так что мы можем выписать все строки, которые существуют в этом алфавите (например, в лексикографическом порядке), этих строк счетное число, и можно пронумеровать их последовательно натуральными числами. Некоторые из этих строк представляют собой корректные алгоритмы, остальные же — "не компилирующиеся" — будем считать алгоритмами, которые всегда зацикливаются. Итак, каждый алгоритм получил свой уникальный номер.

Рассмотрим некоторое числовое множество . Назовем его инвариантным, если выполняется следующее свойство: номера любых двух эквивалентных алгоритмов либо оба лежат в , либо оба не лежат в нем.
Например, множество "Алгоритмы, которые на входе 1 выдают 39" — инвариантно. Аналогично инвариантными являются множества "Алгоритмы, которые останавливаются хоть на каком-нибудь входе", "Алгоритмы, которые возвращают только четные числа", "Алгоритмы, которые никогда не зацикливаются" и так далее.

Фактически, понятие инвариантного множества можно представлять как некоторое свойство алгоритма. Причем мы берем только свойства, характеризирующие алгоритм как класс — зависящие от его входа, выхода и факта конечного времени работы. Например, множество "Алгоритмы, выполняющие ровно 42 шага" — не инвариантно.

Очевидно, если множество — инвариантно, то его дополнение также инвариантно.

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

Множество называется перечислимым, если для него можно построить полуразрешающий алгоритм , который принимает на вход число , и возвращает 1, если , в противном же случае () — зацикливается.
Понятно, что любое разрешимое множество является перечислимым: разрешающий алгоритм легко превратить в полуразрешающий, добавив ему в конец вечный цикл вместо возвращения значения 0. Гораздо интереснее вопрос "Существует ли перечислимое неразрешимое множество?" Правильный ответ — да, существует, и не одно, однако построение конкретных примеров тоже выходит за рамки данного поста.

Теорема Райса (в некоторых редакциях теорема Успенского-Райса) утверждает поразительный факт:
Любое нетривиальное свойство алгоритма является неразрешимым.
Иными словами:
Если некоторое инвариантное множество разрешимо, то имеет место либо , либо .

ДоказательствоСвернуть )
Таким образом, принципиально невозможно построить такую среду/оболочку/систему/IDE, которая по коду данного ей произвольного алгоритма будет автоматически определять, справедливо ли для него какое-то специфическое свойство, каким бы простым и очевидным это свойство ни было. В частности, неразрешима так называемая проблема останова — не существует алгоритма, который по коду другого алгоритма и входному числу определил бы, остановится ли на входе .

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

Если бы.

Метки:

Here Comes Tiburon. Part II

Пришла мне наконец написать давно планируемый пост про один из самых знаменательных релизов Borland, CodeGear и Embarcadero. Про релиз, который, право слово, станет знаменательным. Про релиз, который приносит в нашу жизнь вагон возможностей, который ставит Делфи в один ряд с возможностями многих признанных языков и технологий... короче, харе пафоса =) Всё очень просто. Сегодня я хочу написать в блоге про Delphi & C++Builder 2009 aka Tiburon.

Согласно статье на eWeek, с 25 августа начинается приём заказов. Немногим позже продукт официально выходит в продажу.

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

Оглавление:
Part I: Юникод и параметризированные типы aka дженерики.
 —> Part II: Анонимные методы, IDE и VCL, разнообразное прочее.
Part III: Нововведения в С++Builder`e.


III. Anonymous methodsСвернуть )

IV. IDE и VCLСвернуть )

V. MiscellaneousСвернуть )


Оглавление:
Part I: Юникод и параметризированные типы aka дженерики.
 —> Part II: Анонимные методы, IDE и VCL, разнообразное прочее.
Part III: Нововведения в С++Builder`e.

Метки: