Re[21]: Интерфейс vs. протокол.
От: Pavel Dvorkin Россия  
Дата: 18.04.11 12:00
Оценка:
Здравствуйте, WolfHound, Вы писали:

PD>>А что касается всяких маргинальных языков — может быть, там оно и будет, только надо себе отдавать отчет, что ни один маргинальный язык никогда не попадал в мейнстрим.

WH>Ведешь себя в точности по моему описанию. Хоть бы постеснялся.

Надоел.
With best regards
Pavel Dvorkin
Re[7]: Интерфейс vs. протокол.
От: jazzer Россия Skype: enerjazzer
Дата: 18.04.11 12:05
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, jazzer, Вы писали:


V>>>Дык, в твоем примере аналогично, из любого "состояния" можно сделать несколько попыток перехода. Понятное дело, что если компилятор явным образом uniqueness не поддерживает, то мы можем лишь эмулировать их с различной степенью приближенности.


J>>Нет, у меня будет ошибка компиляции.


V>Эх, невнимательность...


V>Покажи тут ошибку компиляции:

V>
V>auto s4 = f.go( s3, Close()            );
V>auto s5 = f.go( s3, Close()            );
V>


J>>При том что и у тебя, и у меня возвращаемое значение передается дальше правильно, у тебя — ошибка времени исполнения, а у меня — времени компиляции.


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

А то, что ты показываешь с s3 — это неправильная передача значения, в таком случае схема работать не будет. Но и на нее есть управа — можно передавать сразу всю цепочку действий, которые мы хотим совершить, и она будет проверена опять же на этапе компиляции (go_chain в моем примере). Там достаточно гарантировать, что самое начальное состояние правильное, а дальше все промежуточные в цепочки будут правильными автоматически.

V>Неверно.


V>>>Разве на С++ возможно заставить компилятор ругаться на вторую строчку, если первая компилируется в этом выхолощенном примере?

V>>>
V>>>A a1 = f(b);
V>>>A a2 = f(b);
V>>>

J>>В этом — нет, а в таком — можно:
J>>
J>>A a0;
J>>auto a1 = f(b, a0);
J>>auto a2 = f(b, a1);
J>>


V>А такой не решает исходную задачу, ибо не гарантирует протокол.

У меня — гарантирует, если передается действительно a0 и а1, а не что-то другое. А у тебя, даже если передается везде правильный file, все равно контроль только во время выполнения.

J>>Условие задачи было — предоставить статический контроль. Пусть криво и косо, но чтоб был. Где он у тебя? Нету, только рантайм.


V>Выше показал в чем суть. Мой пример a1=f(b) — это выхолощенный случай как твоего, та и моего варианта. Чуть присмотрись. В нем и есть слабость твоего и моего решения. Она, эта "слабость", идентична.


Да у тебя вообще статики нет, либо я слепой с утра.

J>>А рантайм у нас и сейчас есть в виде исключений и прочих проверок времени выполнения.


V>Э нет, в моем примере, как и в твоем, если удалось отладить "основную ветку", то компилятор ограничивает набор возможных "неосновных". Т.е. отладка здесь ровно идет того же плана, что ловля поданного ошибочного NULL. А от него С++ тоже не спасает, со всей своей типизированностью. И не только С++ тут бессилен.

Покажи, где компилятор ругнется в твоем примере. Я не вижу, сорри.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[8]: Интерфейс vs. протокол.
От: vdimas Россия  
Дата: 18.04.11 12:35
Оценка:
Здравствуйте, jazzer, Вы писали:


V>>Покажи тут ошибку компиляции:

V>>
V>>auto s4 = f.go( s3, Close()            );
V>>auto s5 = f.go( s3, Close()            );
V>>


J>>>При том что и у тебя, и у меня возвращаемое значение передается дальше правильно, у тебя — ошибка времени исполнения, а у меня — времени компиляции.


J>Смотри, я тут не просто так выделенные слова написал. Если всё передается правильно и у тебя, и у меня, то у меня будет ошибка компиляции, а у тебя — нет. По крайней мере, я ее тут не вижу, покажи, если она тут есть.


Ты так и не показал ошибку компиляции в приведенном мною фрагменте, а в нем суть. Происходит следующее — мы переиспользуем некую переменную s3, несмотря на то, что она уже содержит ссылку на невалидное состояние. Именно в отсутствии ср-в контроля за моментом, когда переменная становится невалидной, мы можем лишь приблизительно воспроизводить решение, но не точно.

J>А то, что ты показываешь с s3 — это неправильная передача значения, в таком случае схема работать не будет.


Она не будет работать в рантайм. Но компилятор же об этом не скажет.

J>Но и на нее есть управа — можно передавать сразу всю цепочку действий, которые мы хотим совершить, и она будет проверена опять же на этапе компиляции (go_chain в моем примере). Там достаточно гарантировать, что самое начальное состояние правильное, а дальше все промежуточные в цепочки будут правильными автоматически.


