G>>>>Протокол и есть автомат Но это не ТЗ. Вот ТЗ: "стул должен стоять не ближе 5 метров от дивана". Переведи это в автомат.
DG>>>автомат из одной императивной команды: DG>>>установить положение стула не ближе 5 метров от дивана.
S>>С понятием автомата ты тоже не знаком?
DG>т.е. ты даже не понимаешь, что такое автомат из одной команды?
DG>
DG>Абстра́ктный автома́т (в теории алгоритмов) — математическая абстракция, модель дискретного устройства, имеющего один вход, один выход и в каждый момент времени находящегося в одном состоянии из множества возможных. На вход этому устройству поступают символы одного алфавита, на выходе оно выдаёт символы (в общем случае) другого алфавита.
DG>выполняет команду "установить положение стула не ближе 5 метров от дивана", выдает в поток символ "стул, для которого выполняется условие "стоять не ближе 5 метров от дивана"" и переходит в состояние "рабочее".
Не знаком ты с понятием автомата. Команды он не выполняет. Символы алфавита — выдает. А команды —
Здравствуйте, DarkGray, Вы писали:
DG>>>остальные функции являются чисто функциональными и детерминированными. S>>Резульаты остальных функций ты воле заменить значениями.
DG>покажи как
Смотришь, чему равно world.c на входе функции, делаешь соответствующие преобразования, получаешь новый World. Этим новым World заменяешь вызов функции.
Отсутствие побочных эффектов (а они там отсутствуют формально), позволяет совершить такую замену.
DG>>и соответственно, как только ты бы сделал правильное и четкое утверждение, то скорее всего до тебя бы дошло, что тебе показывают и тебя просят подумать про ту часть кода, которая состоит из чисто функциональных детерминированных функциях. S>Ты же написал что заменил код на чисто функциональный. Там не было никаких оговорок.
проблема в том, что я постоянно переоцениваю собеседника. и в данном случае ожидал, что ты можешь сам выделить чистофункциональную часть:
class C
{
public C(int x, int y = 0){this.X = x;this.Y = y;}
public readonly int X;
public readonly int Y;
}
class World
{
public int y;
public C c;
}
World F1(World w)
{
C c = new C(w.c.X + 1, w.c.Y);
return new World{c = c, y = w.y - c.X + c.Y};
}
World F2(World w)
{
C c = new C(w.c.X, w.c.Y - 1);
return new World{c = c, y = w.y + c.X + c.Y};
}
World F0(int y1, int y2, C c)
{
return new World{c = c, y = y1 + y2 + (c.X < 0 ? -c.X : c.X);};
}
class YYY
{
public int y1;
public int y2;
public int y3;
}
YYY clean_main(int startX)
{
C c = new C(startX);
var w1 = F1(F2(F1(F1(F1(new World{c = c, y = 7})))));
var w2 = F2(F1(F1(F2(F2(new World{c = w1.c, y = 24})))));
var w3 = F0(w1.y, w2.y, w2.c);
return new YYY{y1 = w1.y, y2 = w2.y, y3 = w3.y};
}
void main()
{
do
startX <- readLn
yyy = clean_main(startX);
PutLine(yyy.y3)
PutLine(yyy.y1)
PutLine(yyy.y2);
}
объясни, пожалуйста, почему в этой функциональной программе в чистой функциональной функции clean_main нельзя поменять местами ни одного вызова, и уж тем более нельзя заменить ни одну функцию на ее значение.
DG>>покажи как S>Смотришь, чему равно world.c на входе функции, делаешь соответствующие преобразования, получаешь новый World. Этим новым World заменяешь вызов функции. S>Отсутствие побочных эффектов (а они там отсутствуют формально), позволяет совершить такую замену.
это общие слова, а ты покажи какую конкретную замену можно сделать в чистой функции clean_main
S>Не знаком ты с понятием автомата. Команды он не выполняет. Символы алфавита — выдает. А команды —
в роботехнике автомат как раз команды исполняет.
можно, конечно, переписать в виде преобразующего автомата, которые преобразует входную последовательность в последовательность команд для исполнительного механизма:
входной алфавит: символ правило1 — стул должен стоять не ближе 5 метров от дивана
выходной алфавит: символ команда1 — установить положение стула не ближе 5 метров от дивана
входная последовательность: последовательность правил
выходная последовательность: последовательность команд для исполнительного механизма
автомат имеет три состояния:
инициальное,
рабочее,
терминальное.
стартует с инициального.
из инициального переходит в рабочее.
в рабочем читает один символ алфавита с потока (если символы кончились, то переходит в терминальное состояние),
для символа правило1 выдает на выход символ команда1 и переходит в состояние "рабочее".
в терминальном состояние автомат останавливается
DG>>>и соответственно, как только ты бы сделал правильное и четкое утверждение, то скорее всего до тебя бы дошло, что тебе показывают и тебя просят подумать про ту часть кода, которая состоит из чисто функциональных детерминированных функциях. S>>Ты же написал что заменил код на чисто функциональный. Там не было никаких оговорок.
DG>проблема в том, что я постоянно переоцениваю собеседника. и в данном случае ожидал, что ты можешь сам выделить чистофункциональную часть:
Я не посмел, ты ведь написал что сделал эквивалентный чисто функциональный код.
DG>
DG>class C
DG>{
DG> public C(int x, int y = 0){this.X = x;this.Y = y;}
DG> public readonly int X;
DG> public readonly int Y;
DG>}
DG>class World
DG>{
DG> public int y;
DG> public C c;
DG>}
DG>World F1(World w)
DG>{
DG> C c = new C(w.c.X + 1, w.c.Y);
DG> return new World{c = c, y = w.y - c.X + c.Y};
DG>}
DG>World F2(World w)
DG>{
DG> C c = new C(w.c.X, w.c.Y - 1);
DG> return new World{c = c, y = w.y + c.X + c.Y};
DG>}
DG>World F0(int y1, int y2, C c)
DG>{
DG> return new World{c = c, y = y1 + y2 + (c.X < 0 ? -c.X : c.X);};
DG>}
DG>class YYY
DG>{
DG> public int y1;
DG> public int y2;
DG> public int y3;
DG>}
DG>YYY clean_main(int startX)
DG>{
DG> C c = new C(startX);
DG> var w1 = F1(F2(F1(F1(F1(new World{c = c, y = 7})))));
DG> var w2 = F2(F1(F1(F2(F2(new World{c = w1.c, y = 24})))));
DG> var w3 = F0(w1.y, w2.y, w2.c);
DG> return new YYY{y1 = w1.y, y2 = w2.y, y3 = w3.y};
DG>}
DG>void main()
DG>{
DG> do
DG> startX <- readLn
DG> yyy = clean_main(startX);
DG> PutLine(yyy.y3)
DG> PutLine(yyy.y1)
DG> PutLine(yyy.y2);
DG>}
DG>
DG>объясни, пожалуйста, почему в этой функциональной программе
Программа не чисто функциональна, кури бамбук (можешь считать это ответом на переоценку собеседника ). DG>в чистой функциональной функции clean_main нельзя поменять местами ни одного вызова, и уж тем более нельзя заменить ни одну функцию на ее значение.
Потому что вычисления аргументов для очередного вызова завязаны на результат предыдущих вызовов. Но ты не расслабляйся. Судя по языку, я не смог его отнести к какому-то конкретному, потому вызывает сомнения порядок редукции в этом языке. Возможно его можно сменить, тогда изменится порядок вызовов. Возможно это не повлияет на побочный эффект от программы.
ЗЫ. На месте компилятора такого чисто функционального языка я бы оставил void main(){} на основе чистоты.
DG>>>покажи как S>>Смотришь, чему равно world.c на входе функции, делаешь соответствующие преобразования, получаешь новый World. Этим новым World заменяешь вызов функции. S>>Отсутствие побочных эффектов (а они там отсутствуют формально), позволяет совершить такую замену.
DG>это общие слова, а ты покажи какую конкретную замену можно сделать в чистой функции clean_main
Я отвечал до того как увидел твой новый кусок кода с clean_main
S>>Не знаком ты с понятием автомата. Команды он не выполняет. Символы алфавита — выдает. А команды —
DG>в роботехнике автомат как раз команды исполняет.
Очень ценное замечание. А в армии он стреляет.
DG>можно, конечно, переписать в виде преобразующего автомата, которые преобразует входную последовательность в последовательность команд для исполнительного механизма:
Теперь
DG>входной алфавит: символ правило1 — стул должен стоять не ближе 5 метров от дивана DG>выходной алфавит: символ команда1 — установить положение стула не ближе 5 метров от дивана DG>входная последовательность: последовательность правил DG>выходная последовательность: последовательность команд для исполнительного механизма DG>автомат имеет три состояния: DG>инициальное, DG>рабочее, DG>терминальное. DG>стартует с инициального. DG>из инициального переходит в рабочее. DG>в рабочем читает один символ алфавита с потока (если символы кончились, то переходит в терминальное состояние), DG>для символа правило1 выдает на выход символ команда1 и переходит в состояние "рабочее". DG>в терминальном состояние автомат останавливается
Возникает вопрос о целеобразности такого автомата, ну да фиг с ним.
S>Возникает вопрос о целеобразности такого автомата, ну да фиг с ним.
о том и речь, что все зависит от набора команд, поддержанных исполнительным механизмом (или что тоже самое, от вида исполнителя).
и что если не зафиксирован исполнитель (в виде поддержанного им набора команд), то делать какие-то утверждения бессмысленно, и уж тем более бессмысленно делать заявления о декларативности или императивности управляющего языка.
DG>>в роботехнике автомат как раз команды исполняет. S>Очень ценное замечание. А в армии он стреляет.
речь идет о том, что автоматов как грязи: с двумя входными лентами, с тремя входными, с двумя выходными, с десятью выходными, с ячейками памяти, с лентами памяти и т.д.
все они эквиваленты между собой, а также эквивалентны машине тьюринга.
и при набитой руке правила для преобразования одного автомата в другой генерятся за пару минут, и поэтому в каждом конкретном случае используется тот вид автомата, который удобнее.
предыдущий автомат с командами — это автомат с двумя выходными лентами: лента выходного результа + лента команд.
S>>Возникает вопрос о целеобразности такого автомата, ну да фиг с ним.
DG>о том и речь, что все зависит от набора команд, поддержанных исполнительным механизмом (или что тоже самое, от вида исполнителя).
Не понимаю, что такое вид исполнителя и как он меняется от изменения набора команд.
DG>и что если не зафиксирован исполнитель (в виде поддержанного им набора команд), то делать какие-то утверждения бессмысленно, и уж тем более бессмысленно делать заявления о декларативности или императивности управляющего языка.
И все-таки, как связана декларативность языка с исполнителем?
DG>>>в роботехнике автомат как раз команды исполняет. S>>Очень ценное замечание. А в армии он стреляет.
DG>речь идет о том, что автоматов как грязи: с двумя входными лентами, с тремя входными, с двумя выходными, с десятью выходными, с ячейками памяти, с лентами памяти и т.д. DG>все они эквиваленты между собой, а также эквивалентны машине тьюринга. DG>и при набитой руке правила для преобразования одного автомата в другой генерятся за пару минут, и поэтому в каждом конкретном случае используется тот вид автомата, который удобнее.
DG>предыдущий автомат с командами — это автомат с двумя выходными лентами: лента выходного результа + лента команд.
Я так понимаю, ты о каких-то своих автоматах, не о том, который математическая абстракция. Извини, сразу не понял.
Здравствуйте, DarkGray, Вы писали:
S>>Потому что вычисления аргументов для очередного вызова завязаны на результат предыдущих вызовов.
DG>это хорошо или плохо?
Шуруповерт — это хорошо или плохо? Я так думаю, что шуруповертом хорошо заворачивать шурупы. А чистить уши — плохо. Вот и композиция функций — это инструмент.
DG>и можно ли для этой программы сделать так, чтобы завязок не было или было меньше?
Это ты мне скажи. Ты же автор исходной программы. Я так и не понял, что же она должна делать кроме демонстрации "побочного эффекта" в "чистых" функциях, с которая с треском провалилась, как я считаю.
V>>>Просто оно в общем случае описывает эквивалентный автомат, например в терминах use-case... или различные виды описаний каких-нить протоколов и т.д. G>>Протокол и есть автомат Но это не ТЗ. Вот ТЗ: "стул должен стоять не ближе 5 метров от дивана". Переведи это в автомат.
DG>автомат из одной императивной команды: DG>установить положение стула не ближе 5 метров от дивана.
DG>>предыдущий автомат с командами — это автомат с двумя выходными лентами: лента выходного результа + лента команд. S>Я так понимаю, ты о каких-то своих автоматах, не о том, который математическая абстракция. Извини, сразу не понял.
S>>>Потому что вычисления аргументов для очередного вызова завязаны на результат предыдущих вызовов.
DG>>это хорошо или плохо? S>Шуруповерт — это хорошо или плохо? Я так думаю, что шуруповертом хорошо заворачивать шурупы. А чистить уши — плохо. Вот и композиция функций — это инструмент.
ты же по специальности программист? верно?
при этом получается, что ты смог дать наивное пояснение про шуруповерт (который к программированию не имеет никакого отношения) — для каких задач шуруповерт является хорошим инструментом, а для каких не очень (правда скорее всего это опять же не твое понимание, а лишь цитата какого-нибудь авторитета из инструкции к шуруповерту).
а по своей специальности, ты не смог сформулировать даже наивное пояснение, чем хороши (или плохи) завязки между вызовами функциями и при каких условиях. Это к теме, кого сейчас берут в программисты..
S>>>Возникает вопрос о целеобразности такого автомата, ну да фиг с ним.
DG>>о том и речь, что все зависит от набора команд, поддержанных исполнительным механизмом (или что тоже самое, от вида исполнителя). S>Не понимаю, что такое вид исполнителя и как он меняется от изменения набора команд.
есть вид исполнителя: процессор x86,
есть вид исполнителя: реляционная субд с поддержкой sql,
есть вид исполнителя: стековая машина с модулем АЛУ и ФПУ,
есть вид исполнителя: .net,
есть вид исполнителя: .net с набором библиотек для заданной тематики,
есть вид исполнителя: haskell,
есть вид исполнителя: "человек с тремя классами образования",
есть вид исполнителя: человек-специалист в заданной тематике.
и т.д.
каждый из них обладает своим набором поддерживаемых команд, если этот набор последовательно менять (добавляя/убавляя по команде), то произойдет переход к другому виду исполнителя.
DG>>и что если не зафиксирован исполнитель (в виде поддержанного им набора команд), то делать какие-то утверждения бессмысленно, и уж тем более бессмысленно делать заявления о декларативности или императивности управляющего языка. S>И все-таки, как связана декларативность языка с исполнителем?
напрямую (и ты это увидишь, как только определение из той же вики переведешь к математическому виду)
например, для исполнителя samius конструкция "автомат из одной команды Z" есть императивная программа, которую он понимает только если рядом приложена пошаговая инструкция, как из этой конструкции перейти к поддерживаемому им набору команд, в частности, к автомату математическому классическому.
большая часть сказанного в треде воспринимается также императивно: понятно пока есть инструкция — как это понимать; при наличии малейших отклонений в условии — ступор и выдача ошибки.
не делает видимых попыток перехода к декларативному мышлению: фиксирование требований к результату с последующим выбором наилучших инструментов для достижения поставленной цели.
V>>>>Просто оно в общем случае описывает эквивалентный автомат, например в терминах use-case... или различные виды описаний каких-нить протоколов и т.д. G>>>Протокол и есть автомат Но это не ТЗ. Вот ТЗ: "стул должен стоять не ближе 5 метров от дивана". Переведи это в автомат.
DG>>автомат из одной императивной команды: DG>>установить положение стула не ближе 5 метров от дивана.
G>А толку?
при наличии исполнителя, который умеет выполнять эту команду — такого автомата достаточно.
DG>>>предыдущий автомат с командами — это автомат с двумя выходными лентами: лента выходного результа + лента команд. S>>Я так понимаю, ты о каких-то своих автоматах, не о том, который математическая абстракция. Извини, сразу не понял.
DG>понаберут народ на форумы по объявлениям...
DG>это как раз и есть всё математические автоматы, и в приличных вузах на курсе "теории автоматов" (http://ru.wikipedia.org/wiki/%D2%E5%EE%F0%E8%FF_%E0%E2%F2%EE%EC%E0%F2%EE%E2) их как раз и изучают, и переводы одних видов автоматов в другие.
DG>
DG>Синтез автоматов — построение системы из заданных «элементарных автоматов», эквивалентную заданному автомату. Такой автомат называется структурным.
DG>автомат с двумя выходными лентами — это и есть структурный автомат, состоящий, например, из трех элементарных автоматов
Теорию автоматов нам читали, но автомат с двумя выходными лентами я что-то не припомню. Может и просто запамятовал. Но склоняюсь к тому что выдумал его ты.