Re[26]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 10.01.14 21:48
Оценка:
Здравствуйте, alex_public, Вы писали:


_>Я вообще то говорил не про некие отвлечённые, а про вполне конкретные примеры из поставки wxWidgets. Т.е. идём в папку wxWidgets (она у меня уже много лет на компьютере), видим там папку samples и в ней ещё 86 папок с примерами на все случаи. Аналогично с wxHaskell, только там насколько я помню примеров намного меньше. Находим одинаковые и сравниваем код. Я это сделал когда-то, когда смотрел на Haskell вообще и получил вполне однозначные выводы. Сейчас прямо за секунду (а иначе лень) легко повторить это не могу, т.к. уже давно стёр и wxHaskell и сам Haskell у себя с компьютера, как не нужное. Но если кто-то хочет проверить мои слова, то алгоритм очень простой. Причём я указал на эти самые примеры в первом же своём сообщение на эту тему.


Прекрати сочинять, ты потратил уже несколько часов на тему, как тебе лень тратить больше секунды на этот вопрос
Re[41]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 10.01.14 22:10
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Надо полагать это у Питона фишка такая — баги в программах имплементить.


Как и у любого языка с динамической типизацией) Их нельзя использовать в серьёзном проекте, не обкладывая при этом тоннами тестов.
Re[63]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 10.01.14 22:19
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Для того, что бы посчитать, сколько лишнего мусора в твоем коде. Кроме как сравнения с формализмом самой предметной области это сложно сделать.


Вообще то если поправить форматирование (БНФ у тебя в строчку, а в Спирите тоже самое на 4 раскидал) и не вставлять вещи типа namespace'ов (причём тут они к грамматике?), то выглядит практически одинаково.

I>AST нужен не просто так, а для конкретных вещей. Т.е. ты вводишь узел не там, где тебе надо кусочек грамматики описать, а там где тебе нужен этот узел


Можно и так. А можно и сразу.

I>Нет, разумеется. Какой смысл делать для символов?


Тогда я всё же не понял пока, тебе выдаётся дерево или что? Если дерево, то почему не целиком?

I>Я не знаю, что такое ADC


АЦП в смысле.

I>Тем хуже для тебя. Если не помогли ни примерЫ, ни ссылки на работы, то напрашивается один вариант — тебе нравится только императивный код и ничего другого ты видеть не хочешь.


Что-то ты совсем не понял меня. Ну я сейчас накидаю примерчик, так что поймёшь)
Re[35]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 10.01.14 22:40
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Ну так надо делать не "шаблоны", а нормальный параметрический полиморфизм.


Чего чего? ) Это в смысле в рантайме?

K>Никакого реалистичного способа исправить "нетипизированность" шаблонов, разумеется, нет. Любое исправление просто сломает существующий код.


Речь шла не про плюсы, а про гипотетический язык с шаблонами, в котором компилятор их полностью проверяет.

K>Отличная шутка. Вообще-то норма, это когда проверяется именно исходники (бывает, что до рассахаривания), а потом уже генерируется код.


Правильно, исходник по которому генерируется код. И только он, а не некие абстрактные исходники. Для последнего существуют всяческие статические анализаторы. Хотя для обсуждаемой темы они естественно тоже не помогут.

K>Просьба прокомментировать заявление про ужасы IO была тоже очень давно. Сами сопоставить примеры вы отказываетесь, от объяснений уклоняетесь, указать что именно не нравится в моем примере вы не хотите.


Я не собираюсь повторяться в третий раз. Даже дважды уже было много. Тем более, что в ответ не услышал даже одного раза.

K>Понятно, что если мы перейдем к следующему пункту, то к этому уже не вернемся, на что вы, похоже, и рассчитываете. У меня же все основания настаивать на подробном обсуждении этого вопроса есть: преимущества контроля за эффектами будут выглядеть как оправдания каким-то невнятным ужасам, которые я вроде-бы автоматически признаю, переходя к следующему вопросу. Такой вариант меня не устраивает.


Да да, конечно же совсем не признаёте... http://www.rsdn.ru/forum/philosophy/5407470
Автор: Klapaucius
Дата: 23.12.13
)))
Re[41]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 10.01.14 22:55
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Ну так вот эта функция apply — и есть монада. Точнее, чтобы она была монадой, надо к apply добавить функцию по конверсии "чистого" значения в "монадный" тип, и обеспечить выполнение монадических законов.

