2016-06-04 2 views
2

나는 비약을 배우고 난 현재 캡처 및 기능의 일부 응용 프로그램의 의미를 처리하고 있습니다.
저는 이미 fn(x)-> x + 1 end 구문에 익숙합니다.비약 익명 함수, 캡처 및 일부 응용 프로그램

저는 놀라운 행동을 생각했습니다. 나는 즉시 익명 함수 &(&1 <> "-X")를 "다시"라는 의미로 해석 할

f = &(&1 <> "-X") 
# #Function<6.50752066/1 in :erl_eval.expr/5> 

is_function f 
# true 

is_function &(&1 <> "-X") 
# true 

f == &(&1 <> "-X") 
# false 

가 동일하지 않은 값을하는 값을 반환 예를 들어,이 조각의 마지막 표현이 false 반환하는 것을 관찰했습니다 == 의미에 따라) f에 저장됩니다.

잘 될 것이고,이 다른 조각 내 이론을 확인합니다 : 때문에이

g = &(String.upcase(&1)) 
# &String.upcase/1 

is_function g 
# true 

is_function &(String.upcase(&1)) 
# true 

g == &(String.upcase(&1)) 
# true 

g가 다시 익명 함수와 동일 할을 - 어쩌면 - 기존라는 이름의 기능을 캡처하는 것은 컴파일러에 의해 최적화하고, 매번 동일한 값이 리턴됩니다. 두 번째 스 니펫에있는 첫 번째 줄의 반환 값은 두 경우가 다르게 취급된다는 아이디어를 확인하는 것으로 보입니다.

f = &(&1 <> "-X") 
z = &(f.(&1)) 
#Function<6.50752066/1 in :erl_eval.expr/5> 

z == &(f.(&1)) 
# false 

마지막 문이 다시 false입니다

나는 그때는 이미 존재임을 의미하는 "알려진"기능을 시도했다. 모두 이미 존재하기 때문에
이 나는, &(f.(&1))&(String.upcase(&1)) 유사한 방식으로 처리 될 것으로 예상했을 것이다.

는 다음 기능을 캡처의 의미 무엇입니까?

답변

5

당신은 명명 된 기능을 캡처하는 최적화되어 있다는 사실에 대한 권리이며, 따라서 같은 값을 매번 반환합니다.

은 또한 아래로 나는 "MFA"에 의해 함수의 함수 및 인수에 대응을 종종 "funs입니다"에 의해 익명 함수를 참조거야, 그리고 모듈에.

잘 알려진 익명의 기능이 최적화가 어떻게 작동하는지와 관련이 캡처 할 때 더 평등이없는 이유는 사실. 전체 익명 함수를 저장하는 대신 이름이 지정된 함수에서 재미를 만들 때 컴파일러는 모듈 이름, 함수 이름 및 명명 된 함수의 속성을 저장합니다. 익명의 기능을 "다시 캡처"하는 것은 불가능합니다. 매번 새로운 재미를 만들어야합니다.

면책 조항 :이 분석은 컴파일러에 대한 깊은 지식을 기반으로하지는 않지만 http://erlang.org/doc/apps/erts/erl_ext_dist.html에 설명 된 외부 용어 형식 (:erlang.term_to_binary/1을 호출 한 결과)을 잘 알고 있어야합니다.

ETF에 익명 함수에 대한 두 가지 종류가 있습니다 :

  • FUN_EXT/NEW_FUN_EXT - 일반적으로 익명 함수를 인코딩. 이것은 기본적으로 특정 모듈 (fun가 정의 된 모듈) fun table에 대한 참조를 인코딩합니다.
  • EXPORT_EXT - 모듈 이름, 함수 이름 및 형식의 형식으로 명명 된 함수에서 익명 함수를 인코딩합니다.

익명 함수가 구현되는 방법에 대한 통찰력을 제공합니다. 각 모듈에는 내부에서 발생하는 모든 익명 함수 테이블이 있습니다. 나는 컴파일러가 그러한 테이블을 만들기 위해 일종의 람다 리프팅을하고 있다고 의심한다. 명명 된 함수에서 생성 된 재미는 mfa처럼 다르게 인코딩되며 fun 테이블에는 저장되지 않습니다.