Здравствуйте, DarkGray, Вы писали: DG>или другими словами: отнесение программы к декларативной или императивной, это есть задача классификации, а всякая нетривиальная классификация обладает следствием: у каждого класса есть свои свойства, которые не проявляются у других классов. DG>соответственно, вопрос: после того, как ты отнес программу "найди такой целый x, чтобы x^3 был равен сумме y^3+z^3, где z и y — целые" к классу декларативная, какие свойства у данной программы появились? (вопрос в конструктивной логике, а не в логике существования)
После отнесения никакие свойства, конечно же, не появились. Вот мы отнесли воду к классу "жидкости". У неё что, появились какие-то свойства? Нет, они были и до этого.
Мне лично кажется, что классификация выполняется на основе наличия либо отсутствия каких-либо свойств.
В частности, приведённая программа не обладает свойством быть выраженной в терминах последовательного изменения состояния некоторого вычислителя.
Однократного изменения состояния (из "не знаю ответ" в "знаю ответ") недостаточно для того, чтобы считать программу императивной.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
S>После отнесения никакие свойства, конечно же, не появились. Вот мы отнесли воду к классу "жидкости". У неё что, появились какие-то свойства? Нет, они были и до этого.
это в логике существования. когда используется, что свойства чего-либо существуют без нашего знания о них, но проблема в том, что как тогда эти свойства на практике использовать, если мы о них не знаем?
соответственно, рекомендуется утверждения строить в конструктивной логике (а не в логике существования), и тогда свойства появляются как результат выводов из предыдущих утверждений
например, для числа 2^2012^2012 — 1 мы знаем, что существует классификация: оно либо простое либо нет, либо делиться на три, либо нет.
но пока у нас нет алгоритма, который может это проверить, появляется третий вариант — еще не знаем.
и утверждается, что если мы классифицируем это число, как имеющее нулевой остаток от целочисленного деления на 3, тогда это число будет обладать свойством, что оно непростое.
S>После отнесения никакие свойства, конечно же, не появились. Вот мы отнесли воду к классу "жидкости". У неё что, появились какие-то свойства? Нет, они были и до этого.
они были, но мы о них не знали.
если мы относим воду к классу "жидкость", то мы тогда получаем знание о свойствах:
вода имеет свойства: текучесть, сохраняние объема, вязкость и т.д. по списку физические свойства жидкости: http://ru.wikipedia.org/wiki/%C6%E8%E4%EA%EE%F1%F2%FC
так же можем осторожно делать вывод, что вода не твердая, и не газообразная.
S>Мне лично кажется, что классификация выполняется на основе наличия либо отсутствия каких-либо свойств. S>В частности, приведённая программа не обладает свойством быть выраженной в терминах последовательного изменения состояния некоторого вычислителя. S>Однократного изменения состояния (из "не знаю ответ" в "знаю ответ") недостаточно для того, чтобы считать программу императивной.
не обладает свойством быть выраженной — это нельзя построить алгоритм, который переводит эту программу в последовательность изменения состояния некоторого вычислителя?
но для haskell-я и sql-я такой алгоритм есть, это означает что haskell и sql — императивные?
S>>В частности, приведённая программа не обладает свойством быть выраженной в терминах последовательного изменения состояния некоторого вычислителя.
кстати, может ты хотел добавить про конечность алгоритма.
программу про кубы можно представить в виде бесконечного алгоритма последовательного перебора значений (x0, y0), (x0+1, y0), (x0+1, y0+1), (x0+2, y0+1) и т.д.
DG>деление на декларативный и императивный код появилось на заре становления программирования при решении задачи: может ли меняться код исполнения при той или иной записи программы? и в какой степени?
тоже самое можно переформулировать в конструктивную форму:
если для программы можно построить несколько способов исполнения, то программа является декларативной, иначе императивной.
но сейчас с появлением оптимизирующих исполнителей для чего угодно, это определение перестало делить программы на два класса, оно почти все программы запихивает в класс декларативных
соответственно, если хочется продолжать делить языки на два класса, то необходимо поменять этот критерий, и, например, специфицировать как именно подсчитывается кол-во способов исполнения.
G>>Более того императивную программу на haskell (завернутое в IO) не получится автоматически переписать в декларативную программу на haskell.
DG>можно, кстати, пример применения реальной программы на хаскеле, которая не использует монаду IO (или ее аналог)
Нет, потому что main::IO()
Отказаться от побочных эффектов нельзя. Вся суть любой программы в побочных эффектах. Но сделать так чтобы побочные эффекты были только там где необходимы стремятся все.
Здравствуйте, DarkGray, Вы писали:
DG>это в логике существования. когда используется, что свойства чего-либо существуют без нашего знания о них, но проблема в том, что как тогда эти свойства на практике использовать, если мы о них не знаем?
Не вижу проблемы. Свойства существуют независимо от нашего знания о них. Чтобы использовать на практике их, естественно, нужно узнать.
DG>они были, но мы о них не знали. DG>если мы относим воду к классу "жидкость", то мы тогда получаем знание о свойствах.
В моём мире всё наоборот: сначала мы получили знание о свойствах, и после этого получили возможность относить воду к одному или нескольким классам. DG>не обладает свойством быть выраженной — это нельзя построить алгоритм, который переводит эту программу в последовательность изменения состояния некоторого вычислителя?
Нет. Декларативность/императивность программы ничего не говорит о воможности трансформировать её в некоторую другую программу с другими свойствами.
Она является свойством самой программы в том виде, как она записана. DG>но для haskell-я и sql-я такой алгоритм есть, это означает что haskell и sql — императивные?
Вы не угадали.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, DarkGray, Вы писали:
S>>>В частности, приведённая программа не обладает свойством быть выраженной в терминах последовательного изменения состояния некоторого вычислителя.
DG>кстати, может ты хотел добавить про конечность алгоритма.
Нет, не хотел. DG>программу про кубы можно представить в виде бесконечного алгоритма последовательного перебора значений (x0, y0), (x0+1, y0), (x0+1, y0+1), (x0+2, y0+1) и т.д.
1. Что значит "бесконечный"? С точки зрения формулировки, этот алгоритм не более бесконечен, чем алгоритм поиска наибольшего общего делителя.
2. Если вы опираетесь на результат Эйлера в своём предположении о бесконечности алгоритма, то его можно представить в ещё более компактной форме:
start: goto start;
3. И, да, вы привели схему другой программы, которая, по косвенным признакам, является императивной. Это ничего не говорит об императивности исходной программы.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, DarkGray, Вы писали:
S>>Мутишь воду. Равная мощность языков по Тьюрингу не означает возможность автоматического перевода. Определение читал?
DG>если не требуется сохранить время выполнения, то означает.
Покажи мне автоматический перевод sql (без процедур) в регулярные выражения
DG>для перевода языка L1 в язык L2 без сохранения времени выполнения программы достаточно: DG>1. на языке L2 иметь компилируемый эмулятор языка L3 стековой машины (или, например, эмулятор asm x86),
А ты его автоматически получил?
G>>Более того императивную программу на haskell (завернутое в IO) не получится автоматически переписать в декларативную программу на haskell.
DG>можно, кстати, пример применения реальной программы на хаскеле, которая не использует монаду IO (или ее аналог)
Не понимаю, что ты подразумеваешь под аналогом монады, но вот тебе реальная программа, не использующая монаду IO:
ты говоришь, что конструкция foreach(x in items) в ФЯ есть функция, потому что кто-то такой ярлык наклеил, а такая же конструкция в C++ (for (var it = s.begin(); it != s.end(); ++it) — не есть функция, потому что в книжке про это не написано.
но свойства у этих двух конструкций одинаковые, а классификация должна делаться на основе свойств
монада — которая обеспечивает продолжение выполнение с произвольного места.
goto делает тоже самое
DG>>halt проще всего реализовывать через exception-ы DG>>http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html S>Если exception-ы принять за вариант результата функции, то ничего управляющего в них нет.
тоже самое можно принять и для C++, и для C#, что это просто такой хитрый результат вызова функции
DG>>это в логике существования. когда используется, что свойства чего-либо существуют без нашего знания о них, но проблема в том, что как тогда эти свойства на практике использовать, если мы о них не знаем? S>Не вижу проблемы. Свойства существуют независимо от нашего знания о них.
не научное (не конструктивное) определение — потому что нечего фальсифицировать
конструктивное определение — свойство существует независимо от нашего знания о нем, если свойство проявляется в независимости от нашего знания о нем
возьмем, следующий пример (и покажем, что существования свойства не достаточно для его проявления):
var items = (1, 3, 5, 7, 9);
var sortedItems = items.order-by();
здесь последовательность (1, 3, 5, 7, 9) имеет много свойств, и в частности имеет свойство: отсортированности по возрастанию.
Если мы (программист, компилятор, функция, исполнитель и т.д.) знаем, что эта последовательность отсортированная, то ее можно не сортировать (и код будет отрабатывать за O(1), если последовательность построена на этапе компиляции), если же про это свойство не знаем, то код будет работать за O(n*logn).
в тоже время код:
var x = 5 / i;
будет кидать исключение при делении на 0, в независимости от того, знает ли программист, компилятор, функция и т.д., что i может принимать значения 0, и что при делении на 0 кидается исключение.
здесь про то, что делить на на 0 нельзя, и что в данный момент i == 0 — знает самый "нижний" исполнитель: АЛУ в процессоре.
итого:
свойство упорядоченности в первом коде проявляется только, если мы о нем знаем — и для него нельзя считать, что оно существует в независимости от нашего знания
свойство "что деление на 0 прерывает последовательную работу функции" проявляется в независимости от нашего знания, и можно считать, что он существует без нашего знания о нем
DG>>>http://www.xoltar.org/old_site/2003//sep/09/haskellLoops.html S>>Я вижу там определение функции
DG>вот в этом и есть проблемы твоего подхода.
Не надо перевешивать на меня свои проблемы
DG>ты говоришь, что конструкция foreach(x in items) в ФЯ есть функция, потому что кто-то такой ярлык наклеил
Я такое не говорил. Я говорю что в хаскеле нет конструкции foreach. Какой ярлык — это я без понятия. К чему клеить-то, если такой конструкции в языке нет?
DG>, а такая же конструкция в C++ (for (var it = s.begin(); it != s.end(); ++it) — не есть функция, потому что в книжке про это не написано.
В книжке написано что это statement. Если разуешь глаза, то увидишь что он никак не обладает признаками функции.
DG>но свойства у этих двух конструкций одинаковые, а классификация должна делаться на основе свойств
Хреновая у тебя классификация, если она statement и функцию классифицирует одинаково.
DG>>>http://en.wikibooks.org/wiki/Haskell/Control_structures S>>Интересно, это для тебя тоже условный переход?
DG>это альтернатива. DG>условный переход есть частный случай альтернативы, и на большинстве задач условный переход по свойствам не отличим от альтернативы
Так и запишем, что алтьтернативу в определении ты не можешь отличить от инструкции на перевод управления по метке
DG>>>http://hackage.haskell.org/packages/archive/GotoT-transformers/1.0/doc/html/src/Control-Monad-Trans-Goto.html S>>Ты читал что там?
DG>монада — которая обеспечивает продолжение выполнение с произвольного места.
Ты знаешь что такое монада? Почитай определение на досуге. А потом подумай, как монада может обеспечить продолжение с произвольного места. Так вот, goto там это функция, которая берет монадное вычисление и возвращает монадное значение (со слов автора). DG>goto делает тоже самое
Тебя смутил ярлык "goto". Делает goto из C совершенно другое.
DG>>>halt проще всего реализовывать через exception-ы DG>>>http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html S>>Если exception-ы принять за вариант результата функции, то ничего управляющего в них нет.
DG>тоже самое можно принять и для C++, и для C#, что это просто такой хитрый результат вызова функции
С исключением можно работать, можно строить на нем логику, как и на результате. halt/exit таким свойством не обладает, значит не может быть ни рассмотрен, ни смоделирован в качестве результата функции.
Здравствуйте, gandjustas, Вы писали:
DG>>можно, кстати, пример применения реальной программы на хаскеле, которая не использует монаду IO (или ее аналог)
G>Нет, потому что main::IO()
Из этого не следует, что нельзя написать программу, не иcпользующую монаду IO. Потому, что монада — это не какой-то абстрактный тип IO, а тройка из конструктора типа и двух функций. Их можно и не использовать. Вот эта программа
использует (понятно, что putStr написана с использованием монады IO). Например, для написания консольных утилит, которые не ведут с пользователем диалога (не запрашивают данные по сети, не пишут файлы на диск и т.д.), а обрабатывают данные потоково, в качестве этапа конвейера — никакая монада IO не нужна:
main = interact $ чистая_функция
G>Отказаться от побочных эффектов нельзя. Вся суть любой программы в побочных эффектах.
Не любой, вот вышеупомянутая утилита командной строки, для одних и тех же данных, прочитанных из стандартного ввода записывающая одни и те же данные в стандартный вывод — никаких побочных эффектов не имеет. Но это, понятно, очень небольшое подмножество программ.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
DG>>>это в логике существования. когда используется, что свойства чего-либо существуют без нашего знания о них, но проблема в том, что как тогда эти свойства на практике использовать, если мы о них не знаем? S>>Не вижу проблемы. Свойства существуют независимо от нашего знания о них.
DG>не научное (не конструктивное) определение — потому что нечего фальсифицировать
DG>конструктивное определение — свойство существует независимо от нашего знания о нем, если свойство проявляется в независимости от нашего знания о нем
DG>возьмем, следующий пример (и покажем, что существования свойства не достаточно для его проявления): DG>
DG>здесь последовательность (1, 3, 5, 7, 9) имеет много свойств, и в частности имеет свойство: отсортированности по возрастанию.
Тут ты говоришь об одном свойстве — об отсортированности конкретной последовательности. DG>Если мы (программист, компилятор, функция, исполнитель и т.д.) знаем, что эта последовательность отсортированная, то ее можно не сортировать (и код будет отрабатывать за O(1), если последовательность построена на этапе компиляции), если же про это свойство не знаем, то код будет работать за O(n*logn).
Тут ты говоришь уже о другом свойстве — о возможности сэкономить за счет не сортировать если кто-то знает что оно уже отсортировано. Причем знание об отсортированности последовательности — это не свойство последовательности.
DG>в тоже время код: DG>
DG>var x = 5 / i;
DG>
DG>будет кидать исключение при делении на 0, в независимости от того, знает ли программист, компилятор, функция и т.д., что i может принимать значения 0, и что при делении на 0 кидается исключение. DG>здесь про то, что делить на на 0 нельзя, и что в данный момент i == 0 — знает самый "нижний" исполнитель: АЛУ в процессоре.
Тут ты вообще рассматриваешь свойство непонятно чего. Кода, АЛУ, программиста и т.п. Тем не менее, по поводу кода выше ты ошибся. Пруф:
var i = 0.0;
var x = 5 / i;// здесь твой код выше буква в букву.
Console.WriteLine(i == 0); // True
Console.WriteLine(x); // бесконечность
DG>итого: DG>свойство упорядоченности в первом коде проявляется только, если мы о нем знаем — и для него нельзя считать, что оно существует в независимости от нашего знания
Она обладает свойством упорядоченности независимо от твоего знания. Это легко проверить. Попроси кого-нибудь проверить упорядоченность и записать это на бумажку. Потом проверь сам. Сравни свое знание с бумажкой.
DG>свойство "что деление на 0 прерывает последовательную работу функции" проявляется в независимости от нашего знания, и можно считать, что он существует без нашего знания о нем
Я скажу больше. Все обладает своими свойствами без твоего знания об этом. Твои знания/незнания об этом могут влиять лишь на истинность твоих утверждений (а могут и не повлиять). Твой код будет работать верно или не верно вне зависимости от твоих знаний о нем, но в зависимости от других свойств, которыми обладают вещи, вне зависимости от твоих знаний об этом. И вне зависимости от твоих взглядов (конструктивистских или еще каких). Твои примеры это демонстрируют.
Здравствуйте, DarkGray, Вы писали:
DG>не научное (не конструктивное) определение — потому что нечего фальсифицировать
Хм. Мне лично вот кажется, что свойство воды занимать весь предоставленный ей объём можно легко фальсифицировать, опровергнув, таким образом, предположение о возможности классифицировать её как газ.
DG>возьмем, следующий пример (и покажем, что существования свойства не достаточно для его проявления): DG>
DG>здесь последовательность (1, 3, 5, 7, 9) имеет много свойств, и в частности имеет свойство: отсортированности по возрастанию. DG>Если мы (программист, компилятор, функция, исполнитель и т.д.) знаем, что эта последовательность отсортированная, то ее можно не сортировать (и код будет отрабатывать за O(1)
Отличный пример. DG>если же про это свойство не знаем, то код будет работать за O(n*logn).
Ну и откуда вы взяли это O(n*logn)? Вы, наверное, подразумеваете какую-то особенную реализацию внутри вашего order-by().
Если мы применим какой-нибудь реальный алгоритм, то окажется, что свойства последовательности будут проявляться независимо от нашего априорного знания о них.
Например, bubblesort обработает её за 4 сравнения и 0 перестановок — ровно столько нужно, чтобы убедиться, что имеет место свойство упорядоченности. А какую-то другую последовательность длины 5 он обработает за 20 сравнений и 20 перестановок.
Quicksort тоже существенно по-разному будет работать с разными последовательностями. Оценки, которыми вы столь смело оперируете, получены статистически — в предположении, что все возможные последовательности длины N равновероятны.
DG>в тоже время код: DG>
DG>var x = 5 / i;
DG>
DG>будет кидать исключение при делении на 0, в независимости от того, знает ли программист, компилятор, функция и т.д., что i может принимать значения 0, и что при делении на 0 кидается исключение.
Ещё один отличный пример. Если i не может принимать значения 0, то данный код никогда не будет бросать исключение.
DG>свойство упорядоченности в первом коде проявляется только, если мы о нем знаем — и для него нельзя считать, что оно существует в независимости от нашего знания
Как видим, вы опять не угадали.
А теперь, собственно, главный вопрос: при чём тут декларативность?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
S>В моём мире всё наоборот: сначала мы получили знание о свойствах, и после этого получили возможность относить воду к одному или нескольким классам.
во-первых: тогда получается тавтологичная классификация:
из наличия свойств A + B + C следует относимость к классу Z, а из относимости к классу Z только следуют свойства A, B и C.
во-вторых: ты в своих рассуждениях из утверждения: программа X — декларативная, делаешь вывод программа Z — не императивная. а такой вывод можно делать только если доказано, что свойства классов декларативная и императивная не пересекаются.
S>В моём мире всё наоборот: сначала мы получили знание о свойствах, и после этого получили возможность относить воду к одному или нескольким классам.
конструктивно это можно записать так: было проверено, что вода при нормальных условиях (примеси такие-то, температура такая-то, давление такое-то, сила тяжести такая-то, кол-во воды такое-то и т.д.) имеет такие-то и такие-то свойства и поэтому мы ее относим к классу жидкости. из отнесения к классу жидкости следует, что вода обладает при нормальных условиях такими-то, такими-то свойствами.
а дальше возникает вопрос: если нормальные условия поменяются (например, будут рассматриваться свойства воды при давлении 10тыс. атм), то какие свойства надо проверить, чтобы воду отнести к классу жидкости, и если мы ее отнесем к классу жидкости при таких условиях, то какие свойства из это следует?
с ЯП все тоже самое: 40 лет назад нормальные условия были другие — свойства декларативного ЯП и императивного ЯП не пересекались.
в частности, декларативную программу можно было выполнить множеством способом, а императивную — только одним.
для императивной программы был известен пошаговый алгоритм выполнения, для декларативной — нет.
и т.д.
и в те времена, если ЯП относили к классу декларативный, то из него следовали данные свойства, тоже самое для императивного.
прошло 40 лет и нормальные условия поменялись: развились алгоритмы, появились оптимизирующие исполнители и т.д.
и возникает вопрос: а что сегодня следует из того, если программа отнесена к тому или иному классу?