함수를 매개 변수로 사용하면 함수가 즉시 불완전합니까?


17

입력 매개 변수의 순도는 런타임까지 알려지지 않았으므로 함수를 입력 매개 변수로 사용하는 경우 즉시 함수가 불완전한 것으로 간주됩니까?

관련 : 함수가 함수 외부에 정의되어 있지만 매개 변수로 전달되지 않은 순수한 함수를 적용하는 경우 부작용이없고 출력이 입력에만 의존하는 기준을 충족하더라도 여전히 순수합니까?

상황에 따라 JavaScript로 기능 코드를 작성하고 있습니다.


사소한 반대 사례로 다음을 고려하십시오.foo = function(function bar){ print(bar.toString()) }
David는 Reinstate Monica가

1
@DavidGrinberg 이것은 반대의 사례가 아니며 실제로 더 큰 문제를 강조합니다. 재정의 할 수있는 함수가 있고 구현에 부작용이 없음을 보장 할 수없는 경우 객체를 가져 와서 메서드를 호출하는 대부분의 함수가 순수하다는 것을 보장 할 수는 없습니다. 아마도 bar의 toString ()은 디스크에서 일부 파일을 삭제합니까?
Joshua Taylor

3
@DavidGrinberg 그러나 나는 당신이 좋은 방향으로 생각하고 있다고 생각합니다. foo = function(function bar) { return 3; } 입니다 순수, 인수로서 기능을한다.
Joshua Taylor

@JoshuaTaylor 페어 포인트, 나는 그것을 생각하지 않았다. 그러나 이미 본질적으로 문제를 해결했습니다. 대안으로 'root' toString()(즉, Java의 Object에서 찾을 수있는)를 호출하십시오 .
David는 Reinstate Monica가

답변:


22

함수에 사용 된 모든 값이 매개 변수에 의해서만 정의되는 한 순수한 함수입니다.

동일한 입력에 대해 매번 출력이 동일한 패싯은 매개 변수가 순수한지 여부에 의해 제어됩니다. 함수 인수와 같은 매개 변수도 순수하다고 가정하면 순수합니다.

순도가 적용되지 않는 Javascript와 같은 언어에서 이는 매개 변수로 전달 된 불완전한 함수를 호출하여 순수한 함수가 불완전한 동작을 수행 할 수 있음을 의미합니다.

이는 순도를 거의 적용하지 않는 언어 (즉, 거의 모든 언어)의 경우 인수로 전달 된 함수를 호출하는 순수한 함수를 정의 할 수 없음을 효과적으로 의미합니다. 가능한 한 순수하게 작성하고 순수 함수로 추론하는 것이 여전히 유용하지만 잘못된 인수를 전달하면 순수하다는 가정이 깨지기 때문에주의를 기울여야합니다.

실제로 경험상 이것은 일반적으로 큰 문제가 아닙니다. 불순한 함수를 순수한 함수의 함수 인수로 사용하는 경우는 드 find니다.


"함수에 사용 된 모든 값이 매개 변수에 의해서만 정의되는 한, 순수한 함수입니다"라는 문장에 대해. 상수의 경우 어떻게됩니까? 내가하는 기능이있는 경우 areaOfCircle r => Math.Pi * r * r, 할 areaOfCircle그냥 매개 변수를 비 순수 사용하지 않는?
David Arno

2
@DavidArno 이건 공정한 포인트입니다. 참조 투명성에 따르면 정적 외부 값을 참조하는 것은 하드 코딩 된 것과 다르지 않으므로 여전히 순수합니다.
Daenyth

1
"이것은 순수한 함수가 불완전한 행동을 할 수 있다는 것을 의미합니다"-정의에 따르면 순수한 함수는 불완전한 행동을 가질 수 없습니다. f(f2)호출 하는 함수 가 f2의존하는 것에 전적으로 의존하지 않는다고 생각하는 실수를 저지르고 f2있습니다. 임의의 전달 함수를 호출 할 수있는 함수는 순수하지 않습니다.
user2357112는 Monica

2
@Daenyth : 더 좋지만 여전히 함수가 전달 된 함수를 호출해야한다고 가정합니다. 이 같은 수 있습니다 function compose(f, g) {return function h(x) {return f(g(x));};}인수로 기능을 복용에도 불구하고 순수하다.
user2357112는