Именно, нужна некая монада, которая результат предыдущей ф-ии автоматически подаст как аргумент следующей. Тогда (при условии отсутствия ошибок внутри самих ф-ий) еще хоть как-то можно замутить некую "безопасность". Хаскель в руки, как говорится.


V>>А такой не решает исходную задачу, ибо не гарантирует протокол.

J>У меня — гарантирует, если передается действительно a0 и а1, а не что-то другое. А у тебя, даже если передается везде правильный file, все равно контроль только во время выполнения.

Да нет, просто ты забил болт на конструкторы копирования и деструкторы. Т.е. при выходе из диапазона, если явно не закрыть файл, то он повиснет в воздухе. ОК, замени в моем примере на shared_ptr или другой случай подсчета ссылок и будет тебе щастье. ИМХО, передача владения всяко дешевле выходит, хотя теряем немного в автоматизме. И для данного примера выбранный способ детерминированного разрушения — не суть.

V>>Выше показал в чем суть. Мой пример a1=f(b) — это выхолощенный случай как твоего, та и моего варианта. Чуть присмотрись. В нем и есть слабость твоего и моего решения. Она, эта "слабость", идентична.



J>Да у тебя вообще статики нет, либо я слепой с утра.


Статика одинакова в обоих примерах и заключается в том, что каждое состояние — это отдельный тип, для которого определены некие операции. Просто я опустил состояние Initial и Closed, которые избыточны для этого примера, и оставил только состояние file. Вернув твою избыточность получим:
InitialPtr initial;
OpenedPtr file = openFile(initial, "some-path");
file = read(file, &buffer, count);
file = read(file, &buffer2, count2);
ClosedPtr closed = close(file);


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

J>Покажи, где компилятор ругнется в твоем примере. Я не вижу, сорри.


Компилятор ругнется, если в read() мы подадим аргумент не того типа. Например: read(initial, ...). Собсно, как и у тебя. Если бы ты не свел свой пример к одной сигнатуре, макросам и явно выделенному автомату, я бы не встревал. Это все лишнее для демонстрации происходящего.
Re[22]: Интерфейс vs. протокол.
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.04.11 14:27
Оценка:
Здравствуйте, adontz, Вы писали:

A>http://www.rsdn.ru/article/singularity/singularity.xml
Автор(ы): Galen Hunt, James Larus, Martin Abadi, Mark Aiken, Paul Barham, Manuel Fahndrich, Chris Hawblitzel, Orion Hodson, Steven Levi, Nick Murphy, Bjarne Steensgaard, David Tarditi, Ted Wobber, Brian Zill
Дата: 02.03.2006
Singularity – исследовательский проект Microsoft Research, который начался с вопроса: на что была бы похожа программная платформа, если спроектировать ее на пустом месте, и во главу угла поставить не производительность, а надежность?


A>

Singularity выдала 91 операцию в секунду при взвешенной средней пропускной способности в 362 Kбит/с. Web-сервер IIS, выполняемый под управлением Windows 2003 на идентичной аппаратуре, выдает 761 операцию в секунду при взвешенной средней пропускной способности в 336 Kбит/с.


A>

Сетевой стек Singularity, наоборот, не является узким местом, и может поддерживать пропускную способность в 48Mбит/сек.


A>Статья старая, но даже по тогдашним меркам производительность просто нелепая. В обсуждении (не очень большом) это обсосано.


И что нелепого ты тут усмотрел? Ну, одна какая-то фича не отлажена. Пропускная способность в килобитах одинаковая, кстати.

Если поглядеть на табличку сверху, то как раз видно, что как ОС Сингулярити даже по шустрее Винды.
http://www.rsdn.ru/article/singularity/singularity.xml#EIIAE
Автор(ы): Galen Hunt, James Larus, Martin Abadi, Mark Aiken, Paul Barham, Manuel Fahndrich, Chris Hawblitzel, Orion Hodson, Steven Levi, Nick Murphy, Bjarne Steensgaard, David Tarditi, Ted Wobber, Brian Zill
Дата: 02.03.2006
Singularity – исследовательский проект Microsoft Research, который начался с вопроса: на что была бы похожа программная платформа, если спроектировать ее на пустом месте, и во главу угла поставить не производительность, а надежность?

Singularity – это новая система, и ее производительность пока не отлажена до конца. Основные операции с потоками в Singularity, такие, как передача процессорного времени (yielding processor) или синхронизация двух потоков, сравнимы или несколько быстрее, чем на других системах. Однако, благодаря SIP-архитектуре Singularity, межпроцессные операции выполняются значительно быстрее, чем в других системах. Вызовы ядра из процесса в Singularity в 5-10 раз быстрее, поскольку вызов не пересекает границ аппаратной защиты. Простое RPC-подобное взаимодействие двух процессов в 4-9 раз быстрее. А создание процесса в 2-18 раз быстрее, чем в других системах. Это превосходство должно еще больше вырасти, когда мы улучшим реализацию потоков в Singularity.


