익명 함수 속기


85

짧은 표기법 # (..)을 사용하는 익명 함수에 대해 이해할 수없는 것이 있습니다.

다음 작업 :

REPL>  ((fn [s] s) "Eh")
"Eh"

그러나 이것은 그렇지 않습니다.

REPL>  (#(%) "Eh")

이것은 작동합니다 :

REPL> (#(str %) "Eh")
"Eh"

내가 이해하지 못하는 것은 (# (%) "Eh") 가 작동하지 않는 이유 이며 동시에 ((fn [s] s) "Eh") 에서 str 을 사용할 필요가 없다는 것입니다.

둘 다 익명 함수이고 둘 다 여기서 하나의 매개 변수를 사용합니다. 속기 표기법에는 함수가 필요한데 다른 표기법에는 왜 필요하지 않습니까?

답변:


126
#(...)

~의 속기

(fn [arg1 arg2 ...] (...))

(여기서 argN의 수는 본문에있는 % N의 수에 따라 다릅니다). 그래서 당신이 쓸 때 :

#(%)

다음으로 번역됩니다.

(fn [arg1] (arg1))

이것은 다음과 같은 첫 번째 익명 함수와 다릅니다.

(fn [arg1] arg1)

귀하의 버전은 arg1을 값으로 반환하고 속기 확장에서 나온 버전은이를 함수로 호출하려고합니다. 문자열이 유효한 함수가 아니기 때문에 오류가 발생합니다.

속기는 본문 주위에 괄호 집합을 제공하므로 단일 함수 호출 또는 특수 형식을 실행하는 데만 사용할 수 있습니다.


64

다른 답변이 이미 매우 잘 지적한 것처럼, #(%)당신이 실제로 게시는 같은으로 확장 (fn [arg1] (arg1))전혀 동일하지 않습니다, (fn [arg1] arg1).

@John Flatness는을 사용할 수 있다고 지적 identity했지만 dispatch 매크로를 identity사용하여 작성하는 방법을 찾고 있다면 다음 #(...)과 같이 할 수 있습니다.

#(-> %)

#(...)디스패치 매크로를 ->스레딩 매크로와 결합하면 다음과 같이 확장됩니다.(fn [arg1] (-> arg1)) 다시 확장, (fn [arg1] arg1)단지 당신이 원하는 원하는이다. 또한 ->#(...)매크로 콤보는 벡터를 반환하는 간단한 함수를 작성하는 데 유용합니다. 예 :

#(-> [%2 %1])

20

당신이 사용하는 경우 #(...), 당신은 당신이 대신 작성하고 상상할 수있는 (fn [args] (...)), 포함 바로 파운드 후에 시작 괄호.

따라서 작동하지 않는 예제는 다음과 같이 변환됩니다.

((fn [s] (s)) "Eh")

당신이 문자열 "Eh" 를 부르고 있기 때문에 분명히 작동하지 않습니다 . 귀하의 예를 str작품 때문에 지금 기능입니다 (str s)대신 (s).(identity s)str로 강요하지 않기 때문에 첫 번째 예와 더 가까운 아날로그가 될 것입니다.

이 최소한의 예제를 제외하고 모든 익명 함수가 무언가 를 호출 것이기 때문에 생각해 보면 의미가 있습니다. 따라서 실제로 호출하기 위해 또 다른 중첩 된 괄호 집합을 요구하는 것은 약간 어리석은 일입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.