LINUX.ORG.RU

Erlang: and(andalso) и or(orelse) - что-то тут не так


0

0

Всем привет.

Собственно не пойму, что происходит (erlang shell):

F = fun(X) when (X == 0) orelse (X / 0 > 2) -> true; (_) -> false end.
F(0).
true

вроде нормально, short circuit работает. То же самое, если заменить orelse на ';':

f().
F = fun(X) when (X == 0) ; (X / 0 > 2) -> true; (_) -> false end.
F(0).
true

Получается, что orelse и ';' есть одно и то же. Ладно, теперь попробуем or, который вроде как не short circuit:

f().
F = fun(X) when (X == 0) or (X / 0 > 2) -> true; (_) -> false end.
F(0).
false

Неожиданно. А где ошибка, почему false? То же самое с andalso/,/and.

Объясните плиз, кто понимает, что здесь происходит, зачем столько синонимов (andalso и ',', orelse и ';') и почему нету никакой ошибки с or?

★★★★

Если используешь or, то паттерн матчинг используется с применением обоих проверочных выражений, а выражение (X / 0 > 2) является вообще ошибочным, поэтому и false.

orelse использует первое выражение, и если оно неверно, то второе.

; - краткая форма записи для orelse

anonymous
()
Ответ на: комментарий от anonymous

> а выражение (X / 0 > 2) является вообще ошибочным, поэтому и false.

А что в нём ошибочного? Должна же вылететь какая-нибудь арифметическая ошибка, и в книге Армстронга про это написано, а здесь всё просто сглатывается.

Bohtvaroh ★★★★
() автор топика
Ответ на: комментарий от anonymous

> Выражение (0 / 0 > 2) возвращает true?

1> (0/0 > 2).
** exception error: bad argument in an arithmetic expression
     in operator  '/'/2
        called as 0 / 0

Вот у меня так. :) То есть получается, что в гвардах исключения сглатываются? А с чем это связано? С отсутствием side-effects?

> BTW, join erlang@conference.jabber.ru

Гут.

Bohtvaroh ★★★★
() автор топика

Подводя итоги:

F1 = fun() when 1/0; true -> true; () -> false end.
F1().
true

- здесь гвард (1/0) fails (исключение в гварде равносильно тому, что он проваливается) и проверяется следующий, результат true.

F2 = fun() when 1/0 orelse true -> true; () -> false end.
F2().
false

- здесь в гварде (1/0 orelse true) возникает исключение, он не выполняется, и результат false.
Это ключевое различие guard sequences и or/orelse.

F2 = fun() when 1/0 or true -> true; () -> false end.
F2().
false

- аналогично предыдущему.

F4 = fun() when true; 1/0 -> true; () -> false end.
F4().
true

- аналогично F1.

F5 = fun() when true orelse 1/0 -> true; () -> false end.
F5().
true

- у orelse определена последовательность выполнения и он short-circuit, поэтому true.

F6 = fun() when true or 1/0 -> true; () -> false end.
F6().
false

- у or не определена последовательно выполнения и он не short-circuit, поэтому false.

Bohtvaroh ★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.