엘릭서(Elixir) 언어에서 `or` 조건문을 포함하는 가드(guard)의 순서에 따라 코드 실행 결과가 예상치 못하게 달라질 수 있다는 점이 개발자들 사이에서 논의되고 있습니다. 이는 불리언 연산의 교환법칙이 깨진 것처럼 보일 수 있지만, 실제로는 단락 평가(short-circuit evaluation)와 특정 내장 함수의 동작 방식 때문에 발생하는 현상입니다.
예를 들어, `is_integer(x) or is_map_key(x, :foo)`와 `is_map_key(x, :foo) or is_integer(x)`는 논리적으로 동일해 보이지만, `x`가 정수일 때 다른 결과를 낳습니다. 첫 번째 경우, `x`가 정수면 `is_integer(x)`가 `true`를 반환하고 `or` 연산의 단락 평가에 따라 뒤의 `is_map_key(x, :foo)`는 실행되지 않아 성공합니다. 하지만 두 번째 경우, `x`가 정수면 `is_map_key(x, :foo)`는 맵(map)이 아닌 인자를 받아 `false`를 반환하는 대신 예외를 발생시키고, 이 예외는 전체 가드 표현식을 실패하게 만들어 다음 절로 넘어가지 못하게 합니다. 엘릭서 1.20.1과 OTP 29 환경에서는 이러한 동작에 대한 별도의 경고가 없어 개발자가 인지하기 어렵습니다.
이러한 동작은 특히 `is_map_key/2`와 같은 특정 `is_` 계열 함수들이 인자의 타입을 엄격하게 검사하고, 유효하지 않은 타입에 대해 예외를 발생시키는 방식 때문에 두드러집니다. 대부분의 다른 `is_` 함수들은 항상 `true` 또는 `false`를 반환하며 예외를 발생시키지 않습니다. 따라서 개발자는 가드 내에서 `is_map_key/2`와 같은 함수를 사용할 때, 해당 함수가 예외를 발생시킬 수 있는 인자를 받지 않도록 `is_map(x) and is_map_key(x, :foo)`와 같이 추가적인 타입 검사를 먼저 수행하는 것이 안전합니다. 이 사례는 엘릭서 개발 시 가드 조건의 순서와 사용되는 함수의 특성을 면밀히 고려해야 함을 보여줍니다.