Переменная

Переменная — имя, с которым связано некоторое конкретное значение (терм). То же: variable.

Переменные следует называть с заглавной латинской буквы. Если попробуем назвать с маленькой, то Эрланг это воспримет как атом. После заглавной буквы могут последовать любые другие буквы, как строчные, так и заглавные, а также цифры и знак подчёркивания. Myname и MYNAME — это две разные переменные:

1> Myname = "Alex".
"Alex"
2> MYNAME = "Alexei".
"Alexei"
3> Myname ++ MYNAME. 
"AlexAlexei"

Выражение вроде Myname = "Alex" называется сопоставлением. Именно в процессе сопоставления к переменным привязываются конкретные значения. До этого к переменной не было привязано ни одного значения. После привязывания какое-то новое значение к этой переменной уже не удастся привязать.

Переменные нужны для того, чтобы к ним привязывать значения — результат выражения. Если в других языках программирования переменные похожи на коробки, в которых мы сохраняем значения и в которых эти значения можем поменять, в Эрланге переменные лучше мыслить как некоторые точки, к которым привязываются (раз и навсегда) значения.

Переменной можно привязать любое значение (любой терм), например, карту или фунтерм.

В обработчике списка значения привязываются к переменным с помощью генераторов.

Глобальных или приватных переменных в Эрланге нет.

Активно используется рекурсия (в том числе хвостовая), это позволяет обходиться минимумом переменных.

Переменные, которые не используются

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

_A = "Столица Мадагаскара называется Антананариву.",

Если переменная не используется, часть кода, с нею связанная (ненужный код), в итоговый beam-файл не попадёт. Если интересно, можете провести эксперимент: зафиксировать размер beam-файла без строки, сколько со строкой A = "Столица..." и сколько со строкой _A = "Столица...". Размер будет везде одинаковым.

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

main() ->
    A = "Столица Мадагаскара называется Антананариву.",
    B = A, 
    C = B, 
    D = C,
    E = D,
    F = E,
    G = F,
    H = G,
    io:format("Привет! \n" ).

Компилятор выведет предупреждение только по последней переменной H — скажет, что она не используется. Про другие переменные он умолчит (они же вроде бы как-то используются), но в beam-файл они не попадут.

Переменные и декларативность

Такого рода выражения: X = X + 1 в Эрланге являются нонсенсом. На уроках алгебры в школе подобного рода уравнение тоже было бы нонсенсом. Если бы мы так написали на доске, нам, может быть, даже двойку за это поставили бы. В императивных языках программирования выражение X = X + 1 это нормально. Там команды выполняются, а не обсуждаются. Эрланг — более философский (декларативный) язык. X = X + 1 рассматривается не как команда, а как суждение. А оно может быть истинным, а может быть ложным. Это — заведомо ложное. Компилятор обратит на это внимание и выдаст варнинг.

Если мы где-то в коде встречаем выражение вроде Y = X + 55, то можем быть уверены, что внутри текущей функции (области видимости) игрек всегда на 55 больше икса. Верно будет и другое суждение: X = Y - 55. Проверим в оболочке:

1> X = 33.
33
2> Y = X + 55.
88
3> X = Y - 55. 
33
4> X = Y - 54. 
** exception error: no match of right hand side value 34

В императивных языках первые две строки выполнились бы так же. У икса стало бы значение 33, а у игрека 88. Третья строчка могла бы вызвать ошибку: если переменная объявлена как иммутабельная, ей снова не удастся присвоить значение, пусть даже оно такое же. Если бы третья строка выполнилась, то выполнилась бы и четвёртая. В Эрланге же другая логика: суждение X = Y - 54 не прошло проверку на истинность, поэтому программа завершилась крахом.

Можно сказать, у каждой программы на Эрланге есть такая сверхзадача — во время исполнения найти в самой себе противоречие. У программ на императивных языках другая сверхзадача — точно и послушно выполнить задумку программиста.


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