Erlang (функциональное программирование) против объектно-ориентированного программирования с точки зрения мышления - PullRequest
13 голосов
/ 30 ноября 2009

Я изучаю Erlang и пытаюсь создать очень типичную программу для блогов. Однако мой разум в настоящее время пойман в ловушку в мире OO ( var p = new Post (); p.Title = ""; p.Save (); ). Я хотел бы понять некоторые основные мысли в Erlang. Вместо того чтобы создавать объект Post, что мне следует делать с точки зрения структуры данных ( p.Title, p.DateCreated, p.Body )? Должен ли я использовать кортеж? Я хотел бы понять рекомендуемый способ делать такие вещи (как в специфичном для Erlang, так и в специфическом для функционального программирования). Или то, что я делаю, в корне неверно в Erlang или FP?

Требование (в терминах ОО, пока не знаю, как объяснить в терминах ФП ^ _ ^):

  1. создать объект Post (id, title, date_created, body, IList)
  2. создание объекта комментария (id, post_id, creation_by (имя в виде строки), date_created)
  3. одна запись может иметь несколько комментариев
  4. post.AddComment (Комментарий)

Спасибо.

Обновлено: Я не ищу конкретный способ сделать ООП в Эрланге, если это не рекомендуемый способ. Я ищу стандартный / рекомендуемый способ сделать то, что описано в вопросе, однако я не пытаюсь копировать ООП в Erlang.

Ответы [ 4 ]

6 голосов
/ 30 ноября 2009

Erlang - объектно-ориентированный язык. Это утверждение имеет большую силу, если вы посмотрите на ООП так, как его описал Алан Кей:

ООП для меня означает только обмен сообщениями, локальный сохранение и защита и сокрытие состояние процесса и экстрим поздняя привязка всех вещей.

Как вы должны знать, Erlang продвигает стиль программирования под названием Параллельное программирование , в котором вы абстрагируете объекты как независимые процессы, которые обмениваются сообщениями. Каждый процесс имеет свое локальное состояние, они живут в своем параллельном мире. Динамический полиморфизм достигается тем, что вы можете определить класс процессов, которые могут отвечать на общий набор сообщений. Поскольку «объекты» Эрланга живут в своем собственном крошечном процессе, он становится естественной средой для моделирования реального мира. Вы можете использовать свои навыки ООП лучше в Erlang, чем на любом другом языке.

Не могу дать полное описание ООП в Эрланге в таком маленьком пространстве. Я предлагаю вам прочитать книгу Программирование на Erlang: программное обеспечение для параллельного мира .

Также смотрите эти ссылки:

5 голосов
/ 30 ноября 2009

Я бы использовал записи:

-record(post, {title, date_created, body, comments = []}).
-record(comment, {created_by, date_created, content}).

Тогда, если вы хотите использовать mnesia в качестве базы данных:

Post = #post{title = "", body = "", date_created = erlang:universaltime()},
mnesia:transaction(fun() -> mnesia:write(Post) end).

Чтобы добавить комментарий:

Comment = #comment{created_by = "", content = "", date_created = erlang:universaltime()},
mnesia:transaction(fun() ->
    [Post] = mnesia:read(post, Title),
    PostWithNewComment = Post#post{comments = [Comment | Post#post.comments]},
    mnesia:write(PostWithNewComment)
end).

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

0 голосов
/ 09 ноября 2012

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

Алан Кей является создателем Smalltalk вместе с Дэном Ингаллсом. Если вы посмотрите на Smalltalk, станет ясно, что он имеет в виду под обменом сообщениями: сообщение отправляется какому-либо получателю, например aBumblebee.fly (). Я разработал почти 10 лет с Smalltalk. Я немного знаю, как он устроен. Но в Erlang делается муха (aBumblebee), где aBumblebee также не является экземпляром класса.

Я не уверен в этом, но когда вы смотрите на актеров в Эрланге, они тоже не обмениваются сообщениями. Насколько я понимаю, Эрланг до сих пор использует конструкцию получения {case {...}}, потому что сообщения должны быть получены из некоторого списка. Нет другого способа отправить его актеру-получателю.

Если бы Эрланг был ОО, то также не было бы необходимости в этих утверждениях когда дело. Они необходимы, потому что нет позднего связывания. Да, в Erlang есть динамический вызов. Но никакой динамической отправки сообщений нет, и это то, что означает позднее связывание: указатель на функцию, к которому нужно перейти, не определяется во время компиляции, а просматривается во время выполнения. Поскольку все функции в Erlang являются глобальными, поиск какого-либо класса в любом случае не требуется. Кроме того, я не вижу, каким образом существует защита в Эрланге. Как обеспечить инкапсуляцию, если нет класса, модуля или чего-то еще? Для записи все поля являются открытыми.

0 голосов
/ 30 ноября 2009

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

Для ОО-программирования было бы более разумно иметь некоторый объект BlogDb, к которому можно было бы отправлять объекты постов и комментариев. Объект комментария должен знать, к какому идентификатору записи относится комментарий. Не следует создавать объекты записей и комментариев с помощью оператора «new», вместо этого в интерфейсе BlogDb есть методы, которые возвращают их свежие экземпляры.

Внезапно у вас есть приемлемый способ реализовать то же самое в Erlang. Запустите gen_server, который является blog_db. Делайте такие вещи, как

Post = myblog:post(Title, Body),
{ok, Result} = myblog:add_post(BlogDb, Post),
...

Вам не нужно знать детали значения Post, поэтому способ его построения скрыт в «конструкторе» для него в другом модуле.

...