Выражение — кусок кода, который может быть вычислен для производства одного какого-то значения (терма). То же: expression.
Наша программа может состоять из одного или нескольких модулей. Модуль включает в себя одну или несколько функций, функция — одну или несколько кляуз, кляуза — одно или несколько выражений. В пунктуации Эрланга выражению отводится запятая, то есть несколько выражений в кляузе разделяются между собой запятыми.
-module(test).
-export([loop/1]).
loop(X) ->
io:format("~p~n", [X]), % Выражение 1
Y = math:sin(1/X) + math:cos(1/X), % Выражение 2
Z = math:pow(X, Y), % Выражение 3
loop(Z). % Выражение 4
В данном примере, который выводит бесконечную череду бессмысленных чисел, функция loop/1 на вход получает какое-нибудь число. Функция состоит из одной кляузы. Кляуза — из четырёх выражений, разделённых между собой запятыми. Последнее выражение заканчивается точкой, потому что здесь заканчивается не только кляуза, но и функция в целом.
Валидное выражение всегда вычисляется в тот или иной конкретный терм.
Выражения, возвращающие лишь атомы true или false, называются логическми выражениями. Они применяются, например, в обработчике списка.
Практиковаться в выражениях удобно в оболочке. Она воспринимает каждое выражение с последующей точкой как команду: рассчитай, дескать, это выражение и выведи получившееся значение.
Несколько выражений для удобства можно объединить в блочное выражение.
Некоторые выражения могут вычисляться очень долго. Возможно, их стоит обернуть в какую-нибудь функцию или фунтерм, чтобы заспаунить актора, чтобы это выражение вычислялось параллельно.
Есть специальный вид выражения — регулярные выражения.
Если выражение не может быть вычислено, возникает исключительная ситуация. Например, выражение 5 and 7
не может быть вычислено, потому что булев оператор and может работать только с булевыми значениями.
Выражения используются не только как части кляуз, но и в других местах. Например, выражение может быть в гарде.
proba(X,Y) when (X*X + X*Y - 100) > 0 ->
io:format("> 0 ~n");
proba(_,_) -> io:format("=< 0 ~n").
Здесь первая кляуза содержит гарду when ...
. В ней есть выражение (X*X + X*Y - 100) > 0
. Это булево выражение, потому что оно вычисляется в true или false. В этом выражении далеко не все функции можно использовать. Например, если вставим math:sin/1, это вызовет ошибку illegal guard expression
. Тем не менее это тоже выражение.
Пример, где выражение X+Y
находится в конструкции оператора case (конечно, здесь можно было бы обойтись и без case ... end
):
proba(X,Y) ->
case X+Y of
Z when Z>0 -> io:format(">0 ~n");
Z when Z<0 -> io:format("<0 ~n")
end.
У каждого выражения может быть вычислено значение (если, конечно, не будет вызвано исключение). Если мы видим в коде какой-нибудь литерал, например 777
или "привет"
, это тоже выражения. У выражения 777
значение 777. У выражения "привет"
значение [1087,1088,1080,1074,1077,1090]. Когда мы видим выражение io:format("")
, оно тоже вычисляет значение, и это значение атом ok. Выражение <<1,2,3>>
вычисляется в соответствующий бинарник.
В Эрланге нет оператора return, дабы не плодить разных неожиданных побочных эффектов. Функция всегда возвращает значение последнего в кляузе выражения.
-module(test).
-export([main/1]).
main(Input) ->
Phrase = proba(Input),
io:format("Phrase of the day is: ~p.~n",[Phrase]).
proba(plus) ->
A=5,
B=7,
C=A+B,
"hello" ++ "world";
proba(minus) ->
A=13,
B=21,
C=A+B,
"hello" -- "world";
proba(_) -> ":-)".
В кляузы функции proba/1 мы специально добавили по три строчки бессмысленного кода, чтобы подчеркнуть, что возвращается именно значение последнего выражения. Компилятор, кстати, предупредит нас о том, что переменная C ни на что не влияет (не используется).
1> test:main("Привет").
Phrase of the day is: ":-)".
ok
2> test:main(plus).
Phrase of the day is: "helloworld".
ok
3> test:main(minus).
Phrase of the day is: "hel".
ok
© Алексей Карманов, 2024.