И это на совсем новой, не отлаженной (в то время) системе. Думаю, что сейчас уже она сильно стабильнее и шустрее.

Так что ты Ром опять гонишь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Интерфейс vs. протокол.
От: jazzer Россия Skype: enerjazzer
Дата: 18.04.11 17:20
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Ты так и не показал ошибку компиляции в приведенном мною фрагменте, а в нем суть.

Естественно, не показал, потому что я как раз хотел показать, что ее нет, а 0x7be просит, чтоб она была!

V>Происходит следующее — мы переиспользуем некую переменную s3, несмотря на то, что она уже содержит ссылку на невалидное состояние. Именно в отсутствии ср-в контроля за моментом, когда переменная становится невалидной, мы можем лишь приблизительно воспроизводить решение, но не точно.


Да я отлично понимаю, что происходит, но это не решение той задачи, которую предложил 0x7be.

J>>А то, что ты показываешь с s3 — это неправильная передача значения, в таком случае схема работать не будет.

V>Она не будет работать в рантайм. Но компилятор же об этом не скажет.
Да, не скажет. Но даже когда правильная передача, у тебя рантайм, а у меня статика.

J>>Но и на нее есть управа — можно передавать сразу всю цепочку действий, которые мы хотим совершить, и она будет проверена опять же на этапе компиляции (go_chain в моем примере). Там достаточно гарантировать, что самое начальное состояние правильное, а дальше все промежуточные в цепочки будут правильными автоматически.


V>Именно, нужна некая монада, которая результат предыдущей ф-ии автоматически подаст как аргумент следующей. Тогда (при условии отсутствия ошибок внутри самих ф-ий) еще хоть как-то можно замутить некую "безопасность". Хаскель в руки, как говорится.


Ну вот у меня С++ ничего так, цепочки вызовов проверяет
С Хаскелем, конечно, было бы проще, а еще проще — с какой-нть Агдой2.

V>Да нет, просто ты забил болт на конструкторы копирования и деструкторы. Т.е. при выходе из диапазона, если явно не закрыть файл, то он повиснет в воздухе. ОК, замени в моем примере на shared_ptr или другой случай подсчета ссылок и будет тебе щастье. ИМХО, передача владения всяко дешевле выходит, хотя теряем немного в автоматизме. И для данного примера выбранный способ детерминированного разрушения — не суть.


Ага, тем более что у меня автоматические объекты везде и нулевой оверхед в рантайме. Куда уж дешевле

Причем тут конструкторы и деструкторы? 0x7be ясно описал задачу — методы могут вызываться в определенном порядке, и точка. Это — описание конечного автомата с его разрешенными переходами между состояниями. И все это происходит между конструкторами и деструкторами, они за скобками.

V>Статика одинакова в обоих примерах и заключается в том, что каждое состояние — это отдельный тип, для которого определены некие операции. Просто я опустил состояние Initial и Closed, которые избыточны для этого примера, и оставил только состояние file. Вернув твою избыточность получим:

V>
V>InitialPtr initial;
V>OpenedPtr file = openFile(initial, "some-path");
V>file = read(file, &buffer, count);
V>file = read(file, &buffer2, count2);
V>ClosedPtr closed = close(file);
V>


V>Заметь, мой пример лучше передает смысл происходящего, т.к. не ограничивает сигнатуру операций.

Это где это у меня ограничены сигнатуры? У меня сигнатура — это все содержимое сигнала, там сколько угодно параметров может быть. Например, Close вообще без параметров. А так — то же, что у меня, получается, так что не очень понятно, с чем ты споришь.

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

Да, на этом все построено и у меня, и у тебя. Причем тут уникальные ссылки, о которых ты так долго говорил — не понимаю.

J>>Покажи, где компилятор ругнется в твоем примере. Я не вижу, сорри.


V>Компилятор ругнется, если в read() мы подадим аргумент не того типа. Например: read(initial, ...). Собсно, как и у тебя. Если бы ты не свел свой пример к одной сигнатуре, макросам и явно выделенному автомату, я бы не встревал. Это все лишнее для демонстрации происходящего.


Теперь я наконец понял, о чем ты. Ты так налегал на уникальность ссылки, что я решил, что у тебя через нее все и делается (естественно, только в рантайме). А теперь, когда ты показал все целиком, я вижу, что у тебя ровно то же самое, что и у меня, получается. С той лишь разницей, что я могу объявить цепочку действий и через go_chain проверить ее сразу же компилятором, а ты нет (так как каждый метод у меня — это отдельный тип, а у тебя это просто функции, сигнатуры которых могут совпадать и давать одинаковый тип). Цепочки вообще гораздо безопаснее, так как гарантируют не только правильность порядка вызовов, но и то, что цепочка применяется к одному и тому же объекту, исключая целый класс копи-пейстных ошибок типа
V>file1 = read(file1, &buffer, count);
V>file1 = read(file2, &buffer2, count2); // ой, file2 скопировали из другого места и не заметили
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[10]: Интерфейс vs. протокол.
От: vdimas Россия  
Дата: 18.04.11 20:40
Оценка:
Здравствуйте, jazzer, Вы писали:

V>>Ты так и не показал ошибку компиляции в приведенном мною фрагменте, а в нем суть.

J>Естественно, не показал, потому что я как раз хотел показать, что ее нет, а 0x7be просит, чтоб она была!

Именно, на пару постов вверх и в выолощенном примере я показал, где засада. Эта засада одинакова и не контроллируется компилятором.

V>>Происходит следующее — мы переиспользуем некую переменную s3, несмотря на то, что она уже содержит ссылку на невалидное состояние. Именно в отсутствии ср-в контроля за моментом, когда переменная становится невалидной, мы можем лишь приблизительно воспроизводить решение, но не точно.


J>Да я отлично понимаю, что происходит, но это не решение той задачи, которую предложил 0x7be.


Ес-но, эту задачу в рамках C++ не решить. Мне просто непонятно твое упорство в том плане, что мое решение по-сути отличается от твоего. Оно не может отличаться, мы используем одинаковый механизм.


J>>>А то, что ты показываешь с s3 — это неправильная передача значения, в таком случае схема работать не будет.

V>>Она не будет работать в рантайм. Но компилятор же об этом не скажет.
J>Да, не скажет. Но даже когда правильная передача, у тебя рантайм, а у меня статика.

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


J>Ну вот у меня С++ ничего так, цепочки вызовов проверяет

J>С Хаскелем, конечно, было бы проще, а еще проще — с какой-нть Агдой2.

Просто нужен синтаксис и поддержка компилятора для такого фокуса. В Хаскеле это есть.


J>Ага, тем более что у меня автоматические объекты везде и нулевой оверхед в рантайме. Куда уж дешевле


Ты хотел сказать стековые? Для случая файла на порядок дешевле создать в куче некий "shared object", чем делать DuplicateHandle/CloseHandle в каждом конструкторе копирования и деструкторе состояния Opened.

J>Причем тут конструкторы и деструкторы? 0x7be ясно описал задачу — методы могут вызываться в определенном порядке, и точка. Это — описание конечного автомата с его разрешенными переходами между состояниями. И все это происходит между конструкторами и деструкторами, они за скобками.


Дык, он же не дал язык. Если берем С++, то нужны ср-ва для контроля ресурсов. Если бы за ресурсами в С++ следить не надо было, 90% кода можно было написать иначе.


J>Это где это у меня ограничены сигнатуры? У меня сигнатура — это все содержимое сигнала, там сколько угодно параметров может быть. Например, Close вообще без параметров. А так — то же, что у меня, получается, так что не очень понятно, с чем ты споришь.


Я выкинул лишнее, чтобы показать суть. Содержимое сигнала — это не сигнатура, это притянутые за уши ограничения выбранной "автоматной" схемы. Любая сигнатура — это произвольная ф-ия, имеющая как минимум одним аргументом наше типизированное состояние. А проивольный код ты туда в макрос не воткнешь. Остроумно было использовать operator<<, потому как оно корректно будет проглочено компилятором. Но что-то посложнее — увы. Я же говорю — это всё лишее, достаточно каждое состояние представить в виде уникального типа, остальное получается само.

J>Да, на этом все построено и у меня, и у тебя. Причем тут уникальные ссылки, о которых ты так долго говорил — не понимаю.


Для того, чтобы твоё s3 нельзя было переиспользовать после Close(). Да, тоже притянутость за уши, согласен, но тут иначе никак. У тебя сей момент вообще не контролируется, т.е. в случае ошибки при вызове методов для закрытого файла диагностировать это в общем случае будет труднее. А у меня задуман как бы специальный smart-pointer, который выплюнет ошибку вроде "нарушение протокола".

J>Теперь я наконец понял, о чем ты. Ты так налегал на уникальность ссылки, что я решил, что у тебя через нее все и делается (естественно, только в рантайме).


Уникальность, как уже сказал — это единственный способ гарантировать протокол. Ввиду того, что уникальность в С++ не подерживается, был предожен этот костыль.

J>А теперь, когда ты показал все целиком, я вижу, что у тебя ровно то же самое, что и у меня, получается. С той лишь разницей, что я могу объявить цепочку действий и через go_chain проверить ее сразу же компилятором, а ты нет (так как каждый метод у меня — это отдельный тип, а у тебя это просто функции, сигнатуры которых могут совпадать и давать одинаковый тип).


У тебя не метод, а сообщение суть отдельный тип. А это ограничение структуры. Фишка в том, что если "сигнатуры совпадают", как ты говоришь, то контракт и не нарушится, т.е. не о чем беспокоится. А приписать внешний go_chain — дело техники и тысячи вариантов, с той разницей, что ты замыкание аргументов явно прописал в виде сообщений, но можно сделать автоматически, даже в текущем стандарте через boost::bind.


J>Цепочки вообще гораздо безопаснее, так как гарантируют не только правильность порядка вызовов, но и то, что цепочка применяется к одному и тому же объекту, исключая целый класс копи-пейстных ошибок типа


Я с этим и не спорю. Более того, повторю, статически типизированный язык на мой взгляд должен требовать, чтобы результат вызова ф-ии,отличный от void, куда-то девался. Тогда у нас вся программа будет представлять из себя эти "цепочки", пусть даже через промежуточные переменные. А если еще добавить константность на эти значения, будет совсем красиво и надежно.
Re[32]: Интерфейс vs. протокол.
От: VoidEx  
Дата: 19.04.11 06:18
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, VoidEx, Вы писали:


VE>>Ну, для любого вещества точку кипения ты и в рантайме не вычислишь,


PD>Увы, да. Но тут причины химические, а не математико-влгоритмические.


Именно. Причины бесполезности зависимых типов в твоём надуманном примере химические, а не математически-алгоритмические. О чём тебе и говорят.
Re[11]: Интерфейс vs. протокол.
От: jazzer Россия Skype: enerjazzer
Дата: 19.04.11 06:19
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Ес-но, эту задачу в рамках C++ не решить. Мне просто непонятно твое упорство в том плане, что мое решение по-сути отличается от твоего. Оно не может отличаться, мы используем одинаковый механизм.


Где упорство, я же в конце написал, что идеи решения идентичны, разница только в деталях

V>Повторю, мое решение идентично твоему, только оно не завернуто в "автоматную" оболочку. Эта оболочка лишняя, не добавляет ни йоты полезного функционала. Я не говорю, что сам автоматный подход не нужен (сам охотно пользую), речь о конкретной задаче.


Она не завернута явно, но твои InitialPtr, OpenPtr и ClosedPtr — это же состояния КА, так что хоть горшком назови

V>Просто нужен синтаксис и поддержка компилятора для такого фокуса. В Хаскеле это есть.

Да.

J>>Ага, тем более что у меня автоматические объекты везде и нулевой оверхед в рантайме. Куда уж дешевле

V>Ты хотел сказать стековые?
Не обязательно, они могут быть членами классов, например. Automatic storage duration, короче.

V>Для случая файла на порядок дешевле создать в куче некий "shared object", чем делать DuplicateHandle/CloseHandle в каждом конструкторе копирования и деструкторе состояния Opened.

А у меня этого и нету, это у тебя file передается, по-разному обернутый, а у меня передается его состояние, которое с тем, кто и как владеет файлом, никак не связаны. А у тебя смешано владение и состояние.

J>>Причем тут конструкторы и деструкторы? 0x7be ясно описал задачу — методы могут вызываться в определенном порядке, и точка. Это — описание конечного автомата с его разрешенными переходами между состояниями. И все это происходит между конструкторами и деструкторами, они за скобками.


V>Дык, он же не дал язык. Если берем С++, то нужны ср-ва для контроля ресурсов. Если бы за ресурсами в С++ следить не надо было, 90% кода можно было написать иначе.

Ну я-то на С++ пишу на работе, так что мне интересен именно он
А контроль ресурсов мне тут не нужен, не понимаю, почему ты так на него напираешь.

J>>Это где это у меня ограничены сигнатуры? У меня сигнатура — это все содержимое сигнала, там сколько угодно параметров может быть. Например, Close вообще без параметров. А так — то же, что у меня, получается, так что не очень понятно, с чем ты споришь.


V>Я выкинул лишнее, чтобы показать суть. Содержимое сигнала — это не сигнатура, это притянутые за уши ограничения выбранной "автоматной" схемы. Любая сигнатура — это произвольная ф-ия, имеющая как минимум одним аргументом наше типизированное состояние.

Чем тебя не устраивает вызов f.go( s, Read{data_to_read} )? Что ты там хотел, буфер передавать с размером? Тогда это будет выглядеть так: f.go( s, Read{&buffer, size} ).

V>А проивольный код ты туда в макрос не воткнешь. Остроумно было использовать operator<<, потому как оно корректно будет проглочено компилятором. Но что-то посложнее — увы.

