parket
Ой я не могу. 🤣
parket
Похоже на проектные требования 🤣
кана
фри все же не про генерацию кода, про которую ты пишешь, тут какой-то спор об разных темах, каждый думает о своем
Dmitry
да я и пытаюсь понять
Dmitry
т.е например для того, что бы пыщь пыщь написали код забыли логи
Denis
но обычно это не нужны разные интепретаторы, а ЗАТО МЫ МОЖЕМ ДЕЛАТЬ РАЗНЫЕ ИНТЕРПРЕТАТОРЫ
ну я что-то совсем гипотетически нужное могу представить, если f параметризован во фри еще чем-то, но я хз что дальше с этим делать
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
и который нельзя трогать.
Зигохистоморфный
а тут такие и берем, переопределяем инстанс и добавляем туда логинг
или делаем монадическую алгебру и паратримизируем любой монадой, например writer или любая другая а монадический катаморфизм это все свернет в то, что нам надо вместе с эффектом
Dmitry
но если так писать всё, то программа внезапно превращается в интерпретируемую, нет?
Alexander
да
Alexander
причем в несколько
Dmitry
и при этом ограниченную в выразительных средствах
Alexander
конечно, можно скзаать, что нам надо не просто писать логи, а еще внезепно писать в базу
Ну вот смотри. У тебя сотни сценариев на твоем free dsl. Тебе не хочется везде логи пихать. Ты идешь в интерпретатор, где только 20 методов, вставляешь в каждый по соответствующему логу, и все твои сотни сценариев начинают отлично логгироваться.
Alexander
т.е. интерпретатор чтобы записать программу в байткод, читалку байткода и интерпретатор
Alexander
но тут есть бонус что структуру все этого можно расшарить
Alexander
и с явным словарём
Dmitry
ну да, в общем-то все должно прийти к тому, что если мы не хотим, что бы это люто-бешено тормозило, мы получим таки первосортный AST
Dmitry
его оптимизируем
Alexander
с mtl тоже самое
Я этого не отрицаю.
Dmitry
а потом напишем или на трамплинах, или на llvm/ir генератор кода, который будет быстро работать
Dmitry
ну как быстро
Dmitry
быстрее.
Alexander
https://markkarpov.com/post/free-monad-considered-harmful.html свежачок
Alexander
не то, чтобы я был полностью согласен
Alexander
https://markkarpov.com/post/free-monad-considered-harmful.html свежачок
Так это кликбайт. Внутри-то хорошее написано.
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
(всё еще ищу)
кана
я пытаюсь сказать, что идея писать внутри хаскеля на каком-то обрезаном язычке обречена, только если в виде исключений. причем в части исключений совершенно точно должен быть внешний dsl
да это не урезанный язык, это тот же хаскель, весь, просто вместо реального вызова эффектной функции у нас дыра, которая потом заменяется на что-то эффектиное в интерпретаторе
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 не помогает, нужен полноценный контекстно-зависимый парсер, а Гамма или кто там - никогда никакого парсера не писал, зато писал книжку про паттерны)
Alexander
засчет, того, что их выполнение это интепретация структуры (которая ещё и не факт, что сфьюзится) в итоге на каждую операцию делаем лишнее. Это даже в случае если у нас condencity есть и сложность не растет с длиной программы
А в случае с возобновляемыми сценариями там еще и каждый шаг, каждое ветвление записывается, чтобы при остановке сценария прокрутить все это с самого начала, не исполняя эффектов. Но зато именно интерпретация позволяет создать resumable persistable сценарии
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