Wednesday, January 30, 2008

Синтаксис Erlang в двух словах.

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

Тут лучше конечно почитать какой-нибудь более серьезный туториал, начиная с собственно "Getting Started with Erlang" (русский перевод на рсдн), или "Thinking In Erlang". Однако ж, поскольку 30-50 страниц осилить не у каждого поднимется мозг, я здесь изобразил небольшую шпаргалку (не претендующую на полноценное введение).

В принципе Эрланг весьма прост, по крайней мере для тех, кто хоть краем глаза видел какой-нибудь другой функциональный язык.

Для начала самые примитивные вещи:

  • Прежде всего, Эрланг — это язык с динамической типизацией, никакой статической проверки типов тут нет.

  • Литералы-числа в Erlang: 1, 4, 15, 25, 16#1F (в шестнадцатеричной системе), 2#01110110 (в двоичной).
    > 1.
    1
    > 1+2.
    3
    > 1+1.5.
    2.50000
  • Литералы-символы: на самом деле это не отдельный тип, а просто целое число — код символа : $a, $b, $\n $_
    > $a.
    97
    > $\n.
    10
  • Списки задаются в квадратных скобках:
    > [].
    []
    > X = [1,2].
    [1,2].
    > [3 | X].
    [3, 1, 2]
  • Строки — "aba a", "ga a ga".
    > [$a, $b, $c].
     "abc"
    Строки — это на самом деле просто списки символов. Поэтому памяти они занимают немало — в общей сложности 8 байт на один символ строки (на 32-битной машине).
  • Битовые строки (binaries) — эффективное представление бинарных данных
    > <<1, 3, "ba">>.
     <<1,3,98,97>>
    
    Их можно сопоставлять с шаблонами, и быстро передавать туда-сюда. Очень полезная фича Эрланга (правда мы ее использовать сильно не будем).
  • Атомы
    abds
    more
    hello
    ok
    undefined
    
    Начинаются с маленькой буквы, и представляют собой что-то среднее между enum'ами и константными строками, пишутся без кавычек и удобны для разных меток и идентификаторов. Атомы очень похожи на строки, но их нельзя склеивать, вычислять длину и пр., длина их ограничена 256 байтами. Они существенно эффективнее строк в обращении.
  • Еще любые значения еще можно объединять в пары, тройки, четверки, пятерки и так далее, с помощью фигурных скобок: 
    {14, 15} 
    {0, "ba", 3} 
    {$a, [1,2], {3,4}} 
    

Имена переменных всегда начинаются с большой буквы (несмотря на то что они везде называются "переменными", менять их нельзя).

Имена функций и модулей обязательно начинаются с маленькой буквы. Сигнатура функции состоит из ее имени и количества параметров — то есть format/2 и format/3 это разные функции.

Паттерн матчинг (сопоставление с шаблоном) в Erlang выглядит так:

case A of
    Pattern1 -> ...;
    Pattern2 -> ...;
    Pattern3 -> ...;
end

В паттернах можно использовать значок _ который матчит все что угодно (wildcard). В жизни используется как-то так:

case Foo of
    {"HELLO", Name} -> send_response("Hello, " ++ Name);
    "BYE" -> send_response("Bye");
    _ -> send_response("Unknown command")
end

Еще паттерны можно использовать прямо в списке параметров функции:

foo({_, B}) ->
    ...;

foo(X) ->
    ...

что эквивалентно

foo(Y) ->
    case Y of
        {_, B} -> ...
        X -> ...
end.


Плюс, значения можно матчить с помощью знака "равно":

X = {1, 3},
{A, B} = X.

теперь A = 1, а B = 3

Причем, если переменная слева уже определена, в паттерне используется ее значение:

   > B = 4.

Получаем run-time ошибку badmatch, потому что B у нас уже равно трем.