Еще как воткну, ты думаешь, я только на operator<< тестировал? Ты просто не знаешь силы variadic macros. Вообще говоря, единственное, что может сломать макрос — это запятая, которая неизбежно увеличивает количество параметров. Отсюда весь гемор. С появлением variadic macros этой проблемы больше нет.

V>Я же говорю — это всё лишее, достаточно каждое состояние представить в виде уникального типа, остальное получается само.

У меня оно и представлено.

J>>Да, на этом все построено и у меня, и у тебя. Причем тут уникальные ссылки, о которых ты так долго говорил — не понимаю.


V>Для того, чтобы твоё s3 нельзя было переиспользовать после Close(). Да, тоже притянутость за уши, согласен, но тут иначе никак. У тебя сей момент вообще не контролируется, т.е. в случае ошибки при вызове методов для закрытого файла диагностировать это в общем случае будет труднее. А у меня задуман как бы специальный smart-pointer, который выплюнет ошибку вроде "нарушение протокола".

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

J>>Теперь я наконец понял, о чем ты. Ты так налегал на уникальность ссылки, что я решил, что у тебя через нее все и делается (естественно, только в рантайме).


V>Уникальность, как уже сказал — это единственный способ гарантировать протокол. Ввиду того, что уникальность в С++ не подерживается, был предожен этот костыль.

Битва костылей

J>>А теперь, когда ты показал все целиком, я вижу, что у тебя ровно то же самое, что и у меня, получается. С той лишь разницей, что я могу объявить цепочку действий и через go_chain проверить ее сразу же компилятором, а ты нет (так как каждый метод у меня — это отдельный тип, а у тебя это просто функции, сигнатуры которых могут совпадать и давать одинаковый тип).


V>У тебя не метод, а сообщение суть отдельный тип. А это ограничение структуры. Фишка в том, что если "сигнатуры совпадают", как ты говоришь, то контракт и не нарушится, т.е. не о чем беспокоится.

см. выше. не вижу разницы.
V>А приписать внешний go_chain — дело техники и тысячи вариантов, с той разницей, что ты замыкание аргументов явно прописал в виде сообщений, но можно сделать автоматически, даже в текущем стандарте через boost::bind.
Ну вот припиши внешний go_chain в твоей схеме, чтоб была ошибка компиляции, и сравним.
В моей это делается тремя строчками, см. мое исходное сообщение. Как это сделать просто в твоей — я не вижу.

J>>Цепочки вообще гораздо безопаснее, так как гарантируют не только правильность порядка вызовов, но и то, что цепочка применяется к одному и тому же объекту, исключая целый класс копи-пейстных ошибок типа


V>Я с этим и не спорю. Более того, повторю, статически типизированный язык на мой взгляд должен требовать, чтобы результат вызова ф-ии,отличный от void, куда-то девался. Тогда у нас вся программа будет представлять из себя эти "цепочки", пусть даже через промежуточные переменные. А если еще добавить константность на эти значения, будет совсем красиво и надежно.

Ну, это можно сделать каким-нть внешним статическим анализатором или плагином к компилятору, благо GCC позволяет плагины подключать к нему, начиная с версии 4.5. Только это не поможет. Ну денется результат куда-то, как ты застрахуешь программера от того, что он потом не перепутает s1 и s2, которые ты заставил его создать?

ЗЫ Прикинь, придется же писать
std::ostream& i_hate_this_return_policy = std::cout << "Oh no!";

jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[33]: Интерфейс vs. протокол.
От: Pavel Dvorkin Россия  
Дата: 19.04.11 07:33
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Здравствуйте, VoidEx, Вы писали:


VE>>>Ну, для любого вещества точку кипения ты и в рантайме не вычислишь,


PD>>Увы, да. Но тут причины химические, а не математико-влгоритмические.


VE>Именно. Причины бесполезности зависимых типов в твоём надуманном примере химические, а не математически-алгоритмические. О чём тебе и говорят.


Нет. Говоря о химических причинах, я просто имел в виду, что в химии нет методов, позволяющих рассчитывать эти значения с хорошей точностью. Это химический факт, не имеющий к теме дискуссии отношения. Предположим, что такой метод создан, что тогда ? Бесполезность типов вдруг исчезнет и появится полезность ? Из-за того, что кто-то разработал метод расчета, не имеющий отношения к информатике ? Сами-то величины вполне определены, и очень даже неплохо.
Кстати, вполне могу предложить пример, когда расчет вполне возможен. Например, расчет энтальпии образования с хорошей точностью для ряда органических веществ вполне возможен. Но какое это отношение к программированию имеет ?
With best regards
Pavel Dvorkin
Re[34]: Интерфейс vs. протокол.
От: VoidEx  
Дата: 19.04.11 08:59
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, VoidEx, Вы писали:


VE>>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>>Здравствуйте, VoidEx, Вы писали:


VE>>>>Ну, для любого вещества точку кипения ты и в рантайме не вычислишь,


PD>>>Увы, да. Но тут причины химические, а не математико-влгоритмические.


VE>>Именно. Причины бесполезности зависимых типов в твоём надуманном примере химические, а не математически-алгоритмические. О чём тебе и говорят.


PD>Нет. Говоря о химических причинах, я просто имел в виду, что в химии нет методов, позволяющих рассчитывать эти значения с хорошей точностью. Это химический факт, не имеющий к теме дискуссии отношения. Предположим, что такой метод создан, что тогда ?

Тогда мы сможем вычислить в процессе компиляции и возвращать в функции float[computelow..computehigh]
Re[35]: Интерфейс vs. протокол.
От: Pavel Dvorkin Россия  
Дата: 19.04.11 09:13
Оценка:
Здравствуйте, VoidEx, Вы писали:

PD>>Нет. Говоря о химических причинах, я просто имел в виду, что в химии нет методов, позволяющих рассчитывать эти значения с хорошей точностью. Это химический факт, не имеющий к теме дискуссии отношения. Предположим, что такой метод создан, что тогда ?

VE>Тогда мы сможем вычислить в процессе компиляции и возвращать в функции float[computelow..computehigh]

А если эти low и high были оценены неверно ? Их оценить для произвольного вещества, допустим, нельзя, так как метод расчета зависит от каких-то параметров, которые берутся из эксперимента, а он для этих веществ еще не проводился (ситуация вполне реальная : метод расчета есть, данных для него для некоего вещества пока нет)

Я вообще не понимаю, что должно быть в этом случае. Ты же предлагаешь статический анализ, то есть во время компиляции. А мне исходники, естественно, не дашь, если это коммерческая программа ? И вот я ей даю на вход вещество, для которого должно получится <low или > high. И что ?
With best regards
Pavel Dvorkin
Re[36]: Интерфейс vs. протокол.
От: VoidEx  
Дата: 19.04.11 09:23
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, VoidEx, Вы писали:


PD>>>Нет. Говоря о химических причинах, я просто имел в виду, что в химии нет методов, позволяющих рассчитывать эти значения с хорошей точностью. Это химический факт, не имеющий к теме дискуссии отношения. Предположим, что такой метод создан, что тогда ?

VE>>Тогда мы сможем вычислить в процессе компиляции и возвращать в функции float[computelow..computehigh]

PD>А если эти low и high были оценены неверно ? Их оценить для произвольного вещества, допустим, нельзя, так как метод расчета зависит от каких-то параметров, которые берутся из эксперимента, а он для этих веществ еще не проводился (ситуация вполне реальная : метод расчета есть, данных для него для некоего вещества пока нет)

low и high и так на этапе компиляции неизвестны, если ты об этом.

PD>Я вообще не понимаю, что должно быть в этом случае. Ты же предлагаешь статический анализ, то есть во время компиляции. А мне исходники, естественно, не дашь, если это коммерческая программа ? И вот я ей даю на вход вещество, для которого должно получится <low или > high. И что ?

Не понял вопроса.
Re[37]: Интерфейс vs. протокол.
От: Pavel Dvorkin Россия  
Дата: 19.04.11 09:34
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>low и high и так на этапе компиляции неизвестны, если ты об этом.


Тогда я не понимаю, как функция может вернуть ограниченный float[low..high]

PD>>Я вообще не понимаю, что должно быть в этом случае. Ты же предлагаешь статический анализ, то есть во время компиляции. А мне исходники, естественно, не дашь, если это коммерческая программа ? И вот я ей даю на вход вещество, для которого должно получится <low или > high. И что ?

VE>Не понял вопроса.

Задача.

Есть метод расчета чего-то для неопределенного числа различных веществ .
Метод зависит от параметров.Параметры вводятся из файла. Для каждого вещества они свои.
Опиши, как будешь программу делать со статическим анализом.
With best regards
Pavel Dvorkin
Re[38]: Интерфейс vs. протокол.
От: VoidEx  
Дата: 19.04.11 09:51
Оценка: 1 (1)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, VoidEx, Вы писали:


VE>>low и high и так на этапе компиляции неизвестны, если ты об этом.


PD>Тогда я не понимаю, как функция может вернуть ограниченный float[low..high]


Тут 22 страницы со ссылками на зависимые типы.
Re[38]: Интерфейс vs. протокол.
От: WolfHound  
Дата: 19.04.11 09:56
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Тогда я не понимаю, как функция может вернуть ограниченный float[low..high]

Пятисотый раз повторяю: Читай про зависимые типы.

PD>Есть метод расчета чего-то для неопределенного числа различных веществ .

PD>Метод зависит от параметров.Параметры вводятся из файла. Для каждого вещества они свои.
Да плевать откуда они беруться.
Читай про зависимые типы.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[39]: Интерфейс vs. протокол.
От: Pavel Dvorkin Россия  
Дата: 19.04.11 09:59
Оценка:
Здравствуйте, VoidEx, Вы писали:

