Entry tags:
Ссылка с planet haskell, IO monad
Теперь про IO.
В ссылке с прошлого поста товарищ жалуется на то, что IO монада лезет в любую дыру без мыла и заражает в итоге любую более менее осмысленную программу.
В этом плане я не совсем понимаю, почему в хаскеле эта монада - одна на все виды взаимодействия с внешним миром? Например, с моей точки зрения чтение и запись файлов совершенно отличается от обращения к серверу БД, что в свою очередь отличается от разговора с пользователем в консоли, что опять же отличается от взаимодействия в GUI, итд. Еще можно вспомнить работу по сети, работу с COM-портами, FFI итд.
Предположительно, было бы гуманно дать программистам возможность самостоятельно делать IO-подобные монады и расселить разные виды взаимодействия по разным монадам, заодно как-то прикрутить к этим монадам некие атрибуты на тему ленивости и порядка вычислений - т.е. например, запись в лог без разницы в каком порядке будет делаться и вообще должна вычисляться только тогда, когда это значение кому-то интересно.
Это я как-то размышлял на тему, "как бы выглядел хаскель, встроенный в СУБД в качестве языка запросов". Я с трудом могу перейти от размышления над обычной программой в стиле "запустили, ввели данные, получили результат" к постоянно запущенной программе, управляемой событиями типа "сервер, ждет запроса от клиентов" или "GUI приложение ждет нажатия кнопки пользователем".
И от "программа читает файл с состоянием, обрабатывает запрос и сохраняет файл обратно" к "программа живет с внутренним состоянием, которое обрабатывается интегрированным в компилятор/виртуальную машину/интерпретатор движком БД.
Реализация IO мешается в голове, а для СУБД нужна была бы еще одна монада (а может и не одна), отражающая внутреннее состояние, упорядочивающая действия с записями, транзакциями и взаимодействием между различными пользователями, лезущими к одним и тем же данным).
PS: Напомнили в комментариях - эта идея у меня возникла еще потому, что монада IO как бы таскает с собой "состояние внешнего мира". А это самое состояние - оно ни разу не монолитное, и его, если по хорошему, нужно разбить на несколько частей ("пользователь", "файлы", "базы данных", "сторонние системы").
В ссылке с прошлого поста товарищ жалуется на то, что IO монада лезет в любую дыру без мыла и заражает в итоге любую более менее осмысленную программу.
В этом плане я не совсем понимаю, почему в хаскеле эта монада - одна на все виды взаимодействия с внешним миром? Например, с моей точки зрения чтение и запись файлов совершенно отличается от обращения к серверу БД, что в свою очередь отличается от разговора с пользователем в консоли, что опять же отличается от взаимодействия в GUI, итд. Еще можно вспомнить работу по сети, работу с COM-портами, FFI итд.
Предположительно, было бы гуманно дать программистам возможность самостоятельно делать IO-подобные монады и расселить разные виды взаимодействия по разным монадам, заодно как-то прикрутить к этим монадам некие атрибуты на тему ленивости и порядка вычислений - т.е. например, запись в лог без разницы в каком порядке будет делаться и вообще должна вычисляться только тогда, когда это значение кому-то интересно.
Это я как-то размышлял на тему, "как бы выглядел хаскель, встроенный в СУБД в качестве языка запросов". Я с трудом могу перейти от размышления над обычной программой в стиле "запустили, ввели данные, получили результат" к постоянно запущенной программе, управляемой событиями типа "сервер, ждет запроса от клиентов" или "GUI приложение ждет нажатия кнопки пользователем".
И от "программа читает файл с состоянием, обрабатывает запрос и сохраняет файл обратно" к "программа живет с внутренним состоянием, которое обрабатывается интегрированным в компилятор/виртуальную машину/интерпретатор движком БД.
Реализация IO мешается в голове, а для СУБД нужна была бы еще одна монада (а может и не одна), отражающая внутреннее состояние, упорядочивающая действия с записями, транзакциями и взаимодействием между различными пользователями, лезущими к одним и тем же данным).
PS: Напомнили в комментариях - эта идея у меня возникла еще потому, что монада IO как бы таскает с собой "состояние внешнего мира". А это самое состояние - оно ни разу не монолитное, и его, если по хорошему, нужно разбить на несколько частей ("пользователь", "файлы", "базы данных", "сторонние системы").
no subject
Подсмотрено в hmatrix: работа с внешней библиотекой линейной алгебры идёт через блоки памяти, которые выделает Foreign.Alloc. То есть, IO. Но. Когда функция "посчитать" отработала, отдала всё, что запросила, с точки зрения стороннего наблюдателя - меня, она выглядит вполне чистой: если мы её вызовем повторно, она вернёт то же самое, и ничего не испортит. Вероятно, поэтому, авторы hmatrix завернули её в unsafePerformIO. Лично я, когда переписывал их код для своих целей, так делать не стал. Но, мне кажется, такой подход имеет право на жизнь. Если "что-то пошло не так", то и launch_missiles и int_plus одинаково плюются исключениями.
Конечно, чем сложней задача, тем сильней протекает изоляция, и тем сложней считать, что unsafePerformIO делать честно.
Вторую мысль поддерживаю всеми руками. Сомневаюсь, что для задачи
Касательно GRIN: если бы у меня хватало времени прочитывать все твои ссылки на нерусские статьи, я бы уже был офигеть каким умным. Те же CSP и π-calculus в моё поле зрения попали не помню когда. Всё никак.
no subject
Производительность. ;)
Читал обсуждение, что внесение IO действий внутрь STM может её поднять - чтобы не откатываться на верхний уровень транзакции, когда мы можем выполнить некоторые полезные действия с учётом (в голове) того, что ресурс нам недоступен. (примерно, я по памяти)
no subject
2. Первая мысль по поводу "не откатываться на верхний уровень" - надо тоньше на транзакции резать, а не засовывать всю программу в один блок atomically.
3. Вторая мысль - что в STM с рождения есть такой недостаток, и на это нам указываем наличие newTVarIO. Даже у авторов возник случай, когда нам нужно что-то контрабандой протащить за границу монады. А значит, и в реальной жизни где-то такое возникнет.
no subject
Ух ты!
Расскажи, как!
Да что там "расскажи". Статью пиши, не меньше!
Утри нос всем этим Пейтонам-Джонам. ;)
>2. Первая мысль по поводу "не откатываться на верхний уровень" - надо тоньше на транзакции резать, а не засовывать всю программу в один блок atomically.
Зависит от программы, не так ли?
>3. Вторая мысль - что в STM с рождения есть такой недостаток, и на это нам указываем наличие newTVarIO. Даже у авторов возник случай, когда нам нужно что-то контрабандой протащить за границу монады. А значит, и в реальной жизни где-то такое возникнет.
Это не то исключение, что ты ищешь. Это сделано для unsafePerformIO.
no subject
2. См. пункт 3. Резать тоньше надо,конечно, но не всегда возможно и не всегда практично. "Случаи разные бывают"
3. Не понял. newTVarIO сделан для того, чтоб TVar можно было отдать в другой поток, ведь forkIO и forkOS - они не в STM работают. А TVar без возможности работы с ним в многих потоках - это какая-то "вещь в себе".
no subject
Не могу найти ссылку, но видел статью,
где прямо указывалось на выигрыш в производительностью,
по сравнению с вариантом с блокировками при большой нагрузке.
no subject
no subject
Я говорил про какой-то общий подход, что-ли...
А это "можно" будет следовать из специфики задачи.
Хотя, конечно, не помешало бы уметь просто и быстро
подстраиваться к этой самой специфике.
no subject
Это считалось выгодным, когда надо обеспечить какие-то полезные действия в случае провала.
Не знаю, прошло ли это куда-нибудь, или нет. Пока не видно.
no subject
no subject