1) type providers, хотя к Кложуре это не относится.
2) настройка синтаксиса под себя, создание DSL. Замыканиями тупо неудобно пользоваться.
То есть так рассуждать, то можно докатиться до «всё равно всё процессор исполняет, давайте писать тупо на ассемблере». И некоторые ведь пишут, что самое ужасное.
f . g = \x -> f (g x) -- Часть стандартной библиотеки
-- Наш код, data flow справа налево proc = filter (not null) . map g . JSON.parseJson . f
Стало (развернули):
infixr 9 → f → g = \x -> g (f x) -- Придумали сами такое
-- Переписали код, чтобы data flow шёл слева направо. proc = f → JSON.parseJson → map g → filter (not null)
Итого, простейшая функция меняет control flow. Почему это важно? Потому что показывает, что в твоём примере макрос не имеет большого смысла, достаточно просто функции. Даже не замыкания, а простейшей функции.
Там два макроса, один протаскивает значение через первый аргумент всех функций, другой через последний. Что-то мне подсказывает, что в Хаскеле только один из них легко реализуем.
Если все функции одноаргументные, то да, достаточно comp. Если это не только функции, а еще и спец. формы или интероп, то макрос все-таки более универсальный и безгеморройный способ.
Мощь лисповых макросов не оспариваю. Но в существенной степени она лечит именно лисповые закидоны. Например, функции на хаскеле структурированы так, что нужно тащить именно последний аргумент. В редком случае, когда это не так, их можно быстро привести к этому виду (функцией же). Итого, периодическую необходимость протаскиваниея первым аргументом считаем особенностью именно кложи.
Как начинается интероп и пр., появляются монады в дискурсе. Синтаксически это выглядеть будет так же просто, как в лиспе (только без скобок), но опять же, type-sound и написано на одних функциях, без замыканий.
Впрочем, быстрее понять, как макрос наколбасить (или применить существующий), нежели начать уметь такую монаду делать. Разница в learning curve не в пользу Хаскеля.
Макросы используются для создания синтаксических конструкций языка. Раскрытие макроса, в отлиие от функций, происходит во время компиляции, а не в рантайме. Отсюда экономия времени в рантайме.
Против макросов у меня два возражения: трудность диагностики ошибок и непервоклассность. Вы не можете создать значение "частично применённый макрос".
Значение "частично параметризованная функция" создаётся просто замечательно. Более того, раскрывается во время компиляции, а не во время исполнения, экономя время программиста и пользователя.
Отложить вычисления можно через замыкания. Бывают какие-нибудь полезные применения макросов, не сводящиеся к замыканиям?
Reply
2) настройка синтаксиса под себя, создание DSL. Замыканиями тупо неудобно пользоваться.
То есть так рассуждать, то можно докатиться до «всё равно всё процессор исполняет, давайте писать тупо на ассемблере». И некоторые ведь пишут, что самое ужасное.
Reply
Плюс, я ж говорю - срезать углы. Есть разница между:
(->> (f x)
json/parse-json
(map #(g %))
(remove nil?))
и
(let [y (f x)
y1 (json/parse-json y)
y2 (map #(g %) y1)
y3 (remove nil? y2)]
y3)
Reply
Было:
f . g = \x -> f (g x) -- Часть стандартной библиотеки
-- Наш код, data flow справа налево
proc = filter (not null) . map g . JSON.parseJson . f
Стало (развернули):
infixr 9 →
f → g = \x -> g (f x) -- Придумали сами такое
-- Переписали код, чтобы data flow шёл слева направо.
proc = f → JSON.parseJson → map g → filter (not null)
Итого, простейшая функция меняет control flow. Почему это важно? Потому что показывает, что в твоём примере макрос не имеет большого смысла, достаточно просто функции. Даже не замыкания, а простейшей функции.
Reply
Если все функции одноаргументные, то да, достаточно comp. Если это не только функции, а еще и спец. формы или интероп, то макрос все-таки более универсальный и безгеморройный способ.
Reply
Как начинается интероп и пр., появляются монады в дискурсе. Синтаксически это выглядеть будет так же просто, как в лиспе (только без скобок), но опять же, type-sound и написано на одних функциях, без замыканий.
Впрочем, быстрее понять, как макрос наколбасить (или применить существующий), нежели начать уметь такую монаду делать. Разница в learning curve не в пользу Хаскеля.
Reply
Reply
Reply
Reply
Reply
Reply
Reply
Reply
Reply
Значение "частично параметризованная функция" создаётся просто замечательно. Более того, раскрывается во время компиляции, а не во время исполнения, экономя время программиста и пользователя.
Reply
data Book = Book Int String
b = Book 2
можно ли как-то достать значение 2 ?
Reply
Leave a comment