1
"불순한 함수를 순수한 함수의 함수 인수로 사용하는 것은 드물다." -기능적 언어는 아니지만 특정 C ++ 라이브러리 함수에는 인수를 선언해야한다는 특정 경고가 있습니다 (일부 근사치). 어떤 의미에서 이것은 드문 일이 아니라 실제로는 결코 일어나지 않는다는 것을 의미합니다. 그러나 다른 의미에서 그들이 금지해야하는 사실은 사람들이 때때로 그것을 하기 때문입니다. 예를 들어, 그들은 find일치하는 세 번째 일치 항목에 대해 "true"를 반환하는 불순한 술어 를 전달하려고합니다 .
Steve Jessop

19

입력 매개 변수의 순도는 런타임까지 알려지지 않았으므로 함수를 입력 매개 변수로 사용하는 경우 즉시 함수가 불완전한 것으로 간주됩니까?

아니요. 예 :

function pure(other_function) {
    return 1;
}

other_function순수한 함수 인지 불순한 함수 인지 여부 는 중요하지 않습니다 . pure기능은 순수하다.

다른 반례 :

function identity(x) {
    return x;
}

이 기능은 x불순한 기능 이더라도 순수합니다. 전화를 몇 번이나 반복하더라도 identity(impure_function)항상을 반환 impure_function합니다. identity(impure_function)()항상 같은 것을 반환 하는지 여부 는 중요하지 않습니다 . 함수의 반환 값의 반환 값 은 순도에 영향을 미치지 않습니다.


일반적으로 함수가 함수를 호출 할 수있는 경우 인수로 전달되었으므로 순수하지 않습니다. 예를 들어, 함수 function call(f) {f();}는 전역 또는 변경 가능한 상태에 대해 언급하지 않아도 부작용이 f발생할 수 있으므로 순수하지 않습니다 alert.

