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
но практически, к сожалению, неудобно
Ага.
no subject
no subject
no subject
Который зависит от неизвестной нам части State of the world. Иными словами - просто зависит от state of the world. И получается, что смысла в отдельном State of the Database нет.
no subject
Во всяком случае, в моих проектах именно так.
no subject
Вот смотри: работа БД может переполнить какой-либо ресурс? Например, память или дисковое пространство? Или сокеты. Так, что другим "монадам" не останется, где выполнять свои действия. Если может, то БД неявно взаимодействует с другими монадами, через неизвестный нам канал, спрятанный в State of the world. Если нет, я хочу видеть реализацию этого дела.
Если говорить практически, то сделай монаду для БД по образу и подобию монады транзакционной памяти или рисования в холсте Cairo.
Попробуй с этим поработать. ;)
no subject
no subject
Смотри, в GRIN чистые вычисления транслируются в монадический код.
Как ты думаешь, поверх чего работает эта монада? Если там разница между int_plus и launch_missiles?
no subject
Моя мысль была: DBMonad сделать можно и нужно. Но. Монолитное IO тоже имеет право на жизнь, и это можно обосновать.
no subject
Одна моя мысль такая: часть функциональности базы данных не зависит от IO. Но часть - зависит. Поэтому взаимодействие между FileM и DBM будет, скорее всего, через эту самую IO.
Другая моя мысль такая: DBM и FileM можно сделать вот уже сейчас. И делают, если это действительно нужно (работа с графикой и обработка сигналов в gtk2hs, или транзакционная память, например). Только это привнесёт такую кучу проблем...
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)
(no subject)
no subject
Не могу найти ссылку, но видел статью,
где прямо указывалось на выигрыш в производительностью,
по сравнению с вариантом с блокировками при большой нагрузке.
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
no subject
Главным образом, потому, что к базе могут обращаться много пользователей.
Я так думаю.
> такую кучу проблем
А каких проблем?
Нет, я конечно, догадываюсь.
Но ты скажи, если тебе не сложно.
no subject
Ну, самое простое - как совместить БД и рисование? Чтобы мы выбирали из БД и рисовали, рисовали.
Состояние БД у нас одно на всех, и состояние холста тоже. Оба они инкапсулированы в своих монадах.
Здесь либо работа через каналы - в одном потоке БД вычитывает и передаёт результаты в другой поток, - либо ничего другого мне в голову нейдёт. Буду рад услышать другой вариант.
Вот и связь через IO появилась.
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
no subject
Как?
не понял вопроса
Re: не понял вопроса
Если мы вычисляем его в IO, и в IO же какие-то проблемы с памятью - беда беда. А если начали вычислять в BD, а в IO беда с памятью, а упало всё равно в BD, то что-то не так в датском королевстве.
no subject
no subject
Вот если у нас runBD :: BD a -> IO a, тогда наверное логично.
Но я вообще идею поста не очень понял. Т.е. саму идею понял, но детали очень важны, а их нет.
no subject
no subject
(no subject)
(no subject)
no subject
По логике, тогда получается, что нам нужен способ переселиться из FileIO в DBIO где-то внутри СУБД, т.к. внешним клиентам DBIO совершенно не важен.
no subject
И люди так и делают. В третий раз намекну на транзакционную память и на рисование в Cairo. ;)