S>Всё. Спор выглядит странным — это всё равно как говорить, что в С++ никакого ООП нет, а есть только данные и методы.

Ничего подобного. Это гораздо больше чем монада. И будет монадой только для определённого сочетания типа аргумента и функции. Т.е. могут быть варианты:

1. Функцию R(T) применяем к типу Т
2. Функцию M<R>(T) применяем к типу Т
3. Функцию R(M<T>) применяем к типу Т
4. Функцию M<R>(M<T>) применяем к типу Т
5. Функцию R(T) применяем к типу M<Т>
6. Функцию M<R>(T) применяем к типу M<Т>
7. Функцию R(M<T>) применяем к типу M<Т>
8. Функцию M<R>(M<T>) применяем к типу M<Т>

И всё это в одной концепции. Монадой же из всего этого будет только вариант 6. А будет ещё просто применение функций, фукторы и т.д. и т.п.
Re[61]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 10.01.14 23:24
Оценка: 102 (1)
Здравствуйте, Ikemefula, Вы писали:

I>Когда спирит научится реактивный парсинг делать, тогда и сравним перформанс. А пока что сравнивать не с чем.


Собственно я тут подумал, а почему бы и нет! Ведь в той старой темке я тебе так подробно доказывал преимущества Boost.Coroutine на выдуманных тестовых примерах, а тут же на самом деле прямо идеальный реальный примерчик нарисовался. Причём он ещё и оптимальным по быстродействию может быть с учётом минимальных требований Спирита на входной итератор.

Значит смотри, вот пример обычной работы на Спирите:
string s="-333,-22,-1,0,1,22,333";
int sum=0, count=0;
parse(s.cbegin(), s.cend(), int_[([&](const int& n){cout<<n<<'\t'<<double(sum+=n)/++count<<endl;})]%',');

Данный код выдаёт очевидный результат:
-333    -333
-22     -177.5
-1      -118.667
0       -89
1       -71
22      -55.5
333     0


Теперь попробуем заставить Спирит работать реактивно. Для этого я написал (пара десятков строчек) некий класс rstring. Имея его, мы можем написать так:
rstring rs;
rs>>[&](){
    int sum=0, count=0;
    parse(rs.cbegin(), rs.cend(), int_[([&](const int& n){cout<<n<<'\t'<<double(sum+=n)/++count<<endl;})]%',');
};
for(auto& s: {"-3", "3", "3,-22,-1", ",0,1,22,333,"}) rs<<s;//заталкиваем реактивно куски строк в парсер

Как видно, код самого парсера вообще не изменился. И естественно этот код выдаёт такой же результат как и первый вариант.

Ну что, покажешь аналоги этих примеров на базе тех монадных библиотечек? ) И тогда можем ещё и быстродействие сравнить (я поправлю примеры чтобы брали данные из файла и пришлю готовые бинарники), если рискнёшь конечно. )))
Re[42]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 10.01.14 23:25
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Как и у любого языка с динамической типизацией) Их нельзя использовать в серьёзном проекте, не обкладывая при этом тоннами тестов.


Это сказки. В динамическом языке прежде всего код пишется проще, его намного меньше.

Теоретически, это достижимо и в С++, но на практике дл интеграции нужно специальное АПИ. Высокоуровневые вещи, внезапно, это вагоны темплейтов, конские иерархии и сложные макры, через которые очень трудно продираться. А вот аналогичное АПИ на динамичеком языке предельно простое. Вот мне непонятно, как работает pipe, открыл да посмотрел — смешное количество строчек кода. А в С++ только перчисление только темплейтов и скобочек будет раз в десять больше.
Re[37]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 10.01.14 23:33
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Этот код не работает. Как только в него приедет startSync и endSync по частям, ваш логгер облажается.

S>Представьте на секунду, что Analyze вызывается на каждый приехавший символ.

Всё нормально там будет, строка накапливается в js. Т.е. если startSync и endSync приходят хоть по одному символу (но Analyze всё же вызывается построчно, т.е. в каждой строке по кусочку от startSync/endSync), то никаких проблем. Вот если весь Analyze вызывается для каждого символа (т.е. не по строкам, по которым там фильтрация осуществляется), то тогда действительно надо переделать.

