Комментарии 12
Half-Life 3 confirmed?
Макросы это конечно крутая фича кложуры, но их самому лучше часто не писать, потому что их сложно писать и ещё сложнее читать и понимать. Например в вашем макросе, если я напишу следующее:
то моя перемення res будет перезаписана внутренней макросовской res. Для того, чтобы это избежать нужно использовать специальную форму res# которая сгенерит уникальную переменную, которая не сможет пересечься с пользовательской. Тут можно про это почитать в разделе 6.1: www.braveclojure.com/writing-macros/
И ещё вопрос, а нужен ли core.match? Почему бы вместо паттерна не передавать предикат, который будет проверять, валидный ли результат. А то в вашем случае пользователю придётся понимать что такое core.match и как в нём создавать паттерны. Также в использование pipe_matching может стать проще:
Тут используется :ok как предикат и получается, что если в результате есть значения для ключа :ok и оно не nil или false, то значит результат валидный.
(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.
Насчёт «читать внутреннее устройство макросов» — а зачем в этом случае это делать? Просто задаются некоторые правила ( в данном случае требуется паттерн первым аргументом и n-ное количество выражений ) и макрос гарантированно предоставляет определённую управляющую логику для этих выражений — в данном случае pipe matching с заданным pattern-ом (ну если конечно убрать этот баг с «res»))).
Какую логику тут использовать в качестве управляющей — сугубо дело вкуса. Для меня как для erlang-девелопера p.m. — это как глоток свежего воздуха в странноватом пока что для меня языке, вот я и использую его. Ну и строго говоря — предложенный вами вариант это просто частный случай p.m.
Если я все правильно понимаю то родные для closure 1.5 макросы
some-> some->> cond-> cond->>
делают тоже самое и их код тоже весьма приятен
some-> some->> cond-> cond->>
делают тоже самое и их код тоже весьма приятен
Похоже, но не тоже самое. Версия автора это более гибкий some->
Спасибо за статью и интерес к 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
www.erlang.org/doc/man/application.html
www.erlang.org/doc/design_principles/sup_princ.html
www.erlang.org/doc/man/gen_server.html
НЛО прилетело и опубликовало эту надпись здесь
Не знаю)
Название я позаимствовал у одноимённого аналогичного макроса из библиотеки для ЯП Elixir которой пользуюсь. А вообще, возможно такое понятие как «монада» близко pipe_matching. «Возможно» — потому что Haskell я почти не знаю, так что за этот факт не могу ручаться.
Название я позаимствовал у одноимённого аналогичного макроса из библиотеки для ЯП Elixir которой пользуюсь. А вообще, возможно такое понятие как «монада» близко pipe_matching. «Возможно» — потому что Haskell я почти не знаю, так что за этот факт не могу ручаться.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Pipe matching в ЯП Clojure (метапрограммирование в Lisp для начинающих)