С операторами все почти как обычно:

  • арифметические, +-/*%
  • сравнения =/ , ==, =>, =<
  • склеивание списков ++
  • декомпозиция списков (оператор cons) |
  • битовые band, bor, bxor, bnot

Вот, собственно, практически все. Раздражают в Эрланге поначалу только немного странные правила расстановки точек, запятых и точек с запятой. В двух словах — точка ставится в конце определения функции, запятая — между выражениями в определении функции, а точка с запятой разделяет выражения в case .. of и if.

 


В качестве примера — функция, получающая md5 хэш строки. В стандартной библиотеке уже есть функция md5(), которая получает хэш в виде битовой строки.

> H = erlang:md5("boooo").
<<174,62,131,226,250,179,167,216,104,61,142,239,171,209,231,77>>

Нам же понадобится хэш в виде обычной строки, в шестнадцатиричном представлении, поскольку он используется в процедуре аутентификации на last.fm

Для начала можно преобразовать битовую строку в список байт с помощью стандартной функции:

> binary_to_list(H).
[174,62,131,226,250,179,167,216,104,61,142,239,171,209,231,77]

Теперь функция, которая преобразует 4 бита в один hex символ:

hex(V) ->
    if
    V < 10 ->
            $0 + V;
    true ->
        $a + (V - 10)
     end.

Да, if в erlang — лишь упрощенный вариант case .. of, где вместо паттернов — булевые выражения. Так что кейс "true ->" тут играет роль else

Теперь один байт можно преобразовать в hex так:

> E = 31.
> [hex(E bsr 4), hex(E band 16#F)].
"1f"

Ну и с помощью функции lists:foldl применить это ко всей исходной строке:

binary_to_hex(Bin) ->
    lists:foldl(fun (E, Acc) ->
            [hex(E bsr 4) | [hex(E band 16#F) | Acc]] end,
        [],
        lists:reverse(binary_to_list(Bin))).
% returns hex representation of md5 in reverse byte order
md5_hex(Bin) ->
    binary_to_hex(erlang:md5(Bin)).

Тут

  • fun (E, Acc) -> ... end
         это определение лямбда-функции
  • lists:foldl() это известный функциональным программистам foldl.
  • lists:reverse() разворачивает список задом наперед
  • Конструкция вида [A | B] приклеивает в начало списка B элемент A (см. cons).

Итого получаем

>md5_hex("booo").
"1c052f260d1b34423c32e7c7b29026b9"

Весь исходник (utils.erl)

Про ключевую фичу Erlang — поддержку распределенных приложений поговорим в следующей серии.


Crash Course: веб приложения на Erlang [Дисклеймер]

erlang Почему-то зима выдалась крайне скудной на интересные новости.
Однако это не так уж плохо, можно нормально, не отвлекаясь на чтение RSS заняться непосредственно работой, да и появляется время поковырять разнообразные перспективные технологии, в частности — Erlang, неспроста я ему так уделял внимание последнее время.

В общем, по мотивам своих экзерсисов в erlang, я решил написать небольшой туториал, такой crash course про erlang, причем как средство программирования именно веб-приложений. В качестве примера и сверхзадачи я выбрал веб-клиент (прокси) для социального интернет радио last.fm.

Плюс к этому, меня тут даже рекламировали как пишущего про эрланг — будем оправдывать ;)

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

В конце концов можно слушать ласт.фм без установки клиента, например, на КПК/мобильнике с вайфаем.


Friday, December 14, 2007

Erlang @ Amazon

А между тем замечательный язык erlang действительно напрашивается на то чтоб стать next big thing в веб-приложениях. Последнее время все больше и больше интересных новостей из этой области — особенно тут отличился Amazon.

Однако ж обо всем по порядку.

Последнее время Amazon становится одним из основных ньюсмейкеров со своими весьма инновационными сервисами по хостингу данных и приложений.

Первой ласточкой был EC2 — нечто, крайне напоминающее обычный VPS хостинг — амазон предоставляет вам в пользование виртуальные машины с операционной системой на выбор, однако деньги берет не помесячно, а за машино-часы и переданные гигабайты (от $0.10 до $0.80 за машино-час, плюс $0.10-$0.20 за переданный гигабайт).

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

Таким образом за приемлемые деньги можно получить небольшой (или большой) кластер из виртуальных машин.

Народ сразу оживился — действительно, EC2 и распределенный erlang будто созданы друг для друга. Можно запускать сколько нужно нодов на нужном количестве инстансов EC2, при этом не заморачиваясь никакими оргвопросами связанными с покупкой и администрированием настоящих серверов.

Второе — это S3, сервис по хранению данных. Деньги амазон берет за количество запросов + гигабайты в месяц, без всяких фиксированных тарифных планов.

И теперь амазон объявляет о запуске еще одного сервиса под названием SimpleDb — и все встает на свои места.

Это база данных, однако больше всего она похожа на большой excel-евский spreadsheet:

  • данные организуются в таблицы (которые называются доменами), 
  • никаких сложных запросов, но работает, говорят крайне быстро -- чуть ли не реалтайм;
  • в одной ячейке можно хранить несколько значений (как список или кортеж)
  • никаких типов у хранимых данных нет
  • таблицы распределены по многим серверам

Если кто читал про ерланговскую родную базу данных mnesia, сразу увидит много знакомых фраз. Точнее, практически все эти фичи есть и у mnesia.

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

И действительно, в блоге амазоновского разработчика находим подтверждение: SimpleDb построена на erlang!

Если SimpleDb будет популярна — а предпосылки для этого есть (это ж Amazon) — это будет самый убийственный пример применения erlang в боевых условиях.

Да и просто факт, что уже доступна отличная и недорогая платформа для хостинга эрланговских приложений — уже очень хорошая новость.


Tuesday, November 27, 2007

Erlang Job

Для тех, кто не читает форумы рсдн (что, конечно, идеологически правильно): cовершенно неожиданно оказалось что Joel Reymont (чувак с покером на эрланге) родился в Санкт-Петербурге и отлично говорит по-русски. И вообще треть жизни прожил тут.

Оказалось это в связи с тем, что Джоель сейчас ищет программистов на Erlang и OCaml (пока part-time). На сайте у него говорится про разработку бэкенда для того самого OpenPoker, но из треда на рсдне видно что планы у него намного глобальнее.

Так как это уже не первое предложение работы на erlang на русском языке за последнее время, уже очень хочется это назвать тенденцией.


Thursday, November 08, 2007

Угадайка

Как думаете, какой язык поддерживает сразу

  • First-class функции, лямбды и замыкания;
  • параметризованные типы;
  • хвостовые вызовы;
  • array comprehensions;
  • ООП с классами и интерфейсами;
  • ООП на основе прототипов;
  • мультиметоды;
  • coroutines (оператор yield);
  • структурные и номинальные подтипы;
  • перегрузку операторов;
  • Nullable/Non nullable аттрибуты для всех типов.

Ну и по мелочи: for-each, array slicing а-ля питон, регулярные выражения, открытые пространства имен и пр.

Однако ж это все ожидается в чудесном новом Javascript ECMAScript 4!

Еще  одна из самых интересных возможностей в четвертой версии — опциональная статическая проверка типов. Это должно упростить написание сложных систем (засчет строго описанных интерфейсов), и помочь [jit] компиляторам иногда генерировать более эффективный код. Опциональные статические типы, похоже, становятся модными: в Python 3000 тоже не так давно добавили что-то похожее.

Четвертая версия пока получается довольно пестрой — появилась куча новых механизмов и языковых конструкций (см. выше), а совместимость с предыдущей версией надо, по возможности, сохранить — поэтому синтаксис местами получился довольно странный: скажем, [int] это массив целых чисел, а [int, string] — это уже кортеж из целого и строки.

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

var foo : like {x : int, y : int};

А переменная, объявленная с ключевым словом wrap автоматически дополняет хранимый в ней объект нужными свойствами:

var bar : wrap foo { x : int, y : int} = {x : 10, y : 20}.

Может и не революционная фича, конечно, но выглядит крайне интересно.

В ECMAScript 4 обещают также обязательную оптимизацию хвостовых вызовов. В Python 3000 их точно не будет, с руби ситуация туманна —что делает ES4 лучшим выбором в качестве платформы для компиляторов с функциональных языков. В общем-то уже сейчас есть компиляторы, как минимум, OCaml, SML и Haskell, генерирующие код на ECMASCript 3.

Собственно мощь и текущей-то версии js во многом недооценена. Кстати, только я не знал, что автор один из авторов первой версии Javascript — Гай Стил мл., а в качестве основных источников вдохновения при разработке Javascript 3 авторы называют языки Scheme и Self?

Новый Javascript явно претендует на что-то большее. Если он действительно будет "принят на вооружение" — определенно можно ожидать появления изрядного количества серверных приложений и фреймворков на js. Во всяком случае, язык получился явно не слабее питона и руби — хотя, конечно, вряд ли средства интеграции с кодом на C и C++ будут тут столь же развиты, ниша у языка все-таки другая.

Ссылки:


Thursday, October 25, 2007

Пятиминутка ненависти к C++

..на этот раз не моя, однако почитать другим пострадавшим будет довольно забавно. Автор — yousefk, видимо, годами записывал в книжечку все подлянки, которые ему устраивал C++, и в результате у него получился вот такой весьма объемный документ.

Называется это C++ Frequently Questioned Answers, и проезжается он практически по всем сколько-нибудь заметным фичам C++.

За основу взят широко известный C++ FAQ Lite, дополненный "альтернативными" ответами в среднеиздевательском тоне — то есть автор, к счастью, не совсем сваливается в непрерывное брюзжание (как я иногда), что сделало бы такой огромный труд невыносимо скучным.

Причем критика там действительно весьма обоснованная и грамотная, что встретишь не так уж часто. Правда, местами получается таки чересчур эмоционально, но, наверное, только сам автор знает, сколько горя и несчастья причинил ему злой гений Страуструпа за эти годы.