Reputation: 13199
I am learning Erlang and I am trying to create a very sample blog program. However my mind currently is trapped in the OO world (var p = new Post(); p.Title = ""; p.Save();). I would like to understand some basic thinkings in Erlang. Instead of creating Post object what I should do in terms of data structure (p.Title, p.DateCreated, p.Body)? Should I be using tuple? I would like to understand the recommended way in doing such things (in both Erlang specific and or Functional Programming specific). Or is what I am doing fundamentally wrong in either Erlang or FP?
Requirement (in OO terms, not sure how to explain in FP terms yet ^_^):
Thanks.
Updated: I am not looking for specific way of doing OOP in Erlang unless it's the recommended way. I am looking for standard/recommended way of doing what's described in the question, however I am not trying to replicate OOP in Erlang.
Upvotes: 13
Views: 2535
Reputation: 1585
OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.
Alan Kay is the creator of Smalltalk together with Dan Ingalls. If you look at Smalltalk it becomes clear what he means with messaging: a message is sent to some receiver object like aBumblebee.fly(). I've developed almost 10 years with Smalltalk. I know a bit how it is designed. But what is done in Erlang is fly(aBumblebee) where aBumblebee is also not an instance of a class.
I'm not sure about this, but when you look at actors in Erlang they also don't seem to exchange messages. As I understand Erlang so far this receive { case { ... } } construction is because the messages have to be retrieved from some list. There is no other way to send it to the recipient actor.
If Erlang were OO there would also be no need for these when-case statements. They are necessesary, because there is no late binding. There is dynamic invocation in Erlang, yes. But no dynamic dispatch of messages and that is what late binding is about: the function pointer to jump to is not defined at compile time but looked up at runtime. Since all functions in Erlang are kind of global, there is no lookup from some class needed anyway. Also, I don't see in what way protection exists in Erlang. How do you provide encapsulation if there is no class, module or something? For a record all fields are public.
Upvotes: 0
Reputation: 750
I would use records:
-record(post, {title, date_created, body, comments = []}).
-record(comment, {created_by, date_created, content}).
Then if you want to use mnesia as database:
Post = #post{title = "", body = "", date_created = erlang:universaltime()},
mnesia:transaction(fun() -> mnesia:write(Post) end).
To add a comment:
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).
I haven't tested the code, but this is what I would do. Also I assumed that each title is unique.
Upvotes: 5
Reputation: 9486
Your example doesn't really represent good OO style. Comments appear on already published blog posts, so by then you just have some kind of reference to the post id the comment is posted to.
For OO programming it would make more sense to have some kind of BlogDb object that one send post and comment objects to. A comment object needs to know what post id it is a comment to. You should not create post and comment objects using the 'new' operator, instead the BlogDb interface has methods that return fresh instances of those.
Suddenly you have a passable way to implement just the same thing in Erlang. Start a gen_server that is the blog_db. Do things like
Post = myblog:post(Title, Body),
{ok, Result} = myblog:add_post(BlogDb, Post),
...
You don't need to know the details of the Post value, so how it is constructed is hidden in a "constructor" for it in another module.
Upvotes: 0
Reputation: 27174
Erlang is an Object Oriented language. This statement has more power if you look at OOP the way Alan Kay described it:
OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.
As you must be aware, Erlang promotes a style of programming called Concurrency Oriented Programming, in which you abstract away objects as independent processes that communicate by message passing. Each process has it's local state, they live in their own parallel world. Dynamic polymorphism is achieved by the fact that, you can define a class of processes that can respond to a common set of messages. As Erlang 'objects' live in their own tiny process, it becomes a natural medium for modelling the real-world. You can make use of your OOP skills better in Erlang than in any other language.
Can't give a full description about OOP in Erlang in such a small space. I suggest that you read the book Programming Erlang: Software for a Concurrent World.
Also see these links:
Upvotes: 7