Пунктуация

Пунктуация — то, с помощью чего в Эрланге код делится на функции, кляузы, выражения.

В конце каждой функции ставится точка. Точками заканчиваются также инструкции для компилятора (например, -module()) . Поэтому код модуля в целом в общем случае выглядит так:

Инструкция 1.
Инструкция 2.
Функция 1.
Функция 2.
Функция 3.

Функция может состоять из одной или нескольких кляуз. Если кляуз больше одной, они между собой разделяются точкой с запятой. Вот так выглядит функция в общем случае:

Кляуза 1;
Кляуза 2;
Кляуза 3.

Кляуза может состоять из нескольких выражений. Если это так, то выражения между собой разделяются запятыми. Вот так кляуза выглядит в общем случае:

Паттерн Гарда ->
    Выражение 1,
    Выражение 2,
    Выражение 3; 

Если Выражение 3 — последнее во всей функции, то оно завершается точкой.

Однако выражение тоже может быть весьма сложным. Оно может включать в себя блоки if ... end или case ... end. А внутри этих блоков тоже могут быть свои кляузы. Эти кляузы тоже разделяются между собой точками с запятой.

if
    Кляуза 1;
    Кляуза 2;
    Кляуза 3
end, 
case Выражение of
    Кляуза 1;
    Кляуза 2;
    Кляуза 3
end, 

Обратите внимание, что после последних кляуз точка с запятой не ставится.

В оболочке точки имеют свой смысл. Чтобы вывести значение какого-либо выражения, мы после него ставим точку. Таким образом получается что-то вроде команды.

Пример с пунктуацией

-module(primer).        % Инструкция 1
-compile(export_all).   % Инструкция 2

% Функция 1
vremya() -> io:format("~p~n",[time()]). 

% Функция 2
znak(X) when X > 0 -> io:format("~p > 0~n", [X]);   % Кляуза 1
znak(X) when X < 0 -> io:format("~p < 0~n", [X]);   % Кляуза 2
znak(X) -> io:format("Perhaps ~p is 0.~n", [X]).    % Кляуза 3

% Функция 3
deluxe(Y) when is_atom(Y) ->                        % Кляуза 1
    io:format("~p is atom.~n", [Y]),                    % Выражение 1
    io:format("Today is ~p.~n", [date()]),              % Выражение 2
    io:format("I got ~p at ~p.~n", [Y, time()]);        % Выражение 3
deluxe(Y) when is_number(Y) ->                      % Кляуза 2
    io:format("~p is number.~n", [Y]),                  % Выражение 1
    Z = math:sin(Y),                                    % Выражение 2
    if                                                  % Выражение 3
        Z > 0 -> io:format("sin(~p) > 0~n", [Y]);           % if-кляуза 1
        Z < 0 -> io:format("sin(~p) < 0~n", [Y]);           % if-кляуза 2
        true -> io:format("sin(~p) == 0~n", [Y])            % if-кляуза 3
    end,
    case Y rem 3 of                                     % Выражение 4
        0 -> io:format("null~n");                           % case-кляуза 1
        1 -> io:format("one~n");                            % case-кляуза 2
        2 -> io:format("two~n")                             % case-кляуза 3
    end, 
    io:format("This is the end.~n");                    % Выражение 5
deluxe(Y) ->                                        % Кляуза 3
    io:format("~p is strange.~n", [Y]).                 % Выражение 1

Как мы видим, наш модуль primer включает три функции. Первая — выводит текущее время. Вторая, получая аргумент, определяет, он больше нуля или меньше. Третья функция ведёт себя по-разному. Если она в качестве аргумента получает атом, то радуется этому. Если получает число, то сообщает, больше ли синус этого числа нуля или меньше, а также говорит, какой остаток от деления на 3. Получив что-то другое (не атом и не число), функция deluxe/1 этому удивляется.


© Алексей Карманов, 2024.