Выражение

Выражение — кусок кода, который может быть вычислен для производства одного какого-то значения (терма). То же: 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.