parket
Ой я не могу. 🤣
parket
Похоже на проектные требования 🤣
кана
фри все же не про генерацию кода, про которую ты пишешь, тут какой-то спор об разных темах, каждый думает о своем
Dmitry
да я и пытаюсь понять
Dmitry
т.е например для того, что бы пыщь пыщь написали код забыли логи
Dmitry
а тут такие и берем, переопределяем инстанс и добавляем туда логинг
Dmitry
победа
Alexander
Александр ну конечно, хочу преобразовывать
Ну вот в том моем кейсе с персистентными сценариями была задача - передавать сценарии в виде Free -DSL кода. Но как, если есть только методы для дергания сервисов и БД? Нету никаких if, case, и тд. Как сериализовать сам сценарий, написанный на PureScript и этом DSL, но чтобы управляющие конструкции тоже сериализовались? Только вносить их в язык в виде отдельных методов. Но мы решили не идти этим путем, потому что мы можем просто передавать browserified JS, созданный по PureScript-cценарию, и его уже загружать пьюрескриптным движком Workflow. И все получилось.
Dmitry
а можно было просто так
-- Вася, ты забыл вставить логи
log [qc|WTF {a} {b}|]
тут дальше код
Dmitry
конечно, можно скзаать, что нам надо не просто писать логи, а еще внезепно писать в базу
Dmitry
читать из базы
Dmitry
слать в сокет
Dmitry
и еще что-то. ну ок
Dmitry
и при этом не трогая базовый код, написанный архитектором годы назад
Dmitry
и который нельзя трогать.
Dmitry
но если так писать всё, то программа внезапно превращается в интерпретируемую, нет?
Alexander
да
Alexander
причем в несколько
Dmitry
и при этом ограниченную в выразительных средствах
Alexander
т.е. интерпретатор чтобы записать программу в байткод, читалку байткода и интерпретатор
Alexander
но тут есть бонус что структуру все этого можно расшарить
Alexander
Alexander
и с явным словарём
Dmitry
ну да, в общем-то все должно прийти к тому, что если мы не хотим, что бы это люто-бешено тормозило, мы получим таки первосортный AST
Dmitry
его оптимизируем
Dmitry
а потом напишем или на трамплинах, или на llvm/ir генератор кода, который будет быстро работать
Dmitry
ну как быстро
Dmitry
быстрее.
Alexander
https://markkarpov.com/post/free-monad-considered-harmful.html свежачок
Alexander
не то, чтобы я был полностью согласен
Alexander
Dmitry
я пытаюсь сказать, что идея писать внутри хаскеля на каком-то обрезаном язычке обречена, только если в виде исключений. причем в части исключений совершенно точно должен быть внешний dsl
Зигохистоморфный
Dmitry
т.е что бы дать возможность гражданским пользоваться функциями нашей системы на хаскеле
Alexander
> Conclusion
> Of course the title is a click bait and I do not mean to be so categorical. Free monads do have their uses, but in most cases I’d think twice before committing to that style of programming because it’s somewhat tedious and inefficient (unless you’re careful). So the post is just a fair warning and a demonstration of alternative solutions.
Dmitry
идея, что не хаскелисты будут писать на edsl внутри хаскеля = провал
Alexander
понятно, что задачи и толк для freemonad есть
Dmitry
(всё еще ищу)
кана
Alexander
вон то, что у Александр подходит
Alexander
Alexander
(Индийская компания финансовая)
Alexander
там компилятор, интерпретатор, валидатор будут написаны достаточно просто и с одной структурой
Alexander
особенно если на скорость плевать
кана
это как когда мы хотим сделать 3 операции над списком, мы сначала создаем список
x = Cons 1 (Cons 2 Nil)
с тремя дырами (Cons, Cons, Nil)
а потом в foldr заменяем все Cons на функцию, а Nil на значение тремя разными способами (пара (a -> b -> b, b) - это и есть интерпретатор списка)
a = f 1 (f 2 z1)
b = g 1 (g 2 z2)
Free собствено это тоже почти список
Dmitry
Александр я верю, что любую дурь может кто-то делать
Dmitry
люди сначала в уши вставляют себе туннели диаметром с кулак
Alexander
Студенты. Индусы. Интерны. Вы, что ли, хуже?
Dmitry
потом вынимают и уши обрезают/зашивают
Dmitry
т.е нет предела
Dmitry
@qnikst простой компилятор и так написать легко. а сложный - сложно
Dmitry
и фримонада к этому всему относится примерно никак.
кана
Влод
а засчёт чего фри/фрир медленные?
Alexander
засчет, того, что их выполнение это интепретация структуры (которая ещё и не факт, что сфьюзится) в итоге на каждую операцию делаем лишнее. Это даже в случае если у нас condencity есть и сложность не растет с длиной программы
Alexander
(наверняка слова я не все верно употребил
Зигохистоморфный
Зигохистоморфный
во https://qfpl.io/posts/optimising-free-with-plated/
Dmitry
(вспоминает, как в 2001-ом году писал парсер rtf, и в книже Гаммы предлагалось его обрабатывать паттерном Command, и такой обработчик был написан, потом выяснилось, что какой Command не помогает, нужен полноценный контекстно-зависимый парсер, а Гамма или кто там - никогда никакого парсера не писал, зато писал книжку про паттерны)
Andrei
Dmitry
допустим, мы написали на Free парсер-генератор. 1) dsl 2) вроде подходит по семантике-примерам
Dmitry
3) допустим, нам полезно иногда вставить в разбор логи
Dmitry
4) все равно мы выбрасываем всё это, потому что парсер-генератор должен генерировать быстрые парсеры.
Dmitry
end of case.
Alexander
Не очень ясно, как скорость парсер-генератора связана со скоростью генерируемых парсеров
Dmitry
ну, так free ж не генерирует этот парсер, код на free этот самый парсер и есть
Alexander
Ну забейте тогда.
Alexander
Все-таки, это больше для кейсов, когда много бизнес-логики.
Dmitry
да я особо не вижу, чем бизнес-логика отличается от просто логики
кана
еще раз уточню на всякий случай
фри не для генерации кода (и его видоизменения, хоть можно), он для интерпретации кода отдельно (а во время интерпретации нам не нужно знать, что где-то там if, нам важна только следующая команда)
Dmitry
data InstF a
= One a
| Many Int a
| Pause a
deriving (Functor, Foldable, Traversable, Eq, Show)
type Inst = Free InstF
one :: Inst ()
one = liftF $ One ()
many :: Int -> Inst ()
many n = liftF $ Many n ()
pause :: Inst ()
pause = liftF $ Pause ()
Dmitry
из статьи
Dmitry
я правильно понимаю, что здесь забыт
makeFree ''
Dmitry
который и создаёт весь профит? т.е конструкторы написаны руками
кана
да, все три функции можно сгенерить через makeFree ''InstF