Страница 1 из 2 12 ПоследняяПоследняя
Показано с 1 по 10 из 44

Тема: Макросы ОЛ: с побочными эффектами и/или детерминированные?

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1

    По умолчанию

    Цитата Сообщение от anthrwpos Посмотреть сообщение
    Ну, просто ради развлечения)

    Код:
    set_reset :: Bool -> Bool -> State Bool ()
    set_reset False False = state (\w -> ((),w))
    set_reset True False = state (\_ -> ((),True))
    set_reset _ True = state (\_ -> ((),False))
    Здесь есть некоторое жульничество, но формально с точки зрения языка, вся эта конструкция является девственно чистой)
    Я просто хочу посмотреть, что вы на это скажете
    Делаю ставку на то, что тут вы пропихиваете дополнительный аргумент через pointfree.
    На вопрос "сколько аргументов у SR-триггера" вы отвечаете два, но тут дополнительно подали аргумент "историю прошлых серий" он же "глобальное состояние".

    Если объяснение неверное, то я попрошу вас дописать пример использования этого самого SR-триггера и всё встанет на свои места.



    Цитата Сообщение от anthrwpos Посмотреть сообщение
    Потому что изменение файла происходит во внешнем по отношению к функции окружению.
    Да, про файлы всё верно пишете.
    Но я хотел бы подчеркнуть, что вы напираете на слово "внешнее окружение", а с математической (она же computer science) точки зрения, невозможно определить что именно является "внешним окружением".

    Ну, реально.

    Поэтому, "изменение состояния" формулируется обычно как "наблюдаемое изменение состояние". Иными словами, если какое-то глобальное состояние изменяется, но это невозможно увидеть, то это "не считается". Именно поэтому я и называю ФБ SR-триггера блоком с побочным эффектом.

    Ответить на вопрос "меняет ли SR триггер глобальное состояние?", на самом деле, тяжело, ведь непросто сказать где именно хранится состояние SR триггера.
    Но на вопрос "можно ли заметить изменение состояния SR триггера?" ответ напрашивается сам собой. Очевидно, что заметить можно. Значит состояние есть, значит есть и побочный эффект по изменению этого состояния.

  2. #2
    Пользователь Аватар для anthrwpos
    Регистрация
    13.02.2017
    Адрес
    Ленобл
    Сообщений
    188

    По умолчанию

    Цитата Сообщение от Владимир Ситников Посмотреть сообщение
    Делаю ставку на то, что тут вы пропихиваете дополнительный аргумент через pointfree.
    На вопрос "сколько аргументов у SR-триггера" вы отвечаете два, но тут дополнительно подали аргумент "историю прошлых серий" он же "глобальное состояние".
    Если объяснение неверное, то я попрошу вас дописать пример использования этого самого SR-триггера и всё встанет на свои места.
    Пример использования
    Код:
    module Hs where
    
    import Control.Monad.State
    
    set_reset :: Bool -> Bool -> State Bool ()
    set_reset False False = state (\w -> ((),w))
    set_reset True False = state (\_ -> ((),True))
    set_reset _ True = state (\_ -> ((),False))
    
    main :: IO ()
    main = print $ execState prc False
    
    prc :: State Bool ()
    prc = do
      set_reset True False
      set_reset False False
    здесь в функции main вызывается функция execState, которой передается начальное состояние и которая возвращает конечное состояние.
    execState получив начальное состояние запускает функцию prc, где мы производим различные вычисления с использованием SR-триггера путем вызова функции set_reset.
    Вообще мы конечно можем там и любой другой код написать, где мы например, вычисляем с какими входами вызывать set_reset.
    Да, про файлы всё верно пишете.
    Но я хотел бы подчеркнуть, что вы напираете на слово "внешнее окружение", а с математической (она же computer science) точки зрения, невозможно определить что именно является "внешним окружением".
    Еще как возможно. На этом весь Хаскель и сделан.
    В вышеприведенном примере мы используем монаду State, которая создает свое внутреннее локальное состояние. Её использование совершенно не нарушает чистоты языка.
    В частности, вы можете прочитать это состояние из любой чистой функции и она останется чистой функцией, потому что читается локальное, внутреннее состояние. Но никакая чистая функция не может прочитать глобальное внешнее состояние создаваемое монадой IO.

  3. #3

    По умолчанию

    Цитата Сообщение от anthrwpos Посмотреть сообщение
    Пример использования...
    здесь в функции main вызывается функция execState, которой передается начальное состояние и которая возвращает конечное состояние.
    execState получив начальное состояние запускает функцию prc, где мы производим различные вычисления с использованием SR-триггера путем вызова функции set_reset.
    Вообще мы конечно можем там и любой другой код написать, где мы например, вычисляем с какими входами вызывать set_reset.
    Т.е. всё, как я и говорил: вы здесь в функцию set_reset передаёте "состояние триггера".
    Да, в вашем исполнении функция set_reset является чистой, но вы жульничаете в том плане, что помимо S и R аргументов передаёте дополнительный аргумент с состоянием триггера.

    Иначе говоря: SR_triger(S, R, prevState) можно называть чистой функцией.

    Но мы говорим про ОЛ. В ОЛ у SR-триггера всего два входа.
    Ну и сами же говорили, что у SR-триггера ДВА аргумента.


    Цитата Сообщение от anthrwpos Посмотреть сообщение
    Еще как возможно. На этом весь Хаскель и сделан.
    В вышеприведенном примере мы используем монаду State, которая создает свое внутреннее локальное состояние. Её использование совершенно не нарушает чистоты языка.
    В частности, вы можете прочитать это состояние из любой чистой функции и она останется чистой функцией, потому что читается локальное, внутреннее состояние. Но никакая чистая функция не может прочитать глобальное внешнее состояние создаваемое монадой IO.
    Да да да.

    По-вашему, любой ФБ является "чистым"?
    По-вашему, любая программа из ФБ, не обращающаяся к файлам/IO является "чистой"?

  4. #4
    Пользователь Аватар для anthrwpos
    Регистрация
    13.02.2017
    Адрес
    Ленобл
    Сообщений
    188

    По умолчанию

    Цитата Сообщение от Владимир Ситников Посмотреть сообщение
    Т.е. всё, как я и говорил: вы здесь в функцию set_reset передаёте "состояние триггера".
    Таки нет!)
    Посмотрите на сигнатуру set_reset. Она принимает только два Bool аргумента и никаких предыдущих состояний)
    Состояние содержится внутри функции prc, которую мы вызываем посредством execState.
    По-вашему, любая программа из ФБ, не обращающаяся к файлам/IO является "чистой"?
    Почти так. Всё, что не имеет никаких средств для обращения к IO по видимому, является чистым.

  5. #5

    По умолчанию

    Цитата Сообщение от anthrwpos Посмотреть сообщение
    Почти так. Всё, что не имеет никаких средств для обращения к IO по видимому, является чистым.
    О, круто (с вашего позволения, я пока не буду отвечать про сигнатуру set_reset)


    Давайте посмотрим на такой код на C:

    Код:
    int counter = 0;
    
    int abcd() {
      counter = counter + 1;
      return counter;
    }
    Внимание, вопрос: является ли функция abcd чистой?
    Очевидно, что IO эта функция не выполняет.

  6. #6
    Пользователь Аватар для anthrwpos
    Регистрация
    13.02.2017
    Адрес
    Ленобл
    Сообщений
    188

    По умолчанию

    Цитата Сообщение от Владимир Ситников Посмотреть сообщение
    Давайте посмотрим на такой код на C:

    Код:
    int counter = 0;
    
    int abcd() {
      counter = counter + 1;
      return counter;
    }
    Внимание, вопрос: является ли функция abcd чистой?
    Очевидно, что IO эта функция не выполняет.
    Нет, поскольку эта функция может читать ввод посредством некой другой функции, которая будет записывать его в переменную counter.

    А в хаскеле вы из монады IO повлиять на состояние монады State не можете никак =)

  7. #7

    По умолчанию

    Цитата Сообщение от anthrwpos Посмотреть сообщение
    Нет, поскольку эта функция может читать ввод посредством некой другой функции, которая будет записывать его в переменную counter.
    Чего чего?
    "функция может читать ввод посредством некой другой функции" ?

    О чём вообще речь. IO в программе вообще не происходит. Тут же просто сложение.
    Скажите, пожалуйста, по какому принципу вы относите эту функцию abcd к нечистым?

    Я могу добавить больше ограничений: никакая другая функция не обращается к переменной counter. Ни пишет, ни читает.
    Что? abcd это чистая функция в таком случае?

  8. #8

    По умолчанию

    Цитата Сообщение от Владимир Ситников Посмотреть сообщение
    Т.е. всё, как я и говорил: вы здесь в функцию set_reset передаёте "состояние триггера".
    Да, в вашем исполнении функция set_reset является чистой, но вы жульничаете в том плане, что помимо S и R аргументов передаёте дополнительный аргумент с состоянием триггера.
    Тут я ошибся. Да, действительно показанная реализация set_reset удовлетворяет моему исходному вопросу, и получает всего 2 аргумента.
    Да, был неправ, когда говорил про pointfree -- оно в конкретном случае не играет роли.

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

    Да, это позволяет сделать как бы SR триггер на Haskell, но это вольная/творческая переработка ОЛ программы.

    В том же самой же среде ОЛ, SR триггер получает два bool на вход и тут же возвращает bool на выходе.

    Поэтому, переформулирую вопрос про SR-триггер.
    Реализуйте вот такой SR-триггер:
    Код:
    set_reset :: Bool -> Bool -> Bool
    set_reset s r = ...
    SR-триггер в ОЛ это именно такой блок. Получает два bool, возвращает bool. Вы утверждаете, что он чистый, значит должно быть несложно составить аналогичную Haskell функцию.
    Последний раз редактировалось Владимир Ситников; 21.04.2017 в 16:23.

  9. #9
    Пользователь Аватар для anthrwpos
    Регистрация
    13.02.2017
    Адрес
    Ленобл
    Сообщений
    188

    По умолчанию

    Цитата Сообщение от Владимир Ситников Посмотреть сообщение
    Да, ваша прошлая реализация set_reset не получает никаких лишних скрытых аргументов, но эта реализация и не возвращает bool результат.
    Вот это правильно)
    Поэтому, переформулирую вопрос про SR-триггер.
    Реализуйте вот такой SR-триггер:
    Код:
    set_reset :: Bool -> Bool -> Bool
    set_reset s r = ...
    Вот такой триггер сделать невозможно.

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

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

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

  10. #10

    По умолчанию

    Цитата Сообщение от anthrwpos Посмотреть сообщение
    Вот такой триггер сделать невозможно.
    Ну вы же сами только что сказали, что вот такой SR-триггер не является чистой функцией:
    Код:
    set_reset :: Bool -> Bool -> Bool
    set_reset s r = ...
    "такой триггер сделать невозможно", значит оно не является чистой функцией.
    Если бы было сделать возможно, то это была бы чистая функция.

    Я намеренно исключаю возможность существования таких чистых функций, которые на Haskell невозможно выразить. Не хочу вдаваться в детали, но наверняка возможность записи любой функции доказывается через какую-нибудь муть типа лямбда-исчисления.

    Цитата Сообщение от anthrwpos Посмотреть сообщение
    Никаких фундаментальных недостатков чистоты в смысле развертки во времени я пока не нашел.
    Где ищите?
    Хоть что-нибудь читаете?

    Вот пример:

    https://www.schoolofhaskell.com/scho...ns-laziness-io
    Here are the fundamental properties of a pure function:

    1. A function returns exactly the same result every time it's called with the same set of arguments. In other words a function has no state, nor can it access any external state. Every time you call it, it behaves like a newborn baby with blank memory and no knowledge of the external world.
    2. A function has no side effects. Calling a function once is the same as calling it twice and discarding the result of the first call. In fact if you discard the result of any function call, Haskell will spare itself the trouble and will never call the function. No wonder Haskell has a reputation for laziness (more about it later).
    Смотрите внимательно на пункт №1. И читайте: "returns exactly the same result every time it's called with the same set of arguments".
    Ваша set_reset функция при вызове set_reset False False реально возвращает одну и ту же функцию.
    Тут "развёртка по времени" не играет никакой роли. Всё очень просто: вызвали set_reset False False -- получили в ответ одну и ту же функцию. Правда, полученная функция не имеет ничего общего с состоянием какого-либо SR триггера в ОЛ программе, но не суть.

    Теперь же про ОЛ: там мы вызвали SR триггер с аргументами FALSE, FALSE. И что он нам вернёт? TRUE? FALSE? Да пёс его знает, ведь возвращённое значение зависит от того, чему равно состояние триггера перед вызовом.


    Теперь про abcd2.
    Функция abcd2 при двух вызовах с одними и теми же аргументами возвращает разные результаты. При этом, вообще неважно где именно она хранит состояние переменной counter. Хоть "внутри функции", хоть "в глобальной области", хоть в регистре процессора. Это неважно. Важно то, что вызвали два раза с одинаковыми аргументами, а она, собака, вернула разные значения. Всё, баста карапузики, эта функция "не является детерминированной", и, значит, она не может являться "чистой" функцией.
    Если не нравится слово "не является детерминированной", то можно с тем же успехом процитировать статью: не выполнено свойство "A function returns exactly the same result..."

    Именно из-за этого сами функции abcd и abcd2 не являются чистыми функциями.
    Заметьте, я вообще не использовал при этом "вспомогательные гипотетические функции, которые могут читать-писать counter".
    Мне достаточно того факта, что "вызвали функцию, она вернула разное, значит не чистая".
    Последний раз редактировалось Владимир Ситников; 21.04.2017 в 19:36.

Страница 1 из 2 12 ПоследняяПоследняя

Похожие темы

  1. Специальные ,функционально законченные макросы
    от rovki в разделе Программируемые реле
    Ответов: 135
    Последнее сообщение: 14.02.2024, 12:43
  2. Универсальные макросы для OWEN Logic
    от rovki в разделе Среда программирования OWEN Logic
    Ответов: 827
    Последнее сообщение: 22.12.2023, 13:20
  3. макросы для ПР200.
    от Павел Братковский в разделе Среда программирования OWEN Logic
    Ответов: 174
    Последнее сообщение: 17.05.2020, 19:34
  4. Макросы для КаСкады
    от rovki в разделе Программируемые реле
    Ответов: 19
    Последнее сообщение: 04.09.2016, 10:08
  5. Макросы -- объясните немного....
    от tigdin в разделе Программируемые реле
    Ответов: 20
    Последнее сообщение: 28.08.2014, 15:18

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •