Ссылка Date.now прозрачна?
DateTime.Now или жеDate.now прозрачен ли ссылочный?
Это одна из спорных тем в статье о функциональном программировании вQiita.
Прежде всего, мы должны быть очень осторожными, так как слово «прозрачный по ссылкам» является в некотором смысле хитрым словом / концепцией, и в
Что такое ссылочная прозрачность?
Спрашивающий заявляет:
Что означает термин ссылочная прозрачность? Я слышал, что это описывается как «это означает, что вы можете заменить равные равными», но это выглядит как неадекватное объяснение.
Очень типичное объяснение, но идея, которая обычно приводит нас к недоразумению, заключается в следующем: (# 2 ответ на вышеупомянутой странице @Brian R. Bondy)
Ссылочная прозрачность, термин, обычно используемый в функциональном программировании, означает, что при наличии функции и входного значения вы всегда будете получать один и тот же результат. То есть в функции не используется внешнее состояние.
Типичные утверждения, которые я всегда слышал и считал неправильными, таковы:
На языке программированияDate.now
всегда возвращаетдругое значение что соответствует текущему времени, и в соответствии с
учитывая функцию и входное значение, вы всегда получите один и тот же вывод.
следовательно,Date.now
Не ссылочный прозрачный!
Я знаю, что некоторые (функциональные) программисты твердо убеждены в том, что приведенное выше утверждение заслуживает доверия, однако, ответы № 1 и № 3 @Uday Reddy объясняют следующим образом:
Любой разговор о «ссылочной прозрачности» без понимания различия между L-значениями, R-значениями и другими сложными объектами, которые населяют концептуальную вселенную императивного программиста, в корне ошибочен.
Представление функциональных программистов о ссылочной прозрачности, кажется, отличается от стандартного понятия тремя способами:
В то время как философы / логики используют такие термины, как «ссылка», «обозначение», «designatum» и «bedeutung» (немецкий термин Фреге), функциональные программисты используют термин «значение». (Это не совсем их работа. Я замечаю, что Лэндин, Стрейчи и их потомки также использовали термин «ценность», чтобы говорить об упоминании / обозначении. Это может быть просто терминологическое упрощение, которое представили Ландин и Стрейчи, но похоже, что большая разница при использовании наивно.)
Функциональные программисты, похоже, считают, что эти «ценности» существуют внутри языка программирования, а не снаружи. При этом они отличаются как от философов, так и от семантиков языка программирования.
Кажется, они считают, что эти «ценности» должны быть получены путем оценки.
Если подумать, «внешнее состояние» - это тоже хитрое слово / понятие.
Ссылочная прозрачность, термин, обычно используемый в функциональном программировании, означает, что при наличии функции и входного значения вы всегда будете получать один и тот же результат. То есть в функции не используется внешнее состояние.
Является ли «текущее время» «внешним состоянием» или «внешним значением»?
Если мы называем «текущее время» «внешним состоянием», как насчет «события мыши»?
«событие мыши» - это не состояние, которым нужно управлять с помощью контекста программирования, это скореевнешнее событие.
учитывая функцию и входное значение, вы всегда получите один и тот же вывод.
Итак, мы можем понять следующее:
«текущее время» не является ни «входным значением», ни «внешним значением», ни «внешним состоянием» иDate.now
всегда возвращает один и тот же выход, соответствующий текущему событию «текущее время».
Если кто-то все еще настаивает илихочу назвать «текущее время» как «значение», снова,
Функциональные программисты, похоже, считают, что эти «ценности» существуют внутри языка программирования, а не снаружи. При этом они отличаются как от философов, так и от семантиков языка программирования.Значение «текущего времени» никогда не существует в языке программирования, а только внеи значение «текущего времени» за пределами явно обновляется черезне контекст программирования, а реальный поток времени.
Поэтому я понимаю, что Date.now прозрачен по ссылкам.
Я хотел бы прочитать вашу идею. Благодарю.
EDIT1
ВЧто такое (функциональное) реактивное программирование?
Конал Эллиотт @Conal также объясняет функционально-реактивное программирование (FRP).
Он является одним из первых, кто разработал FRP, и объясняет так:
FRP о - "типы данных, которые представляют значение" с течением времени "
Динамические / развивающиеся значения (то есть, значения «во времени») сами по себе являются первоклассными значениями.
В этой перспективе FRP,
Date
можно рассматривать как первоклассное значение «со временем», которое является неизменным объектом на оси времени.
.now
это свойство / функция для адресации «текущее время» в пределахDate
СледовательноDate.time
возвращает неизменяемое и ссылочное прозрачное значение, которое представляет наше «текущее время».
EDIT2
(в JavaScript)
ссылочная непрозрачная функция
let a = 1;
let f = () => (a);
вводFunction:f
нет; выводFunction:f
зависит отa
это зависит от контекста за пределамиf
ссылочная прозрачная функция
let t = Date.now();
let f = (Date) => (Date.now());
Хотя,Date
значение проживает в нашем физическом мире,Date
может рассматриваться как неизменное первоклассное значение FRP «со временем».
посколькуDate
Ссылка из любого контекста программирования идентична, мы обычно неявно можем опуститьDate
в качестве входного значения и просто как
let f = () => (Date.now());
EDIT3
На самом деле, я отправил письмо Коналу Эллиотту @Conal, одному из первых разработчиков FRP. Он любезно ответил и сообщил мне, что здесь есть похожий вопрос.
Как может существовать функция времени в функциональном программировании?
Спрашивающий заявляет:
Итак, мой вопрос: может ли функция времени (которая возвращает текущее время) существовать в функциональном программировании?
Если да, то как оно может существовать? Не нарушает ли это принцип функционального программирования? Это особенно нарушает ссылочную прозрачность, которая является одним из свойств функционального программирования (если я правильно понимаю).
А если нет, то как узнать текущее время в функциональном программировании?
и ответ Конала Эллиотта @Conal в stackoverflow:
Да, для чистой функции возможно вернуть время, если оно указано в качестве параметра. Другой аргумент времени, другой результат времени. Затем формируйте и другие функции времени и объединяйте их с простым словарем функций (-временных) -преобразующих (высших порядков) функций. Поскольку подход не использует состояние, время здесь может быть непрерывным (не зависящим от разрешения), а не дискретным, что значительно повышает модульность. Эта интуиция является основой функционально-реактивного программирования (FRP).
Edit4 Моя благодарность за ответ @Roman Sausarnes.
Пожалуйста, позвольте мне представить мою точку зрения на функциональное программирование и FRP.
Прежде всего, я думаю, что программирование - это, в основном, математика, а функциональное программирование преследует этот аспект. С другой стороны, императивное программирование - это способ описать этапы работы машины, а это не обязательно математика.
Чистое функциональное программирование, такое как Haskel, испытывает определенные трудности с обработкой «состояния» или ввода-вывода, и я думаю, что вся проблема связана с «временем».
«состояние» или «время» для нас, людей, в значительной степени субъективно. Мы естественно верим, что «время» течет или проходит, а «состояние» меняется, то естьНаивный реализм.
Я думаю, что наивный реализм «времени» - это фундаментальная опасность и причина всей путаницы в сообществе программистов, и очень немногие обсуждают этот аспект. В современной физике, или даже в физике Ньютона, мы относимся ко времени чисто математическим образом, поэтому, если мы рассматриваем наш мир с точки зрения физики, нет ничего сложного в том, чтобы относиться к нашему миру с помощью чисто математического функционального программирования.
Итак, я рассматриваю наш мир / вселенную неизменным, как предварительно записанный DVD, и только наше субъективное представление изменчиво, включая «время» или «состояние».
В программировании единственной связью между неизменной вселенной и нашим изменчивым субъективным опытом является «событие». Чистый функциональный язык программирования, такой как Haskell, в основном не имеет этого представления, хотя некоторые проницательные исследователи, включая Корнеля Эллиота, продолжают FRP, но большинство все еще думает, что метод FRP все еще незначителен или труден в использовании, и многие из них рассматривают изменяемое состояние как само собой разумеющееся.
Естественно, FRP является единственным разумным решением, и особенно Корнель Эллиотт как основатель применил эту философскую точку зрения и заявляет:первоклассное значение "со временем", Возможно, к сожалению, многие программисты не поймут, что он на самом деле имел в виду, так как они пойманы в ловушку Наивного реализма, и им трудно рассматривать «время» как философскую или физически неизменную сущность.
Так что, если они обсудятчистый функционал" или же "ссылочная прозрачность«Для преимущества математической целостности / согласованности, для меня« Date.now »естественно прозрачен по ссылкам в чисто функциональном программировании просто потому, что« Date.time »обращается к определенной точке неизменяемой временной шкалы неизменяемой вселенной.
Так что насчетссылочная прозрачность в денотационной семантике, такой как @Reddy или @Roman Sausarnes, обсуждает?
Я рассматриваю ссылочную прозрачность в FP, особенно в сообществе Haskell, - все о математической целостности / согласованности.
Конечно, возможно, я мог бы следовать обновленному определению «ссылочной прозрачности» сообществом Haskell, и практически мы считаем, что код математически несовместим, если мы считаем, что он не является ссылочно-прозрачным, правильным?
На самом деле, опять же,
Как может существовать функция времени в функциональном программировании?
Программист задал следующий вопрос:
Итак, мой вопрос: может ли функция времени (которая возвращает текущее время) существовать в функциональном программировании?
Если да, то как оно может существовать? Не нарушает ли это принцип функционального программирования? Это особенно нарушает ссылочную прозрачность, которая является одним из свойств функционального программирования (если я правильно понимаю).
А если нет, то как узнать текущее время в функциональном программировании?
консенсус
нарушать принцип функционального программирования
= нарушает ссылочную прозрачность, которая является одним из свойств функционального программирования
= Математически противоречиво!
Это наше общее восприятие, верно?
В этом вопросе многие ответили, что «функция, возвращающая текущее время» не является ссылочно-прозрачной, особенно в определении «ссылочной прозрачности» сообществом Haskell, и многие упоминали, что речь идет о математической согласованности.
Однако лишь немногие ответили, что «функция, возвращающая текущее время» прозрачна по ссылкам, и один из ответов с точки зрения FRP - Конал Эллиотт @Conal.
IMO, FRP, перспектива для обработки потока времени как первоклассного неизменного значения «во времени» - это правильный подход с математическим принципом, подобным физике, как я упоминал выше.
Тогда почему функция «Date.now» / «возвращающая текущее время» стала ссылочной непрозрачной в контексте Haskell?
Что ж, единственное объяснение, которое я могу придумать, это то, что обновленное определение "ссылочной прозрачности" сообществом Haskell несколько неверно.
Событийная и математическая целостность / последовательность
Я упомянул - в программировании единственная связь между неизменной вселенной и нашим изменчивым субъективным опытом - это «событие» или «управляемый событиями».
Функциональное программирование оценивается управляемым событиями способом, с другой стороны, императивное программирование оценивается с помощью шагов / процедуры работы машины, описанной в коде.
«Date.now» зависит от «события», и в принципе «событие» неизвестно контексту кода.
Итак, разрушает ли управляемый событиями математическую целостность / последовательность? Точно нет.
Отображение синтаксиса в значение - индексное (указательный палец)
К.С. Пирс ввел термин «индексный», чтобы предложить идею указания (как в «указательном пальце»), «Я», [[здесь]], [[сейчас]] и т. Д.
Вероятно, это математически идентичное понятие «монады», «функтора» вещей в Haskell. В денотационной семантике даже в Хаскеле [[сейчас]] как «указательный палец» ясно.
Индексальный (указательный палец) субъективен, как и Событийный
[[I]], [[здесь]], [[сейчас]] и т. Д. Субъективны, и опять же, в программировании единственная связь между неизменной объективной вселенной и нашим изменчивым субъективным опытом - это «событие» или «событие» управляемое общество»
Поэтому, пока [[сейчас]] привязан к объявлению события «управляемого событиями» программирования, я думаю, что субъективная (зависящая от контекста) математическая несогласованность никогда не возникает.
Edit5
@ Берги дал мне отличный комментарий:
Да,Date.now
, внешнее значение, является ссылочно прозрачным. Это всегда означает «текущее время».
НоDate.now()
это не так, это вызов функции, возвращающий разные номера в зависимости от внешнего состояния. Проблема с относительно прозрачной «концепцией текущего времени» состоит в том, что мы не можем ничего с ней вычислить.
@KenOKABE: похоже, тот же случай, что иDate.now()
, Проблема в том, что это не означает текущее время в одно и то же время, но в разное время - программе требуется время для выполнения, и именно это делает ее нечистой.
Конечно, мы могли бы разработать референсную прозрачностьDate.now
функция / получатель, которая всегда возвращает время начала программы (как если бы выполнение программы было немедленным), но это не такDate.now()/Date.Now
Работа. Они зависят от состояния выполнения программы. - Берги
Я думаю, что мы должны обсудить это.
Date.now
, внешнее значение, является ссылочно прозрачным.
[[Date.now]], как я упоминаю в # Edit4, является индексным (указательный палец), который является субъективным, но до тех пор, пока он остается в индексной области (без выполнения / оценки), он прозрачен по ссылкам, что мы договорились.
Тем не менее, @ Берги предлагаетDate.now()
(с выполнением / оценкой) возвращает «разные значения» в разное время, и это больше не является ссылочно прозрачным. С этим мы не договорились.
Я думаю, что эта проблема, которую он показал, конечно, но существует только в императивном программировании:
console.log(Date.now()); //some numeric for 2016/05/18 xx:xx:xx ....
console.log(Date.now()); //different numeric for 2016/05/18 xx:xx:xx ....
В этом случае,Date.now()
Я не согласен с этим.
Однако в парадигме функционального программирования / декларативного программирования мы никогда не будем писать так, как описано выше. Мы должны написать это:
const f = () => (Date.now());
и этоf
оценивается в некотором «управляемом событиями» контексте, Так ведет себя функционально-программный код.
Да,этот код идентичен
const f = Date.now;
Поэтому в парадигме функционального программирования / декларативного программированияDate.now
или жеDate.now()
(с выполнением / оценкой) никогда не возникает проблем с возвратом «разных значений» в разное время.
Итак, опять же, как я уже упоминал вEDIT4До тех пор, пока [[now]] привязано к объявлению события «Управляемого событиями» программирования, я думаю, что субъективная (зависящая от контекста) математическая несогласованность никогда не возникает.