S>В этом-то и сложность конверсии активного кода в реактивный — там, где активный код пишет "вынь да полож мне следующие 8 символов" (и встаёт в ожидании завершения IO, если у него исчерпался буфер), реактивный код должен уметь вернуть управление сразу же, как только отпроцессил входные данные.


О да, дико сложно. ))) http://www.rsdn.ru/forum/philosophy/5424925
Автор: alex_public
Дата: 11.01.14


S>Поэтому, например, корректных реактивных фильтров контента в ASP.NET приложениях в природе не встречается. Весь Analyze сводится к накапливанию аргументов в буфере, а сам анализ происходит по завершению.


Ну это проблемы исключительно ASP.NET. Как видно, достаточно универсальное решение делается на C++ всего в пару десятков строчек. )))
Re[62]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Evgeny.Panasyuk Россия  
Дата: 11.01.14 01:01
Оценка:
Здравствуйте, alex_public, Вы писали:

I>>Когда спирит научится реактивный парсинг делать, тогда и сравним перформанс. А пока что сравнивать не с чем.

_>Собственно я тут подумал, а почему бы и нет! Ведь в той старой темке я тебе так подробно доказывал преимущества Boost.Coroutine на выдуманных тестовых примерах, а тут же на самом деле прямо идеальный реальный примерчик нарисовался.

Я думал вы договорились Boost.Coroutine не использовать, поэтому и не упоминал
А так да — на корутинах можно легко приделать реактивный парсинг к Boost.Spirit.

Вообще, stackful coroutines можно использовать для упрощения использования многих монад, например optional<T>/expected<T>/future<T>/generator<T>(которая в свою очередь эмулирует корутины)/etc. Буквально недавно это обсуждалось в C++ ISO Proposals.
Но такая техника применима не ко всем монадам. Например это неприменимо к монаде list<T>, потому что одно и то же продолжение может вызываться несколько раз, а для stackful coroutine такой фокус не прокатит (стэк изменяется, объекты деструктятся и т.п.). Грубо говоря нужен полноценный call/cc.
Я думаю для stackless coroutines таких ограничений нет — объекты-автоматы можно копировать и вызывать несколько раз для одного checkpoint'а.

_>Для этого я написал (пара десятков строчек) некий класс rstring.


В новой версии Boost.Coroutine есть интерфейс input/output итераторов. По идее должно быть достаточно boost::coroutines::coroutine<char>::pull_type::iterator + boost::spirit::make_default_multi_pass.
Re[63]: Есть ли вещи, которые вы прницпиально не понимаете...
От: alex_public  
Дата: 11.01.14 03:57
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Я думал вы договорились Boost.Coroutine не использовать, поэтому и не упоминал

EP>А так да — на корутинах можно легко приделать реактивный парсинг к Boost.Spirit.

Хы, не, просто у меня есть привычка не заявлять непроверенный код. А проверять лень было, поэтому я про короутины и не упоминал. Но как видишь, народ меня всё же "добил" своими рассказами о великой сложности задачи реактивного парсинга, так что я ненадолго отбросил лень и набросал код. )))

EP>Вообще, stackful coroutines можно использовать для упрощения использования многих монад, например optional<T>/expected<T>/future<T>/generator<T>(которая в свою очередь эмулирует корутины)/etc. Буквально недавно это обсуждалось в C++ ISO Proposals.


О, это отдельная интересная тема для обсуждения... Вообще C++ в интересном направление стал сейчас развиваеться.

Правда она несколько противоположна тому моему примеру. Я же в нём как бы наоборот использую короутины, чтобы реализовать реактивный парсинг без всяких явных монад.

EP>Но такая техника применима не ко всем монадам. Например это неприменимо к монаде list<T>, потому что одно и то же продолжение может вызываться несколько раз, а для stackful coroutine такой фокус не прокатит (стэк изменяется, объекты деструктятся и т.п.). Грубо говоря нужен полноценный call/cc.

EP>Я думаю для stackless coroutines таких ограничений нет — объекты-автоматы можно копировать и вызывать несколько раз для одного checkpoint'а.

Только их ещё конструировать надо самому. )

