переосмысление колес: Node.JS / Событийное программирование v.s. Функциональное программирование? - PullRequest
19 голосов
/ 08 декабря 2009

Теперь в последнее время появилось много шумихи по поводу Node.JS , управляемой событиями инфраструктуры, использующей обратные вызовы Javascript. Насколько я понимаю, его основное преимущество заключается в том, что вам не нужно ждать шаг за шагом последовательно (например, вы можете получить результаты SQL, , а вызывая другие функции тоже).

Итак, мой вопрос: чем это отличается или лучше, чем просто функциональные языки, такие как CL, Haskell, Clojure и т. Д.? Если не лучше, то почему бы тогда людям просто не использовать функциональные языки (вместо того, чтобы изобретать колесо с помощью Javascript )?

Обратите внимание, что у меня нет опыта ни в Node.JS, ни в функциональном программировании. Так что некоторые основные объяснения могут быть полезны.

Ответы [ 6 ]

33 голосов
/ 12 апреля 2010

Прочитав документы Node.JS (и красивую слайд-колоду ), я думаю, что в других ответах здесь не хватает смысла: Node.JS основан на идее, что стиль писать программы там, где мы ожидаем, что они блокируют ввод / вывод, неправильно, и вместо этого мы должны инициировать ввод / вывод (например, чтение базы данных или чтение сокета) и передать функцию для обработки результата ввода / вывода. вместе с просьбой.

Так что вместо этого:

var result = db.query("select.."); // blocking
// use result

Node.JS основан на идее сделать это:

db.query("select..", function (result) {
    // use result
});

Авторы (Node.JS) отмечают, что этот способ программирования очень неудобен во многих системах, поскольку языки не имеют замыканий или анонимных функций, а библиотеки в основном блокируют ввод / вывод. Тем не менее, Javascript предоставляет первое (и программисты привыкли к нему, учитывая, как JS используется в браузере как событие, подобно событию), а Node.JS заполняет позднее: будучи полностью управляемой событиями библиотекой ввода / вывода без блокирующих вызовов на все.

Как это связано с функциональным программированием? Все функциональные языки программирования предоставляют конструкции замыкания, достаточно мощные, чтобы делать то, что Node.JS пытается сделать с Javascript. Большинство из них облегчают кодирование, поскольку передача замыканий, как правило, является фундаментальной для языка.

Что касается Haskell, то, используя монады, подобные вещи можно очень легко построить. Например:

doQuery :: DBConnection -> IO ()
doQuery db = do
    rows <- query db "select..."
    doSomething rows
    doSomethingElse rows

Эти очень последовательные, обязательные строки кода на самом деле представляют собой последовательность замыканий, контролируемых монадой IO. Это как если бы в JavaScript вы написали:

db.query("select...", function (rows) {
    doSomething(rows, function () {
        doSomethingElse(rows, function () { /* done */ })
    })
})

По сути, при написании монадического кода на функциональном языке вы уже пишете его в форме, которую авторы Node.JS хотят, чтобы мы написали: где каждый шаг последовательного вычисления передается как завершение предыдущего. Однако посмотрите, насколько приятнее этот код в Haskell!

Кроме того, вы можете легко использовать параллельные функции Haskell, чтобы легко выполнить эту неблокирующую операцию:

forkQuery :: DBConnection -> IO ThreadId
forkQuery db = forkIO $ do
    rows <- query db "select..."
    doSomething rows
    doSomethingElse rows

Не путайте это forkIO с дорогой ветвью процесса, к которой вы привыкли, или даже с потоками процессов ОС. Это в основном та же легкая нить исполнения, которую использует Node.JS (только с несколько более богатой семантикой). Вы можете иметь их тысячи, как и на Node.JS.

Итак, вкратце - я думаю, что Node.JS основывается на объекте, который существует в JavaScript, но это гораздо более естественно в функциональных языках. Кроме того, я думаю, что все элементы, которые есть в Node.JS, уже существуют в Haskell и его пакетах, а затем и в некоторых. Для меня я бы просто использовал Haskell!

10 голосов
/ 08 декабря 2009

Я тоже не знаю о Node.JS, но я не вижу поразительного сходства между ним (из вашего описания) и функциональным программированием. Из вашего описания Node.JS, по-видимому, нацелен на помощь асинхронному программированию - поскольку вы заявляете, что «вам не нужно ждать последовательно, шаг за шагом», вы можете выполнять другие задачи, как одна долгосрочная задача делает свое дело.

Функциональное программирование полностью ортогонально этому, т. Е. Оно не имеет никакой связи с асинхронностью. Вы можете иметь одно без другого, или оба вместе, или ни один из них. Функциональное программирование направлено на устранение побочных эффектов в ваших программах и на то, чтобы позволить функциям, являющимся первоклассными членами языка, манипулировать и составлять аналогично другим значениям.

3 голосов
/ 08 декабря 2009

Это не совсем "изобретать велосипед". Javascript на самом деле не является функциональным языком как таковым, но он основан на Лиспе, и именно для этого он предназначен. На мой взгляд, Javascript действительно более силен как функциональный язык Lisp-ish, чем как ОО-язык. Вот почему фреймворки со строго функциональными * проектами, такими как jQuery, так хорошо вписываются в язык.

(* Примечание: не чисто, очевидно, но функционирует во многом так же, как Схема.)

1 голос
/ 28 мая 2010

Я еще не использовал node.js, но я определенно заинтересован в нем и скоро опробую его. Здесь уже есть много отличных ответов о функциональном программировании и тому подобное, поэтому я не буду вдаваться в подробности.

Вы спрашиваете, почему бы не использовать какой-либо другой язык на сервере, такой как haskell, Closure и т. Д. Для меня привлекательность node.js над другими заключается в том, что он является javascript. Мои приложения уже загружены на клиентском javascript, так что это означает, что я могу работать на одном языке как на сервере, так и на клиенте.

Я надеюсь, что это упростит и упростит разработку, потому что мне не нужно будет так резко менять контексты. Может даже произойти некоторое сокращение работы, если можно совместно использовать некоторую логику, которая используется как на клиенте, так и на сервере (возможно, код проверки формы и т. П.).

0 голосов
/ 09 июня 2010

Одним из главных преимуществ сужения разрыва между клиентом и сервером является возможность многократного использования кода на клиенте и сервере. Например, если вы хотите иметь богатый и динамичный веб-сайт AJAX для современных браузеров и урезанную версию для старых браузеров, вы можете использовать один и тот же код отображения для форматирования поступающих данных как на клиенте, так и на сервере.

Другие преимущества включают в себя возможность HTML5 / Google Gears / Adobe Air иметь локальную базу данных хранения и сервер для запуска веб-приложений в автономном режиме, вы можете иметь код, который традиционно будет храниться локально на сервере, если сервер не работает. имеется.

0 голосов
/ 12 апреля 2010

Ключевая роль Javascript в узле как веб-сервере заключается в том, что он в значительной степени определяется событиями.

Я полагаю, что функциональное программирование имеет преимущества для параллелизма из-за неизменности среди прочего.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...