Search
Write a publication
Pull to refresh

Comments 22

Чистые функции не используют переменные из внешней области видимости.

Неправда ваша. Ничего не мешает чистой функции использовать переменную из внешней области видимости если та никогда не меняется.

а если другая «грязная» фнукция поменяла значение этой переменной, то результатт «чистой» поменяется, что испачкает функцию
Ничего не мешает чистой функции использовать переменную из внешней области видимости если та никогда не меняется.
глаз зацепился за «переменную» :-)
Тогда это константа. Если переменная может меняться хотя бы теоретически — гарантировать чистоту функции уже нельзя.

Константа — это переменная, которая объявлена с ключевым словом const (еще иногда константой называют свойство объекта с параметрами десткриптора { writable: false, configurable: false }).


А для того чтобы переменная не менялась — достаточно того чтобы в программе не было оператора присваивания где она находится слева.

Хорошо, зайду с другой стороны. Рассмотрим простейший код с двумя функциями:


const add = x => y => x+y;

Несколько вопросов:


  1. Является ли параметр x константой?
  2. Может ли параметр x меняться теоретически?
  3. Может ли параметр x меняться практически?
  4. Является ли вложенная функция y => x+y чистой?

Еще веселый пример:


for (let i=0; i<5; i++) {
    foo(x => x+i);
}

Является ли переменная i константой? Является ли функция x => x+i чистой?

Нет и нет. А что, тут есть какие-то сомнения? Если i теоретически может быть переопределена в контексте внешнего цикла — ни о какой чистоте не может быть речи. Если передать i как аргумент — все будет чисто. Результат работы "чистой" функции может зависеть ТОЛЬКО от переданных в нее аргументов, непосредственно.

Почему вы теоретически рассматриваете возможность появления новой строки кода снаружи функции — но не рассматриваете возможности появления таковой строки внутри?


Эдак можно про любую функцию сказать "Пока существует теоретическая возможность добавления нечистых операторов в функцию — она не может считаться чистой!" :-)


Чистота функции — это свойство конкретной функции в конкретном коде.

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

Вы так говорите как будто внешний и внутренний код два разных человека пишут…

В любом случае, у термина «чистая функция» есть определение, и там ничего не сказано про код и гарантии, только про наблюдаемое поведение.
Вы так говорите как будто внешний и внутренний код два разных человека пишут…

Вы никогда не участвовали в командной разработке? Тогда понятно.


В любом случае, у термина «чистая функция» есть определение, и там ничего не сказано про код и гарантии, только про наблюдаемое поведение.

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

Рассмотрим снова код const add = x => y => x+y;. Какие два разных человека его писали?


Все там сказано.

Там сказано следующее: чистая функция — это детерминированная функция без побочных эффектов. Детерминированная функция — это функция, которая всегда возвращает одинаковое значения для одинаковых входных параметров.


Так вот: функция add(5) детерминирована, независимо от того нравится вам это или нет.

Я не очень понимаю что именно вы пытаетесь проиллюстрировать своим примером. Ваша функция add вернет грязную функцию, потому, что возьмет значение x из контекста add и будет зависеть от. Если вы вернете не стрелочную функцию — она также будет грязной, так как будет искать значение "x" в контексте своего вызова. Саму функцию add — можно с натяжкой назвать чистой, потому при одинаковом "x" будет возвращать функцию выполняющую то-же действие, но по сути это будут разные объекты, тут уже всплывает специфика языка и то, что вы назовете "детерминированным" в контексте вашей задачи. По сути, никакого концептуального отношения к рассматриваемому вопросу тут нет вообще, вы приводите извращенные примеры и пытаетесь заставить кого-то с ними разбираться, а на практике — вам просто по рукам надают за такой код.

Вот только функция add — чистая. Это же всего лишь каррированный оператор сложения. А операция каррирования чистоту функции не меняет.

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

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

По сути же ваших рассуждений:


Ваша функция add вернет грязную функцию, потому, что возьмет значение x из контекста add и будет зависеть от.

Обоснуйте. Рассмотрим, для определенности, функцию const f = add(5).


Приведите контрпример к утверждению "f — чистая функция". Попробуйте найти сценарий, при котором функция f, вызванная с одним и тем же аргументом, вернет два разных значения.

А теперь еще разок перечитайте то, что сами процитировали. Хотя не нужно, не вижу больше смысла переубеждать вас.

Кстати, не могли бы вы привести пример чистой функции из реального проекта, которая никак не зависит от окружения?
UFO landed and left these words here
Стоит так же добавить, что замыкания это основная концепция для создания модулей. Ну по крайней мере до появления import/export.

Меня всегда удивляло то, почему такая "ежу понятная" вещь требует каких-то особых разъяснений. Статьи вот люди пишут… Я бы даже название отдельное не придумывал, понятия "область видимости" вполне достаточно.

Sign up to leave a comment.

Articles