PD>>Тогда я не понимаю, как функция может вернуть ограниченный float[low..high]


VE>Тут 22 страницы со ссылками на зависимые типы.


Если можешь объяснить (на пальцах), как это должно компилироваться и работать (пример, который я привел) — объясни. Если нет — закончим дискуссию.
With best regards
Pavel Dvorkin
Re[39]: Интерфейс vs. протокол.
От: Pavel Dvorkin Россия  
Дата: 19.04.11 10:00
Оценка: :)
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Тогда я не понимаю, как функция может вернуть ограниченный float[low..high]

WH>Пятисотый раз повторяю: Читай про зависимые типы.

Второй (пока что) раз объясняю — надоел.
With best regards
Pavel Dvorkin
Re[40]: Интерфейс vs. протокол.
От: hardcase Пират http://nemerle.org
Дата: 19.04.11 10:03
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Если можешь объяснить (на пальцах), как это должно компилироваться и работать (пример, который я привел) — объясни. Если нет — закончим дискуссию.


А как вообще работает вывод типов в языках?
Или он тоже не работает в "условиях в реальных проектов"?
/* иЗвиНите зА неРовнЫй поЧерК */
Re[40]: Интерфейс vs. протокол.
От: VoidEx  
Дата: 19.04.11 10:12
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, VoidEx, Вы писали:


PD>>>Тогда я не понимаю, как функция может вернуть ограниченный float[low..high]


VE>>Тут 22 страницы со ссылками на зависимые типы.


PD>Если можешь объяснить (на пальцах), как это должно компилироваться и работать (пример, который я привел) — объясни. Если нет — закончим дискуссию.


Выберу третье: могу, но не буду. Я считаю, что самостоятельный человек должен уметь сам извлекать информацию. Если не может — он идиот, и не стоит на него тратить время. Если может, но не делает, — значит не хочет, и тоже не стоит тратить на него время. Вот если бы информация была недоступна или чересчур сложна, был бы другой разговор.
Re[12]: Интерфейс vs. протокол.
От: vdimas Россия  
Дата: 19.04.11 11:16
Оценка:
Здравствуйте, jazzer, Вы писали:

V>>Я с этим и не спорю. Более того, повторю, статически типизированный язык на мой взгляд должен требовать, чтобы результат вызова ф-ии,отличный от void, куда-то девался. Тогда у нас вся программа будет представлять из себя эти "цепочки", пусть даже через промежуточные переменные. А если еще добавить константность на эти значения, будет совсем красиво и надежно.

J>Ну, это можно сделать каким-нть внешним статическим анализатором или плагином к компилятору, благо GCC позволяет плагины подключать к нему, начиная с версии 4.5.

J>ЗЫ Прикинь, придется же писать

J>
J>std::ostream& i_hate_this_return_policy = std::cout << "Oh no!";
J>

J>

Вот еще
Минимум два варианта:
std::cout << "Yeah baby!" << std::endm; // some kind of "end message" manipulator


static_cast<void>(std::cout << "Yeah baby!");


В обоих случаях мы выражаем намерения явно. Есть еще вариант приведения в стиле С к (void), ИМХО такое приведение надо было пристрелить еще в прошлом стандарте С++ и не вспоминать о нем. А то оно имеет слишком свободное поведение: может работать как const_cast, static_cast, reinterpret_cast, как вызов конструктора, и, самое главное, не ищется полнотекстовым поиском по коду никак вообще. Гадость, одним словом.


J>Только это не поможет. Ну денется результат куда-то, как ты застрахуешь программера от того, что он потом не перепутает s1 и s2, которые ты заставил его создать?


Это верно и сейчас для всех случаев, где s1 и s2 одного типа. Логический вывод из этого — нужно плодить типы. Усугубить еще больше использованный нами подход. Вот абстрактный пример, где нужны два аргумента, принадлежащие одной и той же стадии протокола:
template<int Version>
class ProtocolData { 
private:
  ProtocolData(int value) {}

public:
  ProtocolData(const ProtocolData &) {}

  friend class Protocol;
};

class Protocol {
public:
  ProtocolData<1> Init(const std::string & host);
  
  template<int Version>
  ProtocolData<Version+1> next(ProtocolData<Version> data) {...}

  template<int Version>
  void exchange(ProtocolData<Version> a, ProtocolData<Version> b) {...}
};

...

Protocol protocol;

auto a = protocol.Init("host-a"); 
auto b = protocol.Init("host-b");

protocol.exchange(a, b); // OK

auto a1 = protocol.next(a);
auto b1 = protocol.next(b);

protocol.exchange(a1, b/*1*/); // Compilation error



==========
На остальное чуть позже отвечу.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.