Архив блога

пятница, 10 декабря 2010 г.

Scheme vs Erlang

Таки решил я сравнить эти два языка.Из реализации scheme буду использовать racket-language, ну а erlang один.
1. Pattern matching / Соответствие шаблонам.

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

{cmd, CMD_NAME, [params,[FIRST_PARAM|OTHER_PARAMS]], cmd_end} = {cmd, "MY SUPER COMMAND", [params,[1, 2,3]], cmd_end}.

cmd, cmd_end - это символы эрланга. просто символы, то же самое, для чего в scheme использовалась бы нотация 'cmd и 'cmd_endCMD_NAME, FIRST_PARAM, OTHER_PARAMS - это "переменные", в которые произойдёт подстановка при совпадении с шаблоном. переменные в erlang'е начинаюся с большой буквы (как понимаю, нужно, дабы отличить от символов).
После приведённой выше программы, "переменные" CMD_NAME, FIRST_PARAM, OTHER_PARAMS будут равны "MY SUPER COMMAND", 1 и [2,3] соответственно.

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

(match
    (list 'cmd "MY SUPER COMMAND" (list 'params (list 1 2 3)) 'cmd_end)
    (
        (list 'cmd cmd_name (list 'params (cons first_param other_params)) 'cmd_end); <-- шаблон
        (list cmd_name first_param other_params) ; <-- функция-обработчик успешного результата

    )
)

c одним небольшим нюансом: sheme необходимо указывать функцию, которая бы сразу обработала эти параметры (при совпадении). Что особенно порадовало, так это наличие регулярных выражений в сравнении, т.е. такая конструкция работает:

(match
    (list 'cmd "MY SUPER COMMAND" (list 'params (list 1 2 3)) 'cmd_end)
    (
        (list 'cmd (regexp "SUPER(.*)" cmd_name) (list 'params (cons first_param other_params)) 'cmd_end); <--шаблон
        (list (cadr cmd_name) first_param other_params) ; <-- функция-обработчик успешного результата
    )
)

2. Легковесные процессы, отправка сообщений

это тоже приятная (и одна из основных) фишек erlang. так просто выглядит создание процесса на этом языке:
test_proc()->io:format("hello, world!~n").
Pid = spawn(fun test_proc/0).

отправка сообщений выглядит потрясающе: Pid ! message
например, Pid ! {hello, self()}

приём сообщений делается внутри порождаемой процедуры:
test_proc()->
        some_before_commands(),

        receive
            {Message, Pid}->io:format("received message ~s from ~w", [Message, Pid])
        end,
        some_after_commands(),
        test_proc().

При чём, как я понял, этот процесс встречая команду receive, ждёт сообщений (т. е. если бы после receive-ного end-а у нас стояли комманды, они бы не выполнились до того, как принято и обработано сообщение. Внутри блока receive идёт pattern matching сообщений, и если сообщение совпадает с шаблоном, то оно обрабатывается и управление передаётся за блок receive. Если же сообщение не попадает под шаблон, то, как я понял, ждём следующего сообщения, не передавая никуда управления.

в scheme создание потока тоже не отличается особой громоздкостью:
(define (test) (display "hello, world!") (newline) (test) )
(thread test)


сообщения так же поддерживаются =) называются mail-boxes
(define (test)
    (display "before") (newline)
    (let ((msg (thread-receive)))
        (display msg)

        (newline)
    )
    (display "after") (newline) (test)
)



(define t (thread test))
(thread-send t (list 'message 'main))


единственное, что не происходит pattern-matching для сообщения, но если необходимо, то можно просто добавить его вручную

НО. у erlanga очень хорошо обыграна связь между сообщениями. так, если процесс завершается, то он может послать связанным процессам сообщение о завершении, которые они обязаны будут обработать (иначе завершатся)
И ещё erlanga есть супервизоры, которые только и следят за жизнью процессов и (если необходимо) перезапускают их, но об этом в другой раз

Комментариев нет:

Отправить комментарий