Наложи ми се да търся информация за езика Erlang за да направя един проект за университета. Но се оказа че за този език цялата информация е на английски и е сравнително трудно да се намери на едно място.

Езика има добра документация, но иска доста ровене из нея за да се разбере добре Erlang.

Публикувам тук информацията която събрах и преведох. Не съм програмирал на този език, така че малки неточности са възможни ;)

История

Разработването на Erlang е започнало през 1986 г. в лабораторията за компютърни науки на Ericsson. Той е проектиран с ясна цел: „да осигури по-добър начин за програмирането на телефонни приложения”. По това време конвенционалните езици за програмиране не можели да се справят с проблемите с които се сблъскват телефонните приложения. Налагало се софтуера да се справя с десетки хиляди паралелни процеси и да може да бъде променян докато работи, за да не спират телефонните услуги докато се извършват обновления. Софтуера също така трябвало да работи в реално време строго за определени операции, и не толкова точно за други.

Основната задача на езика била да се справя с проблеми като:

§ Обработването на много паралелни задачи

§ Действия които да се изпълнят в точно определено време или за определено време

§ Системи които да се разполагат на няколко компютъра

§ Взаимодействие с хардуер

§ Много големи софтуерни системи

§ Сложна функционалност като взаимодействие между различни системи

§ Непрекъсната работа в продължение на години

§ Поддръжка на софтуера без да се спира системата

§ Да реагира добре при грешки в хардуера или софтуера

Когато Erlang се появил имало сравнително малко области където се изисквал софтуер който да работи непрекъснато. Но с нарастването на популярността на Интернет и на нуждата от предоставяне на постоянна възможност за достъп до него нараснали и проблемите които Erlang може да реши. Например, създаването на огромен уеб сървър, с динамично обновление на кода, обработващ милиони заявки на ден е сходно със създаването на софтуер, който да управлява телефонните разговори.

От началото Erlang е създаден като инструмент който да върши работа. Често нови функции били добавяни в езика за да се справи с определен проблем и функции които не се използвали били премахвани. Процеса на работа бил толкова бърз, че много от добавянията и премахванията на елементи от езика дори не били записвани.

Предназначение, тип, особености

Erlang е функционален език, създаден за писането на програми които работят постоянно. Използват се паралелни процеси за да се структуира програмата. Процесите нямат споделена памет и комуникират чрез несинхронизирано предаване на съобщения. Процесите в Erlang са много леки и пренадлежат на езика, а не на операционната система.

Езика има механизми които позволяват промяната на кода на програмите докато те работят. Има механизми и за реализирането на системи които никога не спират.

Повечето програми написани на Erlang ще вървят по-бързо ако се изпълняват на многопроцесорни машини.

Типове данни

Erlang има няколко различни типове данни. Всяка частица данни, независимо от какъв тип е се нарича терм.

Number

Има два типа числа: цели (integer) и с плаваща запетая (float).

Освен стандартните означения на числата има и две специфични за Erlang означения:

$char – връща ASCII стойността на знака
Например:

2> $A.
65

В примера $A връща ASCII стойността на знака А

base#value – където base е базата на бройната система на числото, а value е неговата стойност. Базата трябва да е цяло число от 2 до 36.
Например:

1> 2#101.
5
2> 16#1f.
31

Atom

Atom е константа с име. Атома трябва да е обграден с единични кавички ( ‘ ) ако не започва с малка буква или съдържа специални символи.

Примери за atom:

hello
phone_number
'Monday'
'phone number'

Atom-ите много приличат на дефинирането на символични константи в С. Но в Erlang тяхната стойност е самият atom. Т.е. ако се напише команда която е просто atom ще се изпише самият atom.
Пример:

1> hello.

hello

Reference

Това е терм който е уникален за цялата система. Създават се с erlang:make_ref(). Могат да бъдат сравнявани за еднаквост.

Port Identifier

Идентификатор на Erlang порт.

