Pull to refresh

Comments 12

Макросы это конечно крутая фича кложуры, но их самому лучше часто не писать, потому что их сложно писать и ещё сложнее читать и понимать. Например в вашем макросе, если я напишу следующее:
(let [res 123]
  (pipe_matching (:ok result)
    (func1 "foo")
    (func2 res))

то моя перемення res будет перезаписана внутренней макросовской res. Для того, чтобы это избежать нужно использовать специальную форму res# которая сгенерит уникальную переменную, которая не сможет пересечься с пользовательской. Тут можно про это почитать в разделе 6.1: www.braveclojure.com/writing-macros/

И ещё вопрос, а нужен ли core.match? Почему бы вместо паттерна не передавать предикат, который будет проверять, валидный ли результат. А то в вашем случае пользователю придётся понимать что такое core.match и как в нём создавать паттерны. Также в использование pipe_matching может стать проще:
(pipe_matching :ok
  (func1 "foo")
  (func2 res))

Тут используется :ok как предикат и получается, что если в результате есть значения для ключа :ok и оно не nil или false, то значит результат валидный.
Огромное спасибо за ценное замечание насчёт # — я реально проглядел так как ещё пока newbie в таких вещах, в репозитории исправлю обязательно перед использованием в продакшне)

Насчёт «читать внутреннее устройство макросов» — а зачем в этом случае это делать? Просто задаются некоторые правила ( в данном случае требуется паттерн первым аргументом и n-ное количество выражений ) и макрос гарантированно предоставляет определённую управляющую логику для этих выражений — в данном случае pipe matching с заданным pattern-ом (ну если конечно убрать этот баг с «res»))).

Какую логику тут использовать в качестве управляющей — сугубо дело вкуса. Для меня как для erlang-девелопера p.m. — это как глоток свежего воздуха в странноватом пока что для меня языке, вот я и использую его. Ну и строго говоря — предложенный вами вариант это просто частный случай p.m.
Если я все правильно понимаю то родные для closure 1.5 макросы
some-> some->> cond-> cond->>
делают тоже самое и их код тоже весьма приятен
Похоже, но не тоже самое. Версия автора это более гибкий some->
По мне выгодней и понятней писать используя стандартную библиотеку, даже в ущерб гибкости.
Да и гибкость тут несколько надуманная — возврат nil в 99% случаев ожидаемое поведение функции, если данные которые она могла бы вернуть отсутствуют.
Спасибо за статью и интерес к Clojure! Одно маленькое замечание — в clojure предпочтительно использовать kebab-case, а не snake_case политику разделения слов в именах. Воспользуюсь случаем и поделюсь ссылкой на стайлгайд github.com/bbatsov/clojure-style-guide
А чего именно из otp вам не хватает в первую очередь? Может быть, я смогу подсказать библиотеки с нужным функционалом.
При разработке на erlang / otp всегда есть 3 уровня абстракции — application, supervisor, gen_server. Application собственно — это дерево с корневым supervisor к которому привязаны другие supervisors, а gen_server в дереве — соответственно листья. И всё это динамическое — то есть может порождаться, прикрепляясь к какому-либо supervisor или умирать. В одном реальном приложении естественно может работать несколько otp-applications

www.erlang.org/doc/man/application.html
www.erlang.org/doc/design_principles/sup_princ.html
www.erlang.org/doc/man/gen_server.html
Наиболее близок из активно поддерживаемых библиотек Pulsar (http://docs.paralleluniverse.co/pulsar/). Хотя конкретные задачи, которые в Erlang решаются с помощью OTP, можно, наверное, иногда решить совсем другим, более характерным для Clojure, способом.
UFO landed and left these words here
Не знаю)
Название я позаимствовал у одноимённого аналогичного макроса из библиотеки для ЯП Elixir которой пользуюсь. А вообще, возможно такое понятие как «монада» близко pipe_matching. «Возможно» — потому что Haskell я почти не знаю, так что за этот факт не могу ручаться.
Only those users with full accounts are able to leave comments. Log in, please.