Здравствуйте, WolfHound, Вы писали:
PD>>А что касается всяких маргинальных языков — может быть, там оно и будет, только надо себе отдавать отчет, что ни один маргинальный язык никогда не попадал в мейнстрим. WH>Ведешь себя в точности по моему описанию. Хоть бы постеснялся.
Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, jazzer, Вы писали:
V>>>Дык, в твоем примере аналогично, из любого "состояния" можно сделать несколько попыток перехода. Понятное дело, что если компилятор явным образом uniqueness не поддерживает, то мы можем лишь эмулировать их с различной степенью приближенности.
J>>Нет, у меня будет ошибка компиляции.
V>Эх, невнимательность...
V>Покажи тут ошибку компиляции: V>
J>>При том что и у тебя, и у меня возвращаемое значение передается дальше правильно, у тебя — ошибка времени исполнения, а у меня — времени компиляции.
Смотри, я тут не просто так выделенные слова написал. Если всё передается правильно и у тебя, и у меня, то у меня будет ошибка компиляции, а у тебя — нет. По крайней мере, я ее тут не вижу, покажи, если она тут есть.
А то, что ты показываешь с s3 — это неправильная передача значения, в таком случае схема работать не будет. Но и на нее есть управа — можно передавать сразу всю цепочку действий, которые мы хотим совершить, и она будет проверена опять же на этапе компиляции (go_chain в моем примере). Там достаточно гарантировать, что самое начальное состояние правильное, а дальше все промежуточные в цепочки будут правильными автоматически.
V>Неверно.
V>>>Разве на С++ возможно заставить компилятор ругаться на вторую строчку, если первая компилируется в этом выхолощенном примере? V>>>
V>А такой не решает исходную задачу, ибо не гарантирует протокол.
У меня — гарантирует, если передается действительно a0 и а1, а не что-то другое. А у тебя, даже если передается везде правильный file, все равно контроль только во время выполнения.
J>>Условие задачи было — предоставить статический контроль. Пусть криво и косо, но чтоб был. Где он у тебя? Нету, только рантайм.
V>Выше показал в чем суть. Мой пример a1=f(b) — это выхолощенный случай как твоего, та и моего варианта. Чуть присмотрись. В нем и есть слабость твоего и моего решения. Она, эта "слабость", идентична.
Да у тебя вообще статики нет, либо я слепой с утра.
J>>А рантайм у нас и сейчас есть в виде исключений и прочих проверок времени выполнения.
V>Э нет, в моем примере, как и в твоем, если удалось отладить "основную ветку", то компилятор ограничивает набор возможных "неосновных". Т.е. отладка здесь ровно идет того же плана, что ловля поданного ошибочного NULL. А от него С++ тоже не спасает, со всей своей типизированностью. И не только С++ тут бессилен.
Покажи, где компилятор ругнется в твоем примере. Я не вижу, сорри.
J>>>При том что и у тебя, и у меня возвращаемое значение передается дальше правильно, у тебя — ошибка времени исполнения, а у меня — времени компиляции.
J>Смотри, я тут не просто так выделенные слова написал. Если всё передается правильно и у тебя, и у меня, то у меня будет ошибка компиляции, а у тебя — нет. По крайней мере, я ее тут не вижу, покажи, если она тут есть.
Ты так и не показал ошибку компиляции в приведенном мною фрагменте, а в нем суть. Происходит следующее — мы переиспользуем некую переменную s3, несмотря на то, что она уже содержит ссылку на невалидное состояние. Именно в отсутствии ср-в контроля за моментом, когда переменная становится невалидной, мы можем лишь приблизительно воспроизводить решение, но не точно.
J>А то, что ты показываешь с s3 — это неправильная передача значения, в таком случае схема работать не будет.
Она не будет работать в рантайм. Но компилятор же об этом не скажет.
J>Но и на нее есть управа — можно передавать сразу всю цепочку действий, которые мы хотим совершить, и она будет проверена опять же на этапе компиляции (go_chain в моем примере). Там достаточно гарантировать, что самое начальное состояние правильное, а дальше все промежуточные в цепочки будут правильными автоматически.
Именно, нужна некая монада, которая результат предыдущей ф-ии автоматически подаст как аргумент следующей. Тогда (при условии отсутствия ошибок внутри самих ф-ий) еще хоть как-то можно замутить некую "безопасность". Хаскель в руки, как говорится.
V>>А такой не решает исходную задачу, ибо не гарантирует протокол. J>У меня — гарантирует, если передается действительно a0 и а1, а не что-то другое. А у тебя, даже если передается везде правильный file, все равно контроль только во время выполнения.
Да нет, просто ты забил болт на конструкторы копирования и деструкторы. Т.е. при выходе из диапазона, если явно не закрыть файл, то он повиснет в воздухе. ОК, замени в моем примере на shared_ptr или другой случай подсчета ссылок и будет тебе щастье. ИМХО, передача владения всяко дешевле выходит, хотя теряем немного в автоматизме. И для данного примера выбранный способ детерминированного разрушения — не суть.
V>>Выше показал в чем суть. Мой пример a1=f(b) — это выхолощенный случай как твоего, та и моего варианта. Чуть присмотрись. В нем и есть слабость твоего и моего решения. Она, эта "слабость", идентична.
J>Да у тебя вообще статики нет, либо я слепой с утра.
Статика одинакова в обоих примерах и заключается в том, что каждое состояние — это отдельный тип, для которого определены некие операции. Просто я опустил состояние Initial и Closed, которые избыточны для этого примера, и оставил только состояние file. Вернув твою избыточность получим:
Заметь, мой пример лучше передает смысл происходящего, т.к. не ограничивает сигнатуру операций. Повторюсь, в статически типизированном языке мы пытаемся решить эту задачу через назначение уникального типа каждому состоянию. Другим способом мы не можем заставить компилятор подключится к контролю операций вокруг конкретного состояния.
J>Покажи, где компилятор ругнется в твоем примере. Я не вижу, сорри.
Компилятор ругнется, если в read() мы подадим аргумент не того типа. Например: read(initial, ...). Собсно, как и у тебя. Если бы ты не свел свой пример к одной сигнатуре, макросам и явно выделенному автомату, я бы не встревал. Это все лишнее для демонстрации происходящего.
Singularity выдала 91 операцию в секунду при взвешенной средней пропускной способности в 362 Kбит/с. Web-сервер IIS, выполняемый под управлением Windows 2003 на идентичной аппаратуре, выдает 761 операцию в секунду при взвешенной средней пропускной способности в 336 Kбит/с.
A>
Сетевой стек Singularity, наоборот, не является узким местом, и может поддерживать пропускную способность в 48Mбит/сек.
A>Статья старая, но даже по тогдашним меркам производительность просто нелепая. В обсуждении (не очень большом) это обсосано.
И что нелепого ты тут усмотрел? Ну, одна какая-то фича не отлажена. Пропускная способность в килобитах одинаковая, кстати.
Singularity – это новая система, и ее производительность пока не отлажена до конца. Основные операции с потоками в Singularity, такие, как передача процессорного времени (yielding processor) или синхронизация двух потоков, сравнимы или несколько быстрее, чем на других системах. Однако, благодаря SIP-архитектуре Singularity, межпроцессные операции выполняются значительно быстрее, чем в других системах. Вызовы ядра из процесса в Singularity в 5-10 раз быстрее, поскольку вызов не пересекает границ аппаратной защиты. Простое RPC-подобное взаимодействие двух процессов в 4-9 раз быстрее. А создание процесса в 2-18 раз быстрее, чем в других системах. Это превосходство должно еще больше вырасти, когда мы улучшим реализацию потоков в Singularity.
И это на совсем новой, не отлаженной (в то время) системе. Думаю, что сейчас уже она сильно стабильнее и шустрее.
Так что ты Ром опять гонишь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, vdimas, Вы писали:
V>Ты так и не показал ошибку компиляции в приведенном мною фрагменте, а в нем суть.
Естественно, не показал, потому что я как раз хотел показать, что ее нет, а 0x7be просит, чтоб она была!
V>Происходит следующее — мы переиспользуем некую переменную s3, несмотря на то, что она уже содержит ссылку на невалидное состояние. Именно в отсутствии ср-в контроля за моментом, когда переменная становится невалидной, мы можем лишь приблизительно воспроизводить решение, но не точно.
Да я отлично понимаю, что происходит, но это не решение той задачи, которую предложил 0x7be.
J>>А то, что ты показываешь с s3 — это неправильная передача значения, в таком случае схема работать не будет. V>Она не будет работать в рантайм. Но компилятор же об этом не скажет.
Да, не скажет. Но даже когда правильная передача, у тебя рантайм, а у меня статика.
J>>Но и на нее есть управа — можно передавать сразу всю цепочку действий, которые мы хотим совершить, и она будет проверена опять же на этапе компиляции (go_chain в моем примере). Там достаточно гарантировать, что самое начальное состояние правильное, а дальше все промежуточные в цепочки будут правильными автоматически.
V>Именно, нужна некая монада, которая результат предыдущей ф-ии автоматически подаст как аргумент следующей. Тогда (при условии отсутствия ошибок внутри самих ф-ий) еще хоть как-то можно замутить некую "безопасность". Хаскель в руки, как говорится.
Ну вот у меня С++ ничего так, цепочки вызовов проверяет
С Хаскелем, конечно, было бы проще, а еще проще — с какой-нть Агдой2.
V>Да нет, просто ты забил болт на конструкторы копирования и деструкторы. Т.е. при выходе из диапазона, если явно не закрыть файл, то он повиснет в воздухе. ОК, замени в моем примере на shared_ptr или другой случай подсчета ссылок и будет тебе щастье. ИМХО, передача владения всяко дешевле выходит, хотя теряем немного в автоматизме. И для данного примера выбранный способ детерминированного разрушения — не суть.
Ага, тем более что у меня автоматические объекты везде и нулевой оверхед в рантайме. Куда уж дешевле
Причем тут конструкторы и деструкторы? 0x7be ясно описал задачу — методы могут вызываться в определенном порядке, и точка. Это — описание конечного автомата с его разрешенными переходами между состояниями. И все это происходит между конструкторами и деструкторами, они за скобками.
V>Статика одинакова в обоих примерах и заключается в том, что каждое состояние — это отдельный тип, для которого определены некие операции. Просто я опустил состояние Initial и Closed, которые избыточны для этого примера, и оставил только состояние 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, Вы писали:
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, куда-то девался. Тогда у нас вся программа будет представлять из себя эти "цепочки", пусть даже через промежуточные переменные. А если еще добавить константность на эти значения, будет совсем красиво и надежно.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, VoidEx, Вы писали:
VE>>Ну, для любого вещества точку кипения ты и в рантайме не вычислишь,
PD>Увы, да. Но тут причины химические, а не математико-влгоритмические.
Именно. Причины бесполезности зависимых типов в твоём надуманном примере химические, а не математически-алгоритмические. О чём тебе и говорят.
Здравствуйте, 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, которые ты заставил его создать?
Здравствуйте, VoidEx, Вы писали:
VE>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Здравствуйте, VoidEx, Вы писали:
VE>>>Ну, для любого вещества точку кипения ты и в рантайме не вычислишь,
PD>>Увы, да. Но тут причины химические, а не математико-влгоритмические.
VE>Именно. Причины бесполезности зависимых типов в твоём надуманном примере химические, а не математически-алгоритмические. О чём тебе и говорят.
Нет. Говоря о химических причинах, я просто имел в виду, что в химии нет методов, позволяющих рассчитывать эти значения с хорошей точностью. Это химический факт, не имеющий к теме дискуссии отношения. Предположим, что такой метод создан, что тогда ? Бесполезность типов вдруг исчезнет и появится полезность ? Из-за того, что кто-то разработал метод расчета, не имеющий отношения к информатике ? Сами-то величины вполне определены, и очень даже неплохо.
Кстати, вполне могу предложить пример, когда расчет вполне возможен. Например, расчет энтальпии образования с хорошей точностью для ряда органических веществ вполне возможен. Но какое это отношение к программированию имеет ?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, VoidEx, Вы писали:
VE>>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>Здравствуйте, VoidEx, Вы писали:
VE>>>>Ну, для любого вещества точку кипения ты и в рантайме не вычислишь,
PD>>>Увы, да. Но тут причины химические, а не математико-влгоритмические.
VE>>Именно. Причины бесполезности зависимых типов в твоём надуманном примере химические, а не математически-алгоритмические. О чём тебе и говорят.
PD>Нет. Говоря о химических причинах, я просто имел в виду, что в химии нет методов, позволяющих рассчитывать эти значения с хорошей точностью. Это химический факт, не имеющий к теме дискуссии отношения. Предположим, что такой метод создан, что тогда ?
Тогда мы сможем вычислить в процессе компиляции и возвращать в функции float[computelow..computehigh]
Здравствуйте, VoidEx, Вы писали:
PD>>Нет. Говоря о химических причинах, я просто имел в виду, что в химии нет методов, позволяющих рассчитывать эти значения с хорошей точностью. Это химический факт, не имеющий к теме дискуссии отношения. Предположим, что такой метод создан, что тогда ? VE>Тогда мы сможем вычислить в процессе компиляции и возвращать в функции float[computelow..computehigh]
А если эти low и high были оценены неверно ? Их оценить для произвольного вещества, допустим, нельзя, так как метод расчета зависит от каких-то параметров, которые берутся из эксперимента, а он для этих веществ еще не проводился (ситуация вполне реальная : метод расчета есть, данных для него для некоего вещества пока нет)
Я вообще не понимаю, что должно быть в этом случае. Ты же предлагаешь статический анализ, то есть во время компиляции. А мне исходники, естественно, не дашь, если это коммерческая программа ? И вот я ей даю на вход вещество, для которого должно получится <low или > high. И что ?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, VoidEx, Вы писали:
PD>>>Нет. Говоря о химических причинах, я просто имел в виду, что в химии нет методов, позволяющих рассчитывать эти значения с хорошей точностью. Это химический факт, не имеющий к теме дискуссии отношения. Предположим, что такой метод создан, что тогда ? VE>>Тогда мы сможем вычислить в процессе компиляции и возвращать в функции float[computelow..computehigh]
PD>А если эти low и high были оценены неверно ? Их оценить для произвольного вещества, допустим, нельзя, так как метод расчета зависит от каких-то параметров, которые берутся из эксперимента, а он для этих веществ еще не проводился (ситуация вполне реальная : метод расчета есть, данных для него для некоего вещества пока нет)
low и high и так на этапе компиляции неизвестны, если ты об этом.
PD>Я вообще не понимаю, что должно быть в этом случае. Ты же предлагаешь статический анализ, то есть во время компиляции. А мне исходники, естественно, не дашь, если это коммерческая программа ? И вот я ей даю на вход вещество, для которого должно получится <low или > high. И что ?
Не понял вопроса.
Здравствуйте, VoidEx, Вы писали:
VE>low и high и так на этапе компиляции неизвестны, если ты об этом.
Тогда я не понимаю, как функция может вернуть ограниченный float[low..high]
PD>>Я вообще не понимаю, что должно быть в этом случае. Ты же предлагаешь статический анализ, то есть во время компиляции. А мне исходники, естественно, не дашь, если это коммерческая программа ? И вот я ей даю на вход вещество, для которого должно получится <low или > high. И что ? VE>Не понял вопроса.
Задача.
Есть метод расчета чего-то для неопределенного числа различных веществ .
Метод зависит от параметров.Параметры вводятся из файла. Для каждого вещества они свои.
Опиши, как будешь программу делать со статическим анализом.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, VoidEx, Вы писали:
VE>>low и high и так на этапе компиляции неизвестны, если ты об этом.
PD>Тогда я не понимаю, как функция может вернуть ограниченный float[low..high]
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Тогда я не понимаю, как функция может вернуть ограниченный float[low..high]
Пятисотый раз повторяю: Читай про зависимые типы.
PD>Есть метод расчета чего-то для неопределенного числа различных веществ . PD>Метод зависит от параметров.Параметры вводятся из файла. Для каждого вещества они свои.
Да плевать откуда они беруться.
Читай про зависимые типы.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, VoidEx, Вы писали:
PD>>Тогда я не понимаю, как функция может вернуть ограниченный float[low..high]
VE>Тут 22 страницы со ссылками на зависимые типы.
Если можешь объяснить (на пальцах), как это должно компилироваться и работать (пример, который я привел) — объясни. Если нет — закончим дискуссию.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Тогда я не понимаю, как функция может вернуть ограниченный float[low..high] WH>Пятисотый раз повторяю: Читай про зависимые типы.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Если можешь объяснить (на пальцах), как это должно компилироваться и работать (пример, который я привел) — объясни. Если нет — закончим дискуссию.
А как вообще работает вывод типов в языках?
Или он тоже не работает в "условиях в реальных проектов"?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, VoidEx, Вы писали:
PD>>>Тогда я не понимаю, как функция может вернуть ограниченный float[low..high]
VE>>Тут 22 страницы со ссылками на зависимые типы.
PD>Если можешь объяснить (на пальцах), как это должно компилироваться и работать (пример, который я привел) — объясни. Если нет — закончим дискуссию.
Выберу третье: могу, но не буду. Я считаю, что самостоятельный человек должен уметь сам извлекать информацию. Если не может — он идиот, и не стоит на него тратить время. Если может, но не делает, — значит не хочет, и тоже не стоит тратить на него время. Вот если бы информация была недоступна или чересчур сложна, был бы другой разговор.
Здравствуйте, jazzer, Вы писали:
V>>Я с этим и не спорю. Более того, повторю, статически типизированный язык на мой взгляд должен требовать, чтобы результат вызова ф-ии,отличный от void, куда-то девался. Тогда у нас вся программа будет представлять из себя эти "цепочки", пусть даже через промежуточные переменные. А если еще добавить константность на эти значения, будет совсем красиво и надежно. J>Ну, это можно сделать каким-нть внешним статическим анализатором или плагином к компилятору, благо GCC позволяет плагины подключать к нему, начиная с версии 4.5.
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); // OKauto a1 = protocol.next(a);
auto b1 = protocol.next(b);
protocol.exchange(a1, b/*1*/); // Compilation error