Портовете се създават с функцията open_port() и са средство за комуникация с програми извън системата на Erlang. Когато се създаде порт, Erlang програмата може да комуникира чрез него изпращайки и получавайки поредица от байтове.

Erlang процеса който създава порта се нарича негов собственик и цялата комуникация от и към порта трябва да минава през него. Ако собственика на порт прекрати съществуването си порта се затваря.

Синтаксис за отваряне на порт:

Port = open_port(PortName, PortSettings)

Pid

Идентификатор на процес.

Функциите spawn(), spawn_link() и spawn_opt(), които се използват за създаването на процеси, връщат стойност от този тип.

Boolean

В Erlang няма boolean тип. Вместо него се използват аtom-ите true и false за да се означават boolean стойности.

Пример:

1> 2 =< 3.
true
2> true or false.
true

Структури от данни

Bit Strings (Binaries)

Тази структура от данни се използва за да пакетира поредица от битове и да ги разположи в паметта. По този начин могат да се съхраняват големи количества данни в сравнително малко памет.

Синтаксиса е <<E1,…,En>> като Еi е сегмент от bit string-a. Еi е стойност, като може да съдържа и информация за размера и типа и.

Примери:

Bin1 = <<1,17,42>>.
Bin2 = <<"abc">>.

Fun

Това са анонимни функции (обекти). С помощта на тази структура функции без име могат да се дефинират директно в израз или като параметър към друга функция.

Пример:

1> Hypot = fun(X, Y) -> math:sqrt(X*X + Y*Y) end.

2> Hypot(3,4).

5.00000

Tuple

Това е съставен тип данни, който съдържа фиксиран брой терми.

{Term1,…,TermN}

Всеки терм в tuple се нарича елемент, броят на елементите се нарича размер на tuple-a.

За разлика от структурите в С, tuple в Erlang нямат име, нито пък елементите им имат имe. Затова е честа практика да се поставя atom като първи елемент на tuple-a, който описва за какво служи tuple-a. Така кода става много по-четлив. Tuple структурите могат да бъдат вложени.

Пример (създаване на tuple):

F = {firstName, joe}.

Пример (извличане на стойност от tuple):

1> element(2,F).

joe

Съществуват много вградени функции за различни операции с tuple. Например element(), setelement(), tuple_size().

List

Това е съставен тип данни, който съдържа променлив брой терми.

[Term1,...,TermN]

Всеки терм в list се нарича елемент, броят на елементите се нарича дължина на list-а.

Първият елемент от list-а се нарича глава на list-a, всичко останало се рарича опашка. Опашката може да бъде друг list. Всъщност синтаксиса на list е по-кратък вариант на:

[Term1|[...|[TermN|[]]]]

Елементите на list-а могат да бъдат от различни типове.

Пример:

1> L1 = [a,2,{c,4}].
2> [H|T] = L1.
3> H.
a
4> T.
[2,{c,4}]

String

String-овете се ограждат с двойни кавички ( “ ), но не са тип данни в Erlang.

Например string-a “hello” е кратък запис на [$h,$e,$l,$l,$o], което е [104,101,108,108,111].

Два стринга записани един до друг са съединяват по време на компилиране.

Record

Това е структура от данни с фиксиран брой елементи. Елементите имат имена и е сходна на структурите в С.

Record не е истински тип данни за Erlang. По време на компилиране record се преобразува в един или повече tuple.

Пример (деклариране на record):

X = #person{name=Name, age=Age}.

Пример (създаване на record):

-record(person, {name, age}).

Пример (извличане на стойност на поле):

1> X#person.name

Name

Управляващи конструкции

If

if

Guard1 ->

Expr_seq1;

Guard2 ->

Expr_seq2;

end

Всяко условие (Guard1, Guard1) в if оператора се проверяват едно по едно. Когато някое условие се оцени на true се изпълняват изразите след него. Резултата който връщат изразите е резултат на if оператора.

Ако нито едно условие не бъде оценено на true възниква грешка. Ако е необходимо, за последно условие може да се постави true, и така ако всички други не се изпълнят то ще се изпълни.

