Здравствуйте, Cyberax, Вы писали:
C>reductor wrote:
>> Сделайте уже монаду или итератор для нужных вам ресурсов и в них все >> разруливайте.
C>И чем мне монада поможет, если мне надо _хранить_ открытый файл в C>какой-нибудь структуре?
>> Это не языки не предоставляют, это кому-то хочется свою правоту любым >> способом доказать.
C>Ну так покажите.
C>Вот пример на С++: C>
contents <- readFile "test"
-- теперь в contents ленивый список, который будет читать файл по мере надобности.
-- ничего закрывать не нужно, особенно учитывая то, что фактически файл даже еще не открыт.
processData contents -- далее там разберутся, даже не зная откуда эти данные
reductor wrote:
> вы специально чтоли подставляетесь так. > >contents <- readFile "test" >-- теперь в contents ленивый список, который будет читать файл по мере надобности. >-- ничего закрывать не нужно, особенно учитывая то, что фактически файл даже еще не открыт. >processData contents -- далее там разберутся, даже не зная откуда эти данные > > Все, можете сравнивать.
Начнем с такой мааааааааленькой детали, что файл у меня не читается, а
пишется. Ваш ход....
reductor wrote:
> C>Простите, после ваших откровений об уникальном GC в OCaml'е, который > C>дошел до идеи двух поколений — я не верю, что вы что-то знаете о GC > в Java. > Вот без этого, если можно. > Вы даже не поняля, о чем я там говорил. И о чем здесь тоже.
Вы в этом так уверены?
> C>Еще раз: region inference _элементарно_ делается в С++. Это не требует > C>НИКАКИХ изменений языка, а просто использованием существующих техник. > Вы что, даже не набрали region inference в гугле и не посмотрели ЧТО это?
Смотрел, причем очень давно уже.
> C>Используется из крупных продуктов в Apache 2 (он на С, но на С++ эта > C>техника переносится без всяких изменений). Читайте: > C>http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial-3.html > Great. Приехали. Выведение регионов вручную.
Сюда еще добавляются умные указатели из С++ и оно становится
[полу]автоматическим. В С++ нет closure'ов, так что выведение получается
очень простым.
> Почитайте все-таки что такое region inference, просто регионы и > научитесь делать итераторы и монады для автоматического управления > чего угодно.
И чем мне поможет последовательная комбинация (она же "монада"), для
_хранения_ и _уничтожения_ ресурса?
> О, кстати. Иксепшенами тоже научитесь пользоваться. > Тоже замечательная вещь для многих трюков.
У меня приведенный код, кстати, полностью exception-safe.
> C>КАК???? Покажите пример, где будет использоваться _хотя бы_ нормальный > C>прозрачный refcounted-хэндлер для открытых файлов. > Что, мне нарисовать здесь итератор, закрывающий файл когда нужно?
Да. Только вот итератор должен сам закрываться _сразу_ _же_, когда
станет "ненужным" (i.e. мусором).
> C>Как мне разместить объект OCaml в shared memory? > Вызвать shmget через FFI?
Вызвал. У меня есть указатель на блок shared memory. Что дальше? Как мне
сказать OCaml'у, чтобы он создал объект в этом блоке (и мне не нужно
туда пихать сериализованые данные).
Здравствуйте, Cyberax, Вы писали:
C>reductor wrote:
>> вы специально чтоли подставляетесь так. >> >>contents <- readFile "test" >>-- теперь в contents ленивый список, который будет читать файл по мере надобности. >>-- ничего закрывать не нужно, особенно учитывая то, что фактически файл даже еще не открыт. >>processData contents -- далее там разберутся, даже не зная откуда эти данные >> >> Все, можете сравнивать.
C>Начнем с такой мааааааааленькой детали, что файл у меня не читается, а C>пишется. Ваш ход....
ну ладно, если вы настаиваете, то..
getLazyData >>= writeFile "test"
-- эта конструкция будет писать ленивый список, на другой стороне которого ...
-- а какая, впрочем, разница что там
-- или
withOpenedFile name func = openFile name >>= (\hdl -> func handle >> hClose handle)
-- и потом где угодно вызываете это и отдаете ему функцию на растерзание
Здравствуйте, Cyberax, Вы писали:
C>reductor wrote:
>> C>Простите, после ваших откровений об уникальном GC в OCaml'е, который >> C>дошел до идеи двух поколений — я не верю, что вы что-то знаете о GC >> в Java. >> Вот без этого, если можно. >> Вы даже не поняля, о чем я там говорил. И о чем здесь тоже.
C>Вы в этом так уверены?
Да.
C>Смотрел, причем очень давно уже.
Нет.
Все, я прекратил эту тему уже давно.
Всего хорошего. Остальные детали смотрите в документации.
reductor wrote:
> ну ладно, если вы настаиваете, то.. > >getLazyData >>= writeFile "test" >-- эта конструкция будет писать ленивый список, на другой стороне которого ... >-- а какая, впрочем, разница что там >-- или >withOpenedFile name func = openFile name >>= (\hdl -> func handle >> hClose handle) >-- и потом где угодно вызываете это и отдаете ему функцию на растерзание > > Ну?
Уже лучше.
Теперь учтите, что в одной монаде нельзя записать все данные (например,
часть данных потом получим из сети) и нам нужно где-то хранить открытый
файл между записями. Естественно, хранить данные целиком в памяти тоже
нельзя — они могут в нее не поместиться.
Здравствуйте, Cyberax, Вы писали:
C>reductor wrote:
>> ну ладно, если вы настаиваете, то.. >> >>getLazyData >>= writeFile "test" >>-- эта конструкция будет писать ленивый список, на другой стороне которого ... >>-- а какая, впрочем, разница что там >>-- или >>withOpenedFile name func = openFile name >>= (\hdl -> func handle >> hClose handle) >>-- и потом где угодно вызываете это и отдаете ему функцию на растерзание >> >> Ну?
C>Уже лучше.
C>Теперь учтите, что в одной монаде нельзя записать все данные (например, C>часть данных потом получим из сети) и нам нужно где-то хранить открытый C>файл между записями. Естественно, хранить данные целиком в памяти тоже C>нельзя — они могут в нее не поместиться.
Еще раз — список — _ленивый_
кто-то, читая из него, вызывает вычисление на другой стороне, которое вычисляет данные
data = [1..] -- вообще бесконечный список
или
resources = getFirst : getSecond : getThird : []
они начнут вызываться, только когда их кто-то на другой стороне начнет записывать в файл
Здравствуйте, Cyberax, Вы писали:
C>reductor wrote:
>> Еще раз — список — _ленивый_ >> кто-то, читая из него, вызывает вычисление на другой стороне, которое >> вычисляет данные
C>Я это знаю. Однако, надо как-то показать _завершение_ списка.
C>Как это сделать автоматически? Чтобы список сразу завершился, когда на C>него не останется ссылок.
Что вы в дурачка-то играете, в самом деле
конец списка — это []
как оно будет получено, все само завершится
reductor wrote:
> Что вы в дурачка-то играете, в самом деле > конец списка — это [] > как оно будет получено, все само завершится
Я _не_ _хочу_ явно указывать завершение списка (и в С++ это мне не нужно
делать). Представьте, что этот файл — это log-файл, и надо чтобы он
автоматически закрылся когда станет ненужным. То есть когда на список не
останется ссылок.
Здравствуйте, Cyberax, Вы писали:
C>reductor wrote:
>> Что вы в дурачка-то играете, в самом деле >> конец списка — это [] >> как оно будет получено, все само завершится
C>Я _не_ _хочу_ явно указывать завершение списка (и в С++ это мне не нужно C>делать). Представьте, что этот файл — это log-файл, и надо чтобы он C>автоматически закрылся когда станет ненужным. То есть когда на список не C>останется ссылок.
Тихо, тихо.
Что вы блажите-то, все нормально, успокойтесь
Списочек представляет из себя те данные, которые программочка наша считает
когда данных больше нет, файлик закрывается
reductor wrote:
> Списочек представляет из себя те данные, которые программочка наша считает > когда данных больше нет, файлик закрывается
Как определяется момент, в котором в список больше не будет поступать
данных?
> readFile "test" >>= writeFile "test2" > writeFile "test3" "mama myla ramu" > Никто ничего не закрывает и не открывает, все само.
Я понимаю, что можно открывать/закрывать файл на каждую запись, но мне
это сейчас неинтересно.
> while(i.hasNext()) { stream.write(i.next()); } > после выхода из while все само закрылось.
С чего бы?
Вот такой код:
OutputStream stream = new FileOutputStream(...);
while(i.hasNext()) { stream.write(i.next()); }
вызовет resource starvation в неблагоприятных условиях (объяснить почему
или и так понятно?).
Здравствуйте, Cyberax, Вы писали:
C>reductor wrote:
>> Списочек представляет из себя те данные, которые программочка наша считает >> когда данных больше нет, файлик закрывается
C>Как определяется момент, в котором в список больше не будет поступать C>данных?
Данные поставляет наша программа.
Когда у ней их больше нет, она говорит: извини, фигня, вот тебе []
или вот тебе hasNext() = false
>> readFile "test" >>= writeFile "test2" >> writeFile "test3" "mama myla ramu" >> Никто ничего не закрывает и не открывает, все само.
C>Я понимаю, что можно открывать/закрывать файл на каждую запись, но мне C>это сейчас неинтересно.
Это всего лишь иллюстрация почему не требуется указывать что-то руками.
Вы же не видите тут никаких open и close?
Это не потому, что у вас со зрением плохо.
>> while(i.hasNext()) { stream.write(i.next()); } >> после выхода из while все само закрылось.
C>С чего бы?
это визуализация того, так это работает.
хотите вставьте закрытие в итератор, хотите, в ту функцию, которая берет у вас итератор и пишет из него в файл.
хотите — куда-нибудь повыше.
C>Вот такой код: C>
C>OutputStream stream = new FileOutputStream(...);
C>while(i.hasNext()) { stream.write(i.next()); }
C>
C>вызовет resource starvation в неблагоприятных условиях (объяснить почему C>или и так понятно?).
C>Правильно записывается он так: C>
C>И на Haskell'е это будет выглядеть ну асболютно точно так же.
Нет.
lazyData >>= writeFile "test"
когда кончатся данные, все само закроется.
ну или writeFile "test" lazyData
в зависимости от.
lazyData — это вся наша программа.
или наоборот,
withOpenFile "test" ourProgram -- здесь наша программа получает на вход хэндл и пишет в него.
Когда все закончилось, хэндл закроется внутри withOpenFile
Аналогичным образом может работать что угодно, в том числе и аллокация в модуле Foreign
в extData результат будет результат вызова внешней функции, который мы дали пойнтер, создав его на месте. Освобождать его не нужно, он он освободился автоматически по окончанию.
C>А вот на С++ с автоматическими объектами будет выглядеть вот так: C>
Ну сделайте над собой усилие и найдите уже связь между этим и тем, что я вам показал.
Иначе придется записать вас в неизлечимые.
Потому что вы не можете понять такую простую абстракцию.
Кстати здесь я тоже больше не обсуждаю это. надоело.
reductor wrote:
> Данные поставляет наша программа. > Когда у ней их больше нет, она говорит: извини, фигня, вот тебе [] > или вот тебе hasNext() = false
Еще раз, медленно: код, пишуший в файл, не знает точного момента закрытия.
То есть:
void func(FILE *log)
{
//что-то делаем
fprintf(log,"Operation completed\n");
//а нужно ли нам закрыть файл здесь???
}
Точно так же вашу цитату можно переделать, но для памяти:
Объекты использует программа.
Когда они ей больше не нужны, она говорит: извини, фигня, вот delete.
> Это не потому, что у вас со зрением плохо.
Я вижу попытку взять другой сценарий работы.
> C>С чего бы? > это визуализация того, так это работает. > хотите вставьте закрытие в итератор, хотите, в ту функцию, которая > берет у вас итератор и пишет из него в файл. > хотите — куда-нибудь повыше.
Мне ВООБЩЕ не хочется никуда ставить явное закрытие файла. Сам он должен
закрываться когда нужно.
> C>И на Haskell'е это будет выглядеть ну асболютно точно так же. > Нет. > lazyData >>= writeFile "test" > когда кончатся данные, все само закроется.
А когда данные кончаться? Когда запишут конец потока? А когда запишут
конец потока?
> Ну сделайте над собой усилие и найдите уже связь между этим и тем, что > я вам показал. > Иначе придется записать вас в неизлечимые. > Потому что вы не можете понять такую простую абстракцию.
Я прекрасно понимаю вашу идею с потоком. Мне интересно узнать: как
сделать так, чтобы мне НЕ НАДО БЫЛО явно говорить потоку, что он завершен.
Здравствуйте, vdimas, Вы писали:
V>Соответственно, в тех языках, где нет break, continue и return вполне можно можно использовать goto, если использовать ег ос той же "аккуратностью", какую мы получаем в случае break, continue, return.
Да, да. Полностью согласенж. Если писать с должной акуратностью, то х86-ассемблер лучший язык программирования.
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, reductor, Вы писали:
R>Каков, а! R>Ловко перевел тему опять на Вирта. R>Дийкстру не трогает. Боится. И правильно делает. Могут урыть.
Кстати, а может кто-нибудь объяснить феномен того, что рынок альтернативной ОС захватил Линукс, а не какая-нибудь ФриБСД или еще что-нибудь? Может быть это такой подпольный проект МС?
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Все, последний раз.
>> C>И на Haskell'е это будет выглядеть ну асболютно точно так же. >> Нет. >> lazyData >>= writeFile "test" >> когда кончатся данные, все само закроется.
C>А когда данные кончаться? Когда запишут конец потока? А когда запишут C>конец потока?
Когда данных больше не будет.
Когда iterator.hasNext() = false
>> Ну сделайте над собой усилие и найдите уже связь между этим и тем, что >> я вам показал. >> Иначе придется записать вас в неизлечимые. >> Потому что вы не можете понять такую простую абстракцию.
C>Я прекрасно понимаю вашу идею с потоком. Мне интересно узнать: как C>сделать так, чтобы мне НЕ НАДО БЫЛО явно говорить потоку, что он завершен.
Ему ничего не надо говорить. Поток представляет данные
внутри потока тот код, который их вычисляет.
который в какой-то момент прекращает это делать и все закрывается.
Не понимаете?
ничем не могу помочь.
Почитайте что такое first-class computations
Хоть что-нибудь почитайте.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, reductor, Вы писали:
R>>Каков, а! R>>Ловко перевел тему опять на Вирта. R>>Дийкстру не трогает. Боится. И правильно делает. Могут урыть.
VD>Кстати, а может кто-нибудь объяснить феномен того, что рынок альтернативной ОС захватил Линукс, а не какая-нибудь ФриБСД или еще что-нибудь? Может быть это такой подпольный проект МС?
А вот благодаря скандальности создателя и захватил.
Это у него не в первый раз такое.
reductor wrote:
> C>А когда данные кончаться? Когда запишут конец потока? А когда запишут > C>конец потока? > Когда данных больше не будет.
А когда данных больше не будет?
> Когда iterator.hasNext() = false
В данном примере все просто. А если этот поток используется в десяти
местах в программе (т.е. если это log-файл)? Когда следует закрывать его?
> C>Я прекрасно понимаю вашу идею с потоком. Мне интересно узнать: как > C>сделать так, чтобы мне НЕ НАДО БЫЛО явно говорить потоку, что он > завершен. > Ему ничего не надо говорить. Поток представляет данные внутри потока > тот код, который их вычисляет. > который в какой-то момент прекращает это делать и все закрывается.
Код, который их вычисляет — это была бы вся остальная программа (в
случае log-файла). В общем случае, ее невозможно переписать таким образом.