EP>В новой версии Boost.Coroutine есть интерфейс input/output итераторов. По идее должно быть достаточно boost::coroutines::coroutine<char>::pull_type::iterator + boost::spirit::make_default_multi_pass.


О, значит в новой версии может получится вообще автоматом? ) Позитивно. А у меня 1.53 стоит и я при выходе новых как-то не заметил, что короутины поправили. Надо будет посмотреть и возможно обновиться.

Но в любом случае даже свой код очень простой и короткий вышел (я использовал ещё boost::iterator_facade).
Re[64]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 11.01.14 08:54
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Вообще то если поправить форматирование (БНФ у тебя в строчку, а в Спирите тоже самое на 4 раскидал) и не вставлять вещи типа namespace'ов (причём тут они к грамматике?), то выглядит практически одинаково.


Нет, не одинаково. В спирите как видно, раза в три длинее и мутная нотация, мне например, было крайне сложно понять, что к чему

I>>AST нужен не просто так, а для конкретных вещей. Т.е. ты вводишь узел не там, где тебе надо кусочек грамматики описать, а там где тебе нужен этот узел


_>Можно и так. А можно и сразу.


Это экономия на спичках. Никакого профита это не

I>>Нет, разумеется. Какой смысл делать для символов?


_>Тогда я всё же не понял пока, тебе выдаётся дерево или что? Если дерево, то почему не целиком?


Дизайн в библиотеке я реализовал как мне было удобнее. В конечном итоге парсер может возвратить дерево, если его комбинаторы смапить на AST

I>>Я не знаю, что такое ADC


_>АЦП в смысле.


аналого-цифровой преобразователь ?

I>>Тем хуже для тебя. Если не помогли ни примерЫ, ни ссылки на работы, то напрашивается один вариант — тебе нравится только императивный код и ничего другого ты видеть не хочешь.


_>Что-то ты совсем не понял меня. Ну я сейчас накидаю примерчик, так что поймёшь)


Да-да, работай, а то кроме нерабочего Analyse от тебя было около одного нормального примера.
Re[64]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 11.01.14 08:57
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Хы, не, просто у меня есть привычка не заявлять непроверенный код. А проверять лень было, поэтому я про короутины и не упоминал. Но как видишь, народ меня всё же "добил" своими рассказами о великой сложности задачи реактивного парсинга, так что я ненадолго отбросил лень и набросал код. )))


Тебе про сложность никто ничего не говорил. Говорили про пользу и я просил пример для сравнения.
Re[38]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 11.01.14 09:09
Оценка: 6 (1)
Здравствуйте, alex_public, Вы писали:

_>Всё нормально там будет, строка накапливается в js. Т.е. если startSync и endSync приходят хоть по одному символу (но Analyze всё же вызывается построчно, т.е. в каждой строке по кусочку от startSync/endSync), то никаких проблем. Вот если весь Analyze вызывается для каждого символа (т.е. не по строкам, по которым там фильтрация осуществляется), то тогда действительно надо переделать.


Надо переделывать, это ж очевидно, и я на это указываю уже хрен знает сколько раз.

S>>В этом-то и сложность конверсии активного кода в реактивный — там, где активный код пишет "вынь да полож мне следующие 8 символов" (и встаёт в ожидании завершения IO, если у него исчерпался буфер), реактивный код должен уметь вернуть управление сразу же, как только отпроцессил входные данные.


_>О да, дико сложно. ))) http://www.rsdn.ru/forum/philosophy/5424925
Автор: alex_public
Дата: 11.01.14


При чем здесь сложность ? Ты раз за разом выдавал неправильное императивное решение и настаивал что оно работает.

Если ты таки решил прикрутить короутины, то всё в порядке. Правда теперь не ясно, почему ты сопротивлялся столько дней.

Я ожидал что ты сразу переделаешь analyse на короутины, но мне уже надоело. Тебе теперь должно быть понятно, как императивно делается реактивный парсинг.

S>>Поэтому, например, корректных реактивных фильтров контента в ASP.NET приложениях в природе не встречается. Весь Analyze сводится к накапливанию аргументов в буфере, а сам анализ происходит по завершению.


_>Ну это проблемы исключительно ASP.NET. Как видно, достаточно универсальное решение делается на C++ всего в пару десятков строчек. )))


Ну сколько можно — еще одна попытка контекстно-свободный язык парсить регэкспом