Case

case Expression of

Pattern1 [when Guard1] -> Expr_seq1;

Pattern2 [when Guard2] -> Expr_seq2;

end

Изразът (Expression) се сравнява с различните шаблони и при успех се изпълняват съответните изрази. Стойността която връщат изпълнените изрази е стойността която ще върне case оператора.

Ако няма съвпадение на сравняваните шаблони възниква грешка по време на изпълнението на програмата.

Function Calls

Тъй като Erlang няма цикли за постигане на цикличност се използват функции в комбинацията с операторите if и case.

С помощта на функции и рекурсия могат да се реализират повечето видове цикли на Erlang.

Пример за цикъл for реализиран на Erlang:

for(Max, Max, F) -> [F(Max)];

for(I, Max, F) -> [F(I)|for(I+1, Max, F)].

Send

Erlang е създаден за паралелно програмиране и потока на изпълнение на програмата зависи от съобщенията които процесите си разменят.

Expr1 ! Expr2

Тази команда изпраща стойността на Expr2 като съобщение на процеса определен от Expr1. Expr1 може да бъде pid, atom(име) или tuple. Ако се използва atom и не бъде намерен процес със съответното име възниква грешка.

Receive

Получава съобщение изпратено от друг процес със send (!) оператора.

receive
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
end

Ако не бъде получено съобщение което да отговаря на някой от шаблоните изпълнението на процеса се прекратява докато не се получи подходящо съобщение.

Вход/Изход – съхраняване на информация

Erlang ами много модули които реализират различни начини за комуникация със системата му. Най-използваните са: asn1, crypto, gs, inets, jinterface, megaco, public_key, ssh, ssl, wx, xmerl, erl_interface.

Има възможност и за реализирането на всякакви други видове комуникация с устройства чрез байтови потоци.

Езика има модули които реализират всички възможни операции с файлове които операционната система поддържа.

Интересни функции за работа с файлове и директории в модула file:

change_group, change_owner, change_time, close, consult, copy, del_dir, delete, eval, format_error, get_cwd, list_dir, make_dir, make_link, make_symlink, open, position, Pread, pwrite, Read, read_file, read_file_info, read_link, read_link_info, Rename, Script, set_cwd, Sync, Truncate, Write, write_file, write_file_info

Erlang има ODBC модул, който предоставя интерфейс за комуникация с релационни SQL бази данни.

Езика има и модул mnesia, който е система за управление на бази данни и е подходящ за телекомуникационни приложения.

Mnesia има способностите необходими за да се справя с проблемите за които е създаден Erlang.

Някой от най-важните и атрактивни качества на Mnesia са:

· Релационно-обектен хибриден модел на представяне на данните, който е подходящ за телекомуникационни системи.

· Специално създаден DBMS език за заявки.

· Таблиците могат да бъдат съхранявани както на диска, така и в паметта.

· Таблиците могат да бъдат разположени на различни машини.

· Групиране на серия от операции към таблица.

· Програмите могат да бъдат писани без знание къде точно се намират данните.

· Много бързо търсене в реално време.

· Може да бъде преконфигурирана без да бъде спирана.

Компилатори/Интерпретатори

Програмите на Erlang трябва да бъдат компилирани до обектен код. Компилатора генерира файл с обектния код и той се изпълнява от абстрактна машина наречена BEAM.

Компилатора може да генерира и директно изпълним файл.

Обектния код трябва да бъде зареден в системата на Erlang, което се прави от сървър. Кода се зарежда по два начина: когато е необходим или по предварително зададен начин.

Системата на Erlang позволява промяна на кода докато тя работи. Това става за всеки модул по отделно.

Кода на всеки модул може да съществува в два варианта в системата: текущ и стар. Когато модул се зареди за първи път той е текущ. Ако нов вариант на модула се зареди, кода от предния вариант на модула става стар, а новия вариант става текущ.

Ако трети вариант на модула се зареди сървъра ще изтрие стария вариант, третия вариант става текущ, а предишният текущ става стар.