Ссылка с planet haskell, IO monad
Mar. 13th, 2010 11:51 am![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Теперь про IO.
В ссылке с прошлого поста товарищ жалуется на то, что IO монада лезет в любую дыру без мыла и заражает в итоге любую более менее осмысленную программу.
В этом плане я не совсем понимаю, почему в хаскеле эта монада - одна на все виды взаимодействия с внешним миром? Например, с моей точки зрения чтение и запись файлов совершенно отличается от обращения к серверу БД, что в свою очередь отличается от разговора с пользователем в консоли, что опять же отличается от взаимодействия в GUI, итд. Еще можно вспомнить работу по сети, работу с COM-портами, FFI итд.
Предположительно, было бы гуманно дать программистам возможность самостоятельно делать IO-подобные монады и расселить разные виды взаимодействия по разным монадам, заодно как-то прикрутить к этим монадам некие атрибуты на тему ленивости и порядка вычислений - т.е. например, запись в лог без разницы в каком порядке будет делаться и вообще должна вычисляться только тогда, когда это значение кому-то интересно.
Это я как-то размышлял на тему, "как бы выглядел хаскель, встроенный в СУБД в качестве языка запросов". Я с трудом могу перейти от размышления над обычной программой в стиле "запустили, ввели данные, получили результат" к постоянно запущенной программе, управляемой событиями типа "сервер, ждет запроса от клиентов" или "GUI приложение ждет нажатия кнопки пользователем".
И от "программа читает файл с состоянием, обрабатывает запрос и сохраняет файл обратно" к "программа живет с внутренним состоянием, которое обрабатывается интегрированным в компилятор/виртуальную машину/интерпретатор движком БД.
Реализация IO мешается в голове, а для СУБД нужна была бы еще одна монада (а может и не одна), отражающая внутреннее состояние, упорядочивающая действия с записями, транзакциями и взаимодействием между различными пользователями, лезущими к одним и тем же данным).
PS: Напомнили в комментариях - эта идея у меня возникла еще потому, что монада IO как бы таскает с собой "состояние внешнего мира". А это самое состояние - оно ни разу не монолитное, и его, если по хорошему, нужно разбить на несколько частей ("пользователь", "файлы", "базы данных", "сторонние системы").
В ссылке с прошлого поста товарищ жалуется на то, что IO монада лезет в любую дыру без мыла и заражает в итоге любую более менее осмысленную программу.
В этом плане я не совсем понимаю, почему в хаскеле эта монада - одна на все виды взаимодействия с внешним миром? Например, с моей точки зрения чтение и запись файлов совершенно отличается от обращения к серверу БД, что в свою очередь отличается от разговора с пользователем в консоли, что опять же отличается от взаимодействия в GUI, итд. Еще можно вспомнить работу по сети, работу с COM-портами, FFI итд.
Предположительно, было бы гуманно дать программистам возможность самостоятельно делать IO-подобные монады и расселить разные виды взаимодействия по разным монадам, заодно как-то прикрутить к этим монадам некие атрибуты на тему ленивости и порядка вычислений - т.е. например, запись в лог без разницы в каком порядке будет делаться и вообще должна вычисляться только тогда, когда это значение кому-то интересно.
Это я как-то размышлял на тему, "как бы выглядел хаскель, встроенный в СУБД в качестве языка запросов". Я с трудом могу перейти от размышления над обычной программой в стиле "запустили, ввели данные, получили результат" к постоянно запущенной программе, управляемой событиями типа "сервер, ждет запроса от клиентов" или "GUI приложение ждет нажатия кнопки пользователем".
И от "программа читает файл с состоянием, обрабатывает запрос и сохраняет файл обратно" к "программа живет с внутренним состоянием, которое обрабатывается интегрированным в компилятор/виртуальную машину/интерпретатор движком БД.
Реализация IO мешается в голове, а для СУБД нужна была бы еще одна монада (а может и не одна), отражающая внутреннее состояние, упорядочивающая действия с записями, транзакциями и взаимодействием между различными пользователями, лезущими к одним и тем же данным).
PS: Напомнили в комментариях - эта идея у меня возникла еще потому, что монада IO как бы таскает с собой "состояние внешнего мира". А это самое состояние - оно ни разу не монолитное, и его, если по хорошему, нужно разбить на несколько частей ("пользователь", "файлы", "базы данных", "сторонние системы").
no subject
Date: 2010-03-13 12:23 pm (UTC)no subject
Date: 2010-03-13 12:32 pm (UTC)но практически, к сожалению, неудобно
Ага.
no subject
Date: 2010-03-13 12:33 pm (UTC)no subject
Date: 2010-03-13 01:10 pm (UTC)no subject
Date: 2010-03-13 01:16 pm (UTC)Который зависит от неизвестной нам части State of the world. Иными словами - просто зависит от state of the world. И получается, что смысла в отдельном State of the Database нет.
no subject
Date: 2010-03-13 01:22 pm (UTC)Во всяком случае, в моих проектах именно так.
no subject
Date: 2010-03-13 01:28 pm (UTC)Вот смотри: работа БД может переполнить какой-либо ресурс? Например, память или дисковое пространство? Или сокеты. Так, что другим "монадам" не останется, где выполнять свои действия. Если может, то БД неявно взаимодействует с другими монадами, через неизвестный нам канал, спрятанный в State of the world. Если нет, я хочу видеть реализацию этого дела.
Если говорить практически, то сделай монаду для БД по образу и подобию монады транзакционной памяти или рисования в холсте Cairo.
Попробуй с этим поработать. ;)
no subject
Date: 2010-03-13 01:33 pm (UTC)no subject
Date: 2010-03-13 01:48 pm (UTC)Смотри, в GRIN чистые вычисления транслируются в монадический код.
Как ты думаешь, поверх чего работает эта монада? Если там разница между int_plus и launch_missiles?
no subject
Date: 2010-03-13 02:38 pm (UTC)Моя мысль была: DBMonad сделать можно и нужно. Но. Монолитное IO тоже имеет право на жизнь, и это можно обосновать.
no subject
Date: 2010-03-13 02:55 pm (UTC)Одна моя мысль такая: часть функциональности базы данных не зависит от IO. Но часть - зависит. Поэтому взаимодействие между FileM и DBM будет, скорее всего, через эту самую IO.
Другая моя мысль такая: DBM и FileM можно сделать вот уже сейчас. И делают, если это действительно нужно (работа с графикой и обработка сигналов в gtk2hs, или транзакционная память, например). Только это привнесёт такую кучу проблем...
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2010-03-13 07:34 pm (UTC)Как?
не понял вопроса
Date: 2010-03-13 08:41 pm (UTC)Re: не понял вопроса
Date: 2010-03-14 08:45 pm (UTC)Если мы вычисляем его в IO, и в IO же какие-то проблемы с памятью - беда беда. А если начали вычислять в BD, а в IO беда с памятью, а упало всё равно в BD, то что-то не так в датском королевстве.
no subject
Date: 2010-03-13 09:04 pm (UTC)no subject
Date: 2010-03-14 08:49 pm (UTC)Вот если у нас runBD :: BD a -> IO a, тогда наверное логично.
Но я вообще идею поста не очень понял. Т.е. саму идею понял, но детали очень важны, а их нет.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2010-03-13 01:42 pm (UTC)По логике, тогда получается, что нам нужен способ переселиться из FileIO в DBIO где-то внутри СУБД, т.к. внешним клиентам DBIO совершенно не важен.
no subject
Date: 2010-03-13 01:50 pm (UTC)И люди так и делают. В третий раз намекну на транзакционную память и на рисование в Cairo. ;)
no subject
Date: 2010-03-13 12:40 pm (UTC)no subject
Date: 2010-03-13 12:30 pm (UTC)1. IO жостко связывается с многозадачностью (в каком языке самые зеленые треды, ага?). Чтобы обращение одного потока к БД, _ВНЕЗАПНО_ не застопорило все остальные.
2. Инерция мышления. По уму, надо бы эти вещи разгрести и сделать _чистые_ функции доступа к БД, специальную низкоуровневую монаду для компортов, монаду Филе, которая делает POSIX-образный доступ к файлам и т.п.
no subject
Date: 2010-03-13 01:24 pm (UTC)Ради прикола попробуй сделать чтение и запись файла вперемешку с выдачей запроса БД в твоей вселенной, где есть DBM и FileM.
А сокеты, сокеты куда денешь? В FileM или в SocketM?
Получится, что read будет методом класса HasRead: class Monad m => HasRead m where read :: Handle -> m [Char]
И на ровном месте получаем нехилое усложнение.
Кстати, map и ++ для списков стоят отдельно вот уже сколько лет потому, что новичку будет трудно объяснить, почему же map это функтор, а ++ - операция моноида.
Так и здесь - IO монолитно потому, что проще стартовать.
И вот когда уже стартовал, есть возможность сделать и использовать монады для БД, для транзакционной памяти, для рисования в Cairo и тп.
no subject
Date: 2010-03-13 01:38 pm (UTC)POSIX - значит, чтение-запись в File, открытие - лифт из Socket в File.
Но это слишком простой вопрос. Если копать всерьёз, то мы наткнёмся на действительно сложные вопросы дизайна. Потому IO монолитно.
Иещё, не забываем про то, что мы - thread-aware, то есть, мы должны уметь не только (>>=) и return делать, но ещё и сообщать RTS о возможных изменениях состояния потока.
no subject
Date: 2010-03-13 02:20 pm (UTC)А какие с этим проблемы?
Можно писать интерпретирующие монады. Можно ограничивать IO. Можно делать что-то среднее. Простор для творчества.
no subject
Date: 2010-03-13 05:29 pm (UTC)Но как ты этими частями общаться между собой будешь?
Кучу трансформеров городить?
Впрочем, тут тов.
В любом случае, разработчики посчитали, что так, как сейчас, будет практичнее.
Если тебе надо, сам и делай кучу монад на твои жизненные случаи ;-)
Они очень даже бывают, конечно.
Сергей тоже вот правильно говорит.
no subject
Date: 2010-05-18 10:38 am (UTC)