Любой реактивный парсинг сожрёт ресурсы и выдаст фильтрованый результат только по окончании. И это не важно, с++ или асп.нет или yesod(хаскель).

Итого — не считая твоих попыток свести контекстно-свободную грамматику к регулярной принципиальной разницы не вижу.
Re[63]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 11.01.14 09:12
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>Вообще, stackful coroutines можно использовать для упрощения использования многих монад, например optional<T>/expected<T>/future<T>/generator<T>(которая в свою очередь эмулирует корутины)/etc. Буквально недавно это обсуждалось в C++ ISO Proposals.

EP>Но такая техника применима не ко всем монадам. Например это неприменимо к монаде list<T>, потому что одно и то же продолжение может вызываться несколько раз, а для stackful coroutine такой фокус не прокатит (стэк изменяется, объекты деструктятся и т.п.). Грубо говоря нужен полноценный call/cc.
EP>Я думаю для stackless coroutines таких ограничений нет — объекты-автоматы можно копировать и вызывать несколько раз для одного checkpoint'а.

А я помню, как ты рассказывал что stackfull круче чем яйца, а оказыватся это совершенно разные механизмы и области применения у них всего лишь пересекаются
Re[62]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 11.01.14 09:16
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Теперь попробуем заставить Спирит работать реактивно. Для этого я написал (пара десятков строчек) некий класс rstring. Имея его, мы можем написать так:

_>
_>rstring rs;
rs>>>[&](){
_>    int sum=0, count=0;
_>    parse(rs.cbegin(), rs.cend(), int_[([&](const int& n){cout<<n<<'\t'<<double(sum+=n)/++count<<endl;})]%',');
_>};
_>for(auto& s: {"-3", "3", "3,-22,-1", ",0,1,22,333,"}) rs<<s;//заталкиваем реактивно куски строк в парсер
_>

_>Как видно, код самого парсера вообще не изменился. И естественно этот код выдаёт такой же результат как и первый вариант.

_>Ну что, покажешь аналоги этих примеров на базе тех монадных библиотечек? ) И тогда можем ещё и быстродействие сравнить (я поправлю примеры чтобы брали данные из файла и пришлю готовые бинарники), если рискнёшь конечно. )))


"Те" монандные библиотеки именно так и сделаны — через короутины. в js правда приходится туго, короутины толко в следующем стандарте, а сейчас эмуляция оных.

Что касается сравнения производительности, то снова выходит сравнение нативного компилера с джытом. Это не интересно, для этого незачем городить парсеры.
Re[64]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Evgeny.Panasyuk Россия  
Дата: 11.01.14 10:51
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>А я помню, как ты рассказывал что stackfull круче чем яйца,


Так ведь действительно мощный механизм И кстати — корутины могут мигрировать из потока в поток (был когда-то вопрос на эту тему).

I>а оказыватся это совершенно разные механизмы и области применения у них всего лишь пересекаются


По сравнению с чем? С монадами? Ну да — но мы их и не сравнивали.
Если же ты про C# await — насколько я вижу, он тут ничем не поможет. У генерированных автоматов ведь нет value semantics?
Re[64]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Evgeny.Panasyuk Россия  
Дата: 11.01.14 12:30
Оценка:
Здравствуйте, alex_public, Вы писали:

EP>>Я думал вы договорились Boost.Coroutine не использовать, поэтому и не упоминал

EP>>А так да — на корутинах можно легко приделать реактивный парсинг к Boost.Spirit.
_>Хы, не, просто у меня есть привычка не заявлять непроверенный код. А проверять лень было, поэтому я про короутины и не упоминал. Но как видишь, народ меня всё же "добил" своими рассказами о великой сложности задачи реактивного парсинга, так что я ненадолго отбросил лень и набросал код. )))

А, тогда понятно

_>О, это отдельная интересная тема для обсуждения... Вообще C++ в интересном направление стал сейчас развиваеться.

_>Правда она несколько противоположна тому моему примеру. Я же в нём как бы наоборот использую короутины, чтобы реализовать реактивный парсинг без всяких явных монад.

Это было неофициальное обсуждение. Я думаю вряд ли в C++ добавят сахар для монад (возможно будет мощный препроцессор, на котором этот сахар легко реализуется (и не только он)).

