Changes

Main Page

21,937 bytes added, 5 years ago
no edit summary
<span class{{ Язык программирования | name ="plainlinks" styleErlang | semantics ="font-sizeмультипарадигмальный:77%;">'''[[Special:Statisticsпараллельное, функциональное программирование |{{NUMBEROFPAGES}}]]''' pages</span><br/>year = 1987<span class |designer ="plainlinks" styleEricsson Computer Science Laboratory |extension ="font-size:77%;">'''[[Special:Statistics.erl |{{NUMBEROFARTICLEStyping = строгая, динамическая |influenced_by = ML, Миранда, Ада, Модула-2, CHILL, Пролог}}]]''' articles</span><br/>
'''Erlang (Эрла́нг)''' — функциональный язык программирования, позволяющий писать программы для разного рода распределённых систем. Разработан и поддерживается компанией Ericsson. Язык включает в себя средства порождения параллельных процессов и их коммуникации с помощью посылки асинхронных сообщений. Программа транслируется в байт-код, исполняемый виртуальной машиной, что обеспечивает переносимость.
<categorytree mode=all depth=0>Category:International Association for Cryptologic Research</categorytree>История ==В середине 1980-х в компьютерной лаборатории компании Ericsson исследовали применимость существующих на тот момент языков программирования для программного обеспечения телекоммуникационных систем. Джо Армстронг (Joe Armstrong), Роберт Вирдинг (Robert Virding) и Майк Вильямс (Mike Williams) под руководством Бьярне Деккера (Bjarne Däcker), написав прототипы программ на различных языках, пришли к выводу, что ни один из этих языков не имел полного набора возможностей, необходимых в области телекоммуникационных систем. В результате был создан новый язык программирования — Erlang. Своё название язык, вероятно, получил в честь датского математика и инженера Агнера Эрланга, основателя научного направления по изучению сетевого трафика в телекоммуникационных системах. По другой версии, название языка изначально было сокращением от «ericsson language».
<inputbox>type=create= Особенности ==</inputbox>Язык динамический. Синтаксис наследован от Prolog — компактный, содержит минимум конструкций, лёгкий для освоения, но не примитивный.
К услугам программиста — модули, полиморфные функции, сопоставление с образцом, анонимные функции, условные конструкции, структуры, обработка исключений, оптимизация хвостовой рекурсии. В общем базовый арсенал современных функциональных языков. Функциональная парадигма (отсутствие присваиваний) позволяет Erlang избежать таких традиционных для императивных языков проблем распределенных приложений, как необходимость синхронизации, опасность возникновения тупиков и гонок. Главное в Erlang — его модель легковесных процессов. Перефразируя для Erlang слоган текущего дня “Everything is an object” («Всё является объектом»), можно сказать “Everything is a process” («Всё является процессом»). Процессы дёшевы, создание процесса занимает не больше ресурсов, чем вызов функции. Единственным способом взаимодействия процессов является асинхронный обмен сообщениями. Процесс имеет свой «почтовый ящик», откуда может выборочно читать сообщения, в чем очень помогает сопоставление по шаблону, код проверки «ящика» чем-то похож на программу на awk, нужное выгребается и обрабатывается, остальное остаётся или выбрасывается. На разработку программ накладывают сильный отпечаток два момента^ язык стимулирует к созданию большого количества конкурентных процессовпроцессы жёстко изолированы и не имеют общего состоянияПроцесс проектирования заключается в итеративном разбиении системы на иерархии конкурентно взаимодействующих подсистем, пока составляющие не станут достаточно просты для реализации. Мощность связки «Процессы+сообщения» не меньше, чем «Объекты+Интерфейсы+Наследование», но зачастую приводит к более компактным и понятным решениям. Устранение конкуренции также просто как и создание. Отсутствие необходимости блокировки доступа к состоянию процесса для синхронизации их взаимодействия сильно облегчает жизнь. Для конкурентного ресурса обычно просто создаётся процесс-монитор, через который осуществляется взаимодействие с ресурсом. Второй момент выражается в формуле «let it crash» («пусть процесс упадет»). Вместо перехвата ошибок и попытки продолжения работы часть программы, содержащая рискованный код, выделяется в отдельный процесс-камикадзе, этот процесс делает все возможное, чтобы система убила его в случае возникновения ошибки, а процесс-родитель только получает сообщения о смерти таких незадачливых потомков и делает выводы. Учитывая, что обычно в 90 % подобных ситуаций ничего более путного, чем вывести сообщение об ошибке и попытаться жить с этой болью дальше, не представляется возможным, отсутствие в коде многочисленных проверок не так уж непривлекательно. == Высокоуровневые конструкции ==Erlang является декларативным языком программирования, который скорее используется для описания того, что должно быть вычислено нежели как. Например, определение функции, которое использует сопоставление с образцом для выбора одного из вариантов вычисления или извлечения элемента данных из составной структуры, напоминает уравнение. Сопоставление с образцом распространено даже на битовые строки, что упрощает реализацию телекоммуникационных протоколов. Функции являются объектами первого класса в Erlang. В языке также широко применяются характерные для функциональной парадигмы программирования списковые включения (генераторы списков). ==Параллельные вычисления == Обмен сообщениями между процессами в ErlangОтличительной особенностью языка является применение легковесных процессов в соответствии с моделью акторов. Такой подход позволяет выполнять одновременно сотни тысяч и даже миллионы таких процессов, каждый из которых может иметь скромные требования по памяти. Процессы изолированы друг от друга и не имеют общего состояния, но между ними можно установить связь и получать сообщения об их состоянии. Для взаимодействия процессов используется асинхронный обмен сообщениями. Каждый процесс имеет свою очередь сообщений, обработка которой использует сопоставление с образцом. Процесс, отправивший сообщение, не получает уведомления о доставке, даже если идентификатор процесса-получателя недействителен или получатель игнорирует сообщение. Таким образом, ответственность за правильно организованное взаимодействие между процессами лежит на разработчике. Например, при реализация на Erlang сетевого чата структура программы может напрямую отражать одновременность действий пользователей по обмену сообщениями путём запуска новых процессов. Эффективность передачи сообщений сохраняется и при увеличении числа процессов, а требования к памяти минимизируются за счёт того, что легковесными процессами управляет виртуальная машина, а не средства нижележащей операционной системы. == Распределённые вычисления ==Erlang с самого начала проектировался для распределённых вычислений и масштабируемости. Распределение вычислений встроено в синтаксис и семантику языка, поэтому построение системы можно вести, абстрагируясь от конкретного места вычислений. В стандартной поставке Erlang может наладить связь процессов по протоколу TCP/IP независимо от поддерживаемых им нижележащих платформ (операционных систем). Работающий экземпляр среды выполнения Erlang (англ. Erlang runtime system) называется узлом (англ. node). Программы, написанные на Erlang, способны работать на нескольких узлах. Узлами могут быть процессоры, многие ядра одного процессора, и даже целый кластер машин. Узел имеет имя и «знает» о существовании других узлов на данной машине или в сети. Создание и взаимодействие процессов разных узлов не отличается от организации взаимодействия процессов внутри узла. Для создания процесса на другом узле процессу достаточно знать его имя и, без особых на то оснований, он может не интересоваться физическим расположением взаимодействующего с ним процесса. Синтаксис отправки сообщения процессу на своём узле и удалённом один и тот же. Благодаря встроенным в язык возможностям распределённых вычислений объединение в кластер, балансировка нагрузки, добавление узлов и серверов, повышение надёжности вызывают лишь небольшие затраты на дополнительный код. По умолчанию узлы спроектированы для работы внутри обособленного сегмента сети (DMZ), но, если необходимо, коммуникация между узлами может происходить с применением защищённого криптографическими методами протокола SSL. == Мягкое реальное время ==Программы на высокоуровневом языке Erlang могут быть использованы в системах мягкого реального времени (которое иногда переводят как «псевдореальное» или «квазиреальное»). Автоматизированное управление памятью и сборка мусора действуют в рамках одного процесса, что даёт возможность создавать системы с миллисекундным временем отклика (даже несмотря на необходимость сборки мусора), не испытывающие ухудшения пропускной способности при высокой нагрузке. ==Горячая замена кода ==Для систем, которые не могут быть остановлены для обновления кода, Erlang предлагает горячую замену кода (англ. hot code upgrade). При этом в приложении могут одновременно работать старая и новая версии кода. Таким способом программное обеспечение на Erlang может быть модернизировано без простоев, а выявленные ошибки исправлены. ==Типы данных ==Типизация в Erlang является строгой и динамической. Динамическая типизация была выбрана для языка Erlang по причине того, что первые разработчики были больше с ней знакомы. По мнению Джо Армстронга, статическая типизация потребовала бы очень больших трудозатрат, в частности, реализовать систему горячей дозагрузки кода было бы крайне затруднительно. Такая типизация, при которой возможные ошибки типов выявляются только во время выполнения, тем не менее, не помешала создавать системы с очень высоким уровнем доступности. Данные в Erlang являются неизменяемыми: операции не переписывают старые значения, находящиеся в памяти. Если необходимо, модули на Erlang можно снабдить описаниями и определениями новых типов (не влияющими на компиляцию программы) для автоматической проверки типов с помощью утилиты Dialyzer. == Элементы синтаксиса =={| class="wikitable"|-| Комментарий до конца строки || %|-| Регистрозависимость || да|-| Присваивание значения переменной || =|-| Определение функции || fun(a, b) -> ... end|-| Вызов функции || f(a,b,...)|-| Вызов функции без параметров || f()|} ''Арифметические операции'' {| class="wikitable"|-|Обозначение || Выполняемая операция || Пример || Результат примера|-|bnot || Побитовое отрицание bnot || (2#1000) || -9|-|band || Побитовое И || 2 band 3 || 2|-|bor || Побитовое ИЛИ || 1 bor 2 || 3|-|bxor || Побитовое исключающее ИЛИ || 5 bxor 3 || 6|-|bsr || Побитовый сдвиг вправо || 32 bsr 2 || 8|-|bsl || Побитовый сдвиг влево || 1 bsl 5 || 32|} == Примеры ==''Hello, World!'' Пример для версий erl 5.7.3Первая строка задает имя модуля и указывает на то, что он должен находиться в файле prog.erl. Вторая строка экспортирует 0-арную (не имеющую параметров) функцию main. Третья описывает саму функцию, которая выводит “Hello, World!”. <source>-module(prog).-export([main/0]). main() -> io:format("Hello, World!~n").</source> ''Факториал'' Пример для версий erl 5.7.3Используется рекурсивное определение факториала. В Erlang нет встроенных циклов, поэтому цикл приходится симулировать рекурсивной функцией, которая начинает с больших значений N, но делает рекурсивный вызов для N-1 до того, как выводит N!. loop(_) — ветвь, которая задает поведение функции, если ее аргумент — не целое число или отрицателен (необходима для корректного определения функции). <source>-module(prog). -export([rumain/0, loop/1]). fact(0) -> 1;fact(N) -> N * fact(N-1). loop(N) when is_integer(N), N>=0 -> loop(N-1), io:Заглавная страницаformat("~B! = ~B~n",[N,fact(N)]);loop(_) -> ok. main() -> loop(16).</source> ''Числа Фибоначчи'' Пример для версий erl 5.7.3Используется итеративное определение чисел Фибоначчи, выраженное в форме хвостовой рекурсии. <source>-module(prog). -export([main/0]). fib(1,_,Res) -> io:format("~B, ",[Res]);fib(N,Prev,Res) when N > 1 -> io:format("~B, ",[Res]), fib(N-1, Res, Res+Prev). main() -> fib(16,0,1), io:format("...~n").</source> ''Числа Фибоначчи'' Пример для версий erl 5.7.3Используется формула Бине. Числа с плавающей точкой обязаны выводиться с как минимум одним знаком после запятой, поэтому результат работы выглядит так: 1.0, 1.0, 2.0, 3.0, 5.0, 8.0, 13.0, 21.0, 34.0, 55.0, 89.0, 144.0, 233.0, 377.0, 610.0, 987.0, ... <source>-module(prog). -export([main/0]). fib(0) -> ok;fib(N) -> fib(N-1), SQ5 = math:sqrt(5), T1 = math:pow(0.5*(1 + SQ5),N), T2 = math:pow(0.5*(1 - SQ5),N), io:format("~.1f, ", [(T1-T2)/SQ5]). main() -> fib(16), io:format("...~n"). </source> ''Квадратное уравнение'' Пример для версий erl 5.7.3 <source>-module(prog). -export([main/0]). solve(A, B, C) -> D = B*B - 4*A*C, if (D == 0) -> io:format("x = ~f~n", [-B*0.5/A]); true -> if (D > 0) -> SQ = math:sqrt(D), io:format("x1 = ~f~nx2 = ~f", [(-B+SQ)/2/A, (-B-SQ)/2/A]); true -> SQ = math:sqrt(-D), io:format("x1 = (~f,~f)~nx2 = (~f,~f)", [-0.5*B/A, 0.5*SQ/A, -0.5*B/A, -0.5*SQ/A]) end end. main() -> case io:fread("A = ", "~d") of eof -> true; {ok, X} -> [A] = X, if (A == 0) -> io:format("Not a quadratic equation."); true -> case io: fread("B = ", "~d") of eof -> true; {ok, Y} -> [B] = Y, case io: fread("C = ", "~d") of eof -> true; {ok, Z} -> [C]= Z, solve(A, B, C) end end end end.</source>
Editors
19
edits