함수가 함수를 인수로 사용하지만이를 호출하거나 호출하지 않으면 순수 할 수 있습니다. 다른 불순한 일을해도 여전히 불순 할 수 있습니다. 예를 들어 function f(ignored_function) {alert('This isn't pure.');}호출하지 않아도 불순합니다 ignored_function.


4
이 반응은 지나치게 과장된 것처럼 보입니다. 우리는 문제가 호출되는 함수 매개 변수에 관한 것이라는 질문에서 유추 할 수 있습니다. 다른 함수를 호출하지 않고 매개 변수로 사용할 수있는 함수의 존재는이 질문에 영향을 미치지 않습니다.
walpen

13
@ 왈펜 : 질문은 논쟁을 불러 일으키는 것에 대해 언급하지 않습니다. 질문자가 함수가 호출하지 않고 다른 함수를 입력으로 사용할 수 있다는 것을 깨달았다 고 생각할 이유가 없습니다. 당신이 가정한다고 가정하기보다는 이와 같은 숨겨진 가정을 지적하는 것이 중요합니다.
user2357112는

12

입력 매개 변수의 순도는 런타임까지 알려지지 않았으므로 함수를 입력 매개 변수로 사용하는 경우 즉시 함수가 불완전한 것으로 간주됩니까?

기술적으로, 입력 기능도 순수하다는 것을 보장 할 수있는 언어가 없다면 말입니다.

함수가 함수 외부에 정의되어 있지만 매개 변수로 전달되지 않은 순수한 함수를 적용하는 경우 부작용이없는 기준을 충족하고 출력이 입력에만 의존하는 경우에도 여전히 순수합니까?

예. 여기서 중요한 것에 집중합시다. 함수를 순수하게 호출하는 것은 그 자체로는 유용하지 않습니다. 순수한 함수는 상태에 의존하지 않거나 부작용이없는 입력에 대해 동일한 출력을 생성하는 것이 매우 유용한 특성 세트이므로 유용합니다. 함수가 실행되면 해당 입력에 대한 답변을 "기억"할 수 있으며 항상 참임을 의미합니다. 또한 부작용을 발생시키기 위해 기능을 다시 실행할 필요가 없습니다. 또한 해당 기능을 다른 기능과 병렬로 (또는 순서대로) 실행할 수 있으며 기능이 제대로 작동하지 않는 숨겨진 상호 작용이 없음을 알 수 있습니다.

함수가 참조하는 방법에 관계없이 함수가 다른 순수 읽기 전용 함수를 사용하여 작업을 수행하는 경우에도 유용한 특성이 유지됩니다.


5

Telastyn이 말했듯이 : 기술적으로는 입력 기능도 순수하다는 것을 보장 할 수있는 방법이 없다면 말입니다.

그것은 가설이 아니며 실제로 이것을 보장하는 좋은 방법이 있습니다. 최소한 강력한 형식의 언어로되어 있어야합니다.

JavaScript에서 쓸 수있는 순수한 함수는

function foo(f) {
   return f(1) + 2;
}

Haskell로 직접 번역 될 수 있습니다 :

foo :: (Int -> Int) -> Int
foo f = f 1 + 2

이제 JavaScript에서 다음과 같은 악의적 인 일을 할 수 있습니다

js> foo (function(x) {console.log("muharhar"); return 0})
muharhar
2

Haskell에서는 불가능합니다 . 이유 존재, 뭔가 부작용-FUL 같은 console.log()필수는 항상 결과 유형이 IO something아니라, something혼자.

GHCi> foo (\x -> print "muarhar" >> return 0)

<interactive>:7:12:
    Couldn't match expected type ‘Int’ with actual type ‘IO b0’
    In the expression: print "muarhar" >> return 0
    In the first argument of ‘foo’, namely
      ‘(\ x -> print "muarhar" >> return 0)’
    In the expression: foo (\ x -> print "muarhar" >> return 0)

이 표현식을 타입 체크 foo하려면 타입 시그니처 를 제공해야합니다.

foo :: (Int -> IO Int) -> Int

그러나 그것은 더 이상 그것을 구현할 수 없다는 것이 밝혀졌습니다 : 인수 함수 IO의 결과로 인해에서 사용할 수 없습니다 foo.

<interactive>:8:44:
    Couldn't match expected type ‘Int’ with actual type ‘IO Int’
    In the first argument of ‘(+)’, namely ‘f 1’
    In the expression: f 1 + 2

내가 IO액션을 사용할 수있는 유일한 방법 foo은 결과 자체에 foo유형 이있는 경우 IO Int입니다.

foo :: (Int -> IO Int) -> IO Int
foo f = do
   f1 <- f 1
   return (f1 + 2)

그러나이 시점에서 그것이 foo순수한 기능이 아니라는 서명에서 분명 합니다.


1
"불가능하다"고 말하기 전에 unsafeIO:-)를 살펴보십시오.
Bergi

2
@ Bergi : 실제로 Haskell의 일부는 아니지만 외부 함수 인터페이스입니다. 다른 언어로 정의 된 함수 가 순수 하다는 것을 주장하기 위해 Haskell 컴파일러는 분명히 다른 언어에는 없기 때문에 유형 서명에서 유추 할 수 없습니다 같은 것 IO. 또한, "순수한"기능에서 부작용을 숨겨서 신체 상해를 유발하는 데 사용될 수도 있지만, 순수한 기능의 평가 순서를 지정하는 신뢰할 수있는 방법이 없기 때문에 Haskell에서는 실제로 안전하지 않습니다.
leftaroundabout

그래, 그건 사실이야. 그러나 나는 그것이 접근 방법의 안전성이 이전에 확립되어야했던 "순수한"기능에서 유익한 부작용 을 "숨기는"데 사용되는 것을 보았습니다 .
Bergi

@Bergi 당신은 주로 사용해서는 안됩니다 unsafeIO; 그것은 타입 시스템이 보장하는 마지막 단계 인 이스케이프 탈출 해치이므로 좋은 점은 아닙니다.
Andres F.

0

전혀 그렇지 않다.

전달 된 함수가 불완전하고 함수가 전달 된 함수를 호출하면 함수가 불완전한 것으로 간주됩니다.

순수 / 불순 관계는 JS의 sync / async와 약간 비슷합니다. 순수하지 않은 코드를 자유롭게 사용할 수 있지만 다른 방법으로는 사용할 수 없습니다.


이 답변은이 답변 에서 아직 설명 되지 않은 내용을 추가하지 않습니다 ... 일을 다시 시작하기 전에 이전 답변을 검토하십시오 :)
Andres F.

동기화 / 비동기 비유는 어떻습니까?
Bobby Marinoff 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.