EP>>Я думаю для stackless coroutines таких ограничений нет — объекты-автоматы можно копировать и вызывать несколько раз для одного checkpoint'а.

_>Только их ещё конструировать надо самому. )

Я в общем про stackless. А конструировать их можно разными способами: вручную, макросами, внешним генератором и т.п.

EP>>В новой версии Boost.Coroutine есть интерфейс input/output итераторов. По идее должно быть достаточно boost::coroutines::coroutine<char>::pull_type::iterator + boost::spirit::make_default_multi_pass.


_>О, значит в новой версии может получится вообще автоматом? ) Позитивно.


Да, вот так:
int main()
{    
    typedef coroutine<char> Coro;
    Coro::push_type coro([](Coro::pull_type &coro)
    {
        parse
        (
            make_default_multi_pass(begin(coro)),
            make_default_multi_pass(end(coro)),
            int_[phoenix::ref(cout) << _1 << endl] % ','
        );
    });
    copy("1,2,3,4,5", begin(coro));
}


_>Но в любом случае даже свой код очень простой и короткий вышел (я использовал ещё boost::iterator_facade).


Тоже использую iterator_facade — очень удобно.
Re[62]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.14 19:01
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Теперь попробуем заставить Спирит работать реактивно. Для этого я написал (пара десятков строчек) некий класс rstring.

А можно показать исходник этого "некоего класса rstring"?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[46]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.14 19:12
Оценка:
Здравствуйте, alex_public, Вы писали:
_>Да, такое можно сделать, но тогда опять же непонятно зачем нам именно такие данные. Они же будут приходить в очень странной последовательности, по отношению к оригинальной структуре. Например для <a></a><b><c><c/></b> придёт как a, c, b. И зачем нам оно такое?
Нам нужны не "именно такие" данные, а возможность заставить XPath Expression работать по неполным данным, а также не держать в памяти весь буфер.
Один пример — выражение типа //c[@value>1] будет мне возвращать нужные мне теги по мере поступления, а не после /b. Что может быть крайне ценным при, скажем, обработке XSLT.
Другой пример — если я считаю некое выражение, скажем sum(//c[@class="red"]/value). Мне для этого подсчёта, вообще говоря, нахрен не упал весь документ одновременно. Отпарсили — прибавили — выкинули. Нужно понимать, что если я тяну документ по сети, и отдаю результат тоже в сеть, то большую часть времени мой "поток" спит. Когда я уже избавился от нативных потоков, и эта сплюшка не отъедает 1мб стека от адресного пространства моего процесса во время своего сна, то боттлнеком становятся вот такие "запоздало-реактивные" реализации. "Накапливаемый" документ отъедает непозволительно большую память на непозволительно большое время. В приведённом примере мне нужно, грубо говоря, хранить три строчки "состояния" парсера, а всё остальное выкидывать сразу после прочтения.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[42]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.14 19:28
Оценка:
Здравствуйте, alex_public, Вы писали:

_>И всё это в одной концепции. Монадой же из всего этого будет только вариант 6. А будет ещё просто применение функций, фукторы и т.д. и т.п.

Я, наверное, чего-то не понял. Монада задаёт правила комбинирования функций. Поэтому из "одной концепции" получается весь зоопарк, включая M<R>(M<T>) и всякие F(G()).
Вот, скажем, для Nullable<T> есть встроенные в язык C# правила для лифтинга операторов. А для пользовательских функций "правил лифтинга" нет. И нет никакой возможности описать "правила лифтинга" для своего типа Arbitrary<T> так, чтобы операторы и функции, определённые для T, автоматически конвертировались в операторы и функции, определённые для Arbitrary<T>. Нет средств выразить это в языке. И я никак не вижу способа добиться аналогичного результата в С++. Допустим, Петя определил тип optional<T> очевидным образом, предполагая использовать его для value-типов вроде int, double, и так далее.
Как мне сделать так, чтобы этот тип корректно работал со всеми, в том числе ещё не написанными, типами?
Вот Вася определил тип big_integer.
Как мне писать программу с использованием optional<big_integer>?
Для big_integer Вася определил множество операторов и функций.
Как Пете описать тип optional<T>, чтобы я, прикладной программист, не должен был писать каждый раз
optional<big_integer> e = a.has_value() ? exp(a.value()) : optional<big_integer>::null;
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.