Главная » Хабрахабр » [Перевод] Приключения оператора pipeline в babel@7

[Перевод] Приключения оператора pipeline в babel@7

0. В релизе babel@7. Из этой статьи вы узнаете, что такое оператор pipeline и зачем ему нужна конфигурация. 0-beta52 появился новый обязательный флаг конфига для плагина @babel/plugin-proposal-pipeline-operator, что ломает обратную совместимость для предыдущих версий плагина.

Текущий статус

Оператор pipeline берёт своё начало в таких языках, как F#, Hack, Elm, Elixir и других, а при добавлении его в JavaScript возникают два спорных момента: Gilbert Garza, изначально предложивший оператор pipeline, ставил целью получить простой синтаксис для «упорядоченных цепочек вызовов функций в удобочитаемом функциональном стиле».

  • Где и как использовать плейсхолдеры?
  • Как должны работать async / await в пайплайне?

Плейсхолдеры

В Hack плейсхолдеры обязательны для любой правой части пайплайна, например: Первый вопрос был поднят Кевин Смит в этом тикете, где он предложил использовать стиль пайплайнов из языка Hack.

namespace Hack\UserDocumentation\Operators\Pipe\Examples\MapFilterCountPiped; function piped_example(array<int> $arr): int { return $arr |> \array_map($x ==> $x * $x, $$) |> \array_filter($$, $x ==> $x % 2 == 0) |> \count($$);
} var_dump(piped_example(range(1, 10)));

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

Пока что мы выбрали хеш (#), и, хотя дискуссия по-прежнему открыта, любой токен потенциально будет иметь пересечения с другими использованиями. Обратная сторона медали — усложнение языка из-за добавления нового токена. Например хеш также используется приватными полями класса, как и любые другие варианты токена используются так или иначе.

Async / Await

Первый вариант оператора pipeline содержал такой синтаксис для await:

x |> await f

что может быть развёрнуто в:

await f(x)

К сожалению, пользователи вполне могут ожидать и такого разворачивания:

(await f)(x)

Да, есть варианты, как без явного синтаксиса работать с функциями, возвращающими Promise, но все эти варианты слишком громоздкие или требуют вспомогательных функций. Пока буксовала сама идея добавления async в пайплайн, члены комитета высказались против оператора pipeline, который не поддерживает async / await.

Предлагаемые решения

Давайте посмотрим на эти предложения. В результате дискуссий сформировались два предложения (вдобавок к минимальному варианту): использовать F#-пайплайны и Smart-пайплайны.

Минимальный вариант оператора

В минимальном варианте убрана поддержка асинхронности и нет плейсхолдеров. Это предложение касается только базовой функциональности. Он используется больше как черновик-пробник, чтобы выявить преимущества и недостатки других предложений, и вряд ли будет принят без кардинальных изменений, которые есть в альтернативных предложениях. Такой вариант соответствует поведению babel-плагина предыдущих версий, до появления конфигурации, и соответствует текущей спецификации по оператору pipeline в репозитории.

F# пайплайны

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

На текущий момент (по спецификации F#-пайплайнов) стрелочные функции должны быть обёрнуты в скобки:

let person = ; let newScore = person.score |> double |> (_ => add(7, _)) |> (_ => boundScore(0, 100, _));

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

Что касается асинхронности, в F#- пайплайнах await работает как унарная функция:

promise |> await

Что разворачивается в:

await promise

и поэтому await может быть использован посреди длинной цепочки асинхронных вызовов:

promise |> await |> (x => doubleSay(x, ', ')) |> capitalize |> (x => x + '!') |> (x => new User.Message(x)) |> (x => stream.write(x)) |> await |> console.log;

Такая специальная обработка await потенциально может открыть возможность похожим образом использовать другие унарные операторы (например, typeof), но исходная спецификация F#-пайплайнов не содержит их.

Smart-пайплайны

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

promise |> await # |> doubleSay(#, ', ') |> # || throw new TypeError() |> capitalize |> # + '!' |> new User.Message(#) |> await stream.write(#) |> console.log;

Если одиночный идентификатор передан в шаг пайплайна, то никакой дополнительный токен (плейсхолдера) не требуется, это называется «минималистским стилем» ("bare style"): Правила использования плейсхолдеров в Smart-пайплайнах довольно просты.

x |> a;
x |> f.b;

В отличие от Hack, унарные функции не требуют токена плейсхолдера.

Отсутствие токена плейсхолдера в таком случае вызывает раннюю ошибку SyntaxError: Для других выражений плейсхолдер (называемый "lexical topic token" — «лексема тематического стиля») обязателен, а пайплайн считается работающим в рамках «тематического стиля» — "topic style".

10 |> # + 1;
promise |> await #;

Это поможет избежать выстрела себе в ногу и устранить неопределённость. Если имеются какие-либо операторы, скобки (в том числе для вызова метода), кавычки, или вообще что угодно, кроме идентификатора и точки, то токен плейсхолдера обязателен.

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

На сцену выходит Babel

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

Таким образом плагин оператора pipeline требует опции "proposal", как для конфигурирования babylon для парсинга, так и для последующей трансформации. Поскольку парсинг для всех трёх предложений незначительно, но отличается, их поддержка должна быть сначала добавлена в @babel/parser (который babylon), причём парсер должен знать, какое предложение нужно сейчас поддерживать.

Мы бы хотели в итоге сделать один из вариантов пайплайнов дефолтным для плагина, чтобы избавиться от необходимости в конфигурационной опции. Мы работали над этим в оперативном режиме, потому что нам надо сделать все изменения, ломающие обратную совместимость, до того, как babel@7 перестанет быть бетой.

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

Принять участие

К вашим услугам также презентация со встречи TC39. Если хотите участвовать в обсуждении предложения, то все обсуждения публичны и вы можете найти их в репозитории предложения оператора pipeline. S. В конце концов, вы можете обратиться к James DiGioia, J. Choi или к Daniel Ehrenberg в твиттере.

Мы также работаем над добавлением новых возможностей в repl, так что вы сможете проверить свой код и в интерактивном режиме. Но что гораздо важнее, как только работа над pipeline будет завершена, попробуйте его в своих проектах! Отправляйте твиты на @babeljs. Нам нужна обратная связь, и использование в реальном коде очень поможет её собрать.


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Спустя пять лет вышла очередная версия DOSBox под номером 0.74-2

К сожалению, пока внимание толп людей было приковано к анонсам таких гигантов индустрии как Apple, релиз одной некоммерческой, но довольно популярной игровой ретро-платформы, прошел почти незаметно. Вышел DOSBox 0.74-2. Это позволяет играть в такие игры во множестве операционных систем, не ...

Данные пользователей Windows на ПК с поддержкой сенсорного ввода пишутся в отдельный файл

Это сделано для удобства пользователя и ускорения процесса его работы. Большое количество моделей ноутбуков и all-in-one рабочих станций в наше время имеют поддержку сенсорного ввода. Но, как оказалось, у компьютерных систем с активированной поддержкой тач-ввода есть одна малоизвестная функция, которая ...