Elixir 프로그래머는 아니지만, 마지막 예제에서 가장 놀라운 건 가드 표현식의 오류가 호출자에게 전파되지 않고 그 가드가 “건너뛰어진다”는 점임
왜 그렇게 만들었는지는 알 것 같지만, 직관에 어긋나는 결과가 나오는 것도 놀랍지 않음
Erlang의 API 설계가 Armstrong의 Erlang thesis p109/s4.5에서 말한 의도적 프로그래밍을 돕기 위한 것이었다는 점을 생각하면 아이러니함
논문에서는 dict:fetch(Key, Dict), dict:search(Key, Dict), dict:is_key(Key, Dict)처럼 프로그래머가 “키가 반드시 있어야 한다”, “있을 수도 있으니 흐름을 나눈다”, “존재 여부만 검사한다”는 의도를 드러내는 함수들을 나눠 설명함
그런데 Elixir의 is_map_key/2는 “dict” 인자가 dict가 아니면 예외를 내고, 그 예외 실패가 전체 가드 절 실패로 이어져 이 구분을 깨는 것처럼 보임
반대로 or가 예외를 잡아 false로 합치는 언어가 있다면 다른 경우에는 더 놀라울 것 같기도 함
배운 건 있었지만, 왜 Pratchett 참조를 피했는지 아쉬움
Death가 어디선가 이마를 짚고 있을 듯함
여기서 흥미로운 점은 두 가지인데, false가 아니라 실패한 가드는 전체 표현식을 실패하게 만들고, 다소 직관과 다르게 is_map_key가 is_map 검사를 내포하지 않는다는 것임 is_map(x) and is_map_key(x, :corporal)처럼 세 번째 변형을 추가하면 기대한 대로 동작함 is_map_key의 동작은 조금 일관성이 없어 보이고 그래서 놀랍게 느껴지며, 다른 is_... 가드들도 어떤 것은 안전하고 어떤 것은 타입 기대를 깔고 평가해야 하는지 확인해 보면 흥미로울 듯함
Pratchett 참조에는 동의하지만, 지금 폭염이라 뇌가 기대한 대로 동작하지 않음
궁금해서 몇 가지를 직접 확인해 봤는데, 대략 보기로는 is_map_key가 특정 종류의 인자를 요구하는 유일한 is_ 가드인 것 같음
다른 is_ 함수들은 불리언 성격을 내포하고 항상 true | false를 반환하며 실패하지 않음
여기서 흥미로운 Elixir 스타일 질문이 생김
예제는 재미있고 설명도 잘 되지만, 개인적으로는 가능하면 가드보다 패턴 매칭을 선호함
물론 예외는 있지만, 이런 함수들은 보통 def a(%{foo: x}), do: true, def a(x) when is_integer(x), do: true, def a(), do: false 같은 여러 함수 절로 썼을 것 같음