Functional programming 从思维角度看Erlang(函数式编程)与面向对象编程
我正在学习Erlang,并试图创建一个非常简单的博客程序。然而,我的思维目前被困在OO世界中(var p=new Post();p.Title=“”;p.Save();)。我想了解一些关于二郎的基本想法。在数据结构(p.Title,p.DateCreated,p.Body)方面,我应该做什么来代替创建Post对象?我应该使用tuple吗?我想了解做这些事情的推荐方法(特定于Erlang和/或特定于函数式编程)。还是我在Erlang或FP中所做的根本错误 需求(用OO术语,不确定如何用FP术语解释):Functional programming 从思维角度看Erlang(函数式编程)与面向对象编程,functional-programming,erlang,oop,Functional Programming,Erlang,Oop,我正在学习Erlang,并试图创建一个非常简单的博客程序。然而,我的思维目前被困在OO世界中(var p=new Post();p.Title=“”;p.Save();)。我想了解一些关于二郎的基本想法。在数据结构(p.Title,p.DateCreated,p.Body)方面,我应该做什么来代替创建Post对象?我应该使用tuple吗?我想了解做这些事情的推荐方法(特定于Erlang和/或特定于函数式编程)。还是我在Erlang或FP中所做的根本错误 需求(用OO术语,不确定如何用FP术语解释
- (采访)
- 您的示例并不真正代表良好的OO风格。评论会出现在已经发布的博客帖子上,因此到那时,您只需要对该评论发布到的帖子id进行某种引用
对于OO编程来说,使用某种BlogDb对象将post和comment对象发送给它更有意义。注释对象需要知道它是要注释的帖子id。您不应该使用“new”操作符创建post和comment对象,相反,BlogDb接口具有返回这些对象的新实例的方法
突然间,您有了一种在Erlang中实现相同功能的可行方法。启动博客数据库的gen_服务器。做像这样的事情
Post = myblog:post(Title, Body),
{ok, Result} = myblog:add_post(BlogDb, Post),
...
您不需要知道Post值的详细信息,因此它的构造方式隐藏在另一个模块中的“构造函数”中。我将使用记录:
-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).
我还没有测试代码,但这就是我要做的。我还假设每个标题都是唯一的
OOP对我来说只意味着消息传递、本地保留、保护和隐藏状态进程,
以及所有东西的极端后期绑定
艾伦·凯和丹·英格尔是Smalltalk的创始人。如果你看一下Smalltalk,就会明白他在消息传递中的意思:消息被发送到某个接收方对象,比如aBumblebee.fly()。我在Smalltalk工作了将近10年。我对它的设计略知一二。但在Erlang中所做的是fly(aBumblebee),其中aBumblebee也不是类的实例
我不确定这一点,但当你观察Erlang中的演员时,他们似乎也不会交换信息。据我所知,Erlang到目前为止这种receive{case{…}}结构是因为必须从某个列表中检索消息。没有其他方法将其发送给收件人参与者
如果Erlang是OO,那么在case语句中也不需要这些语句。它们是必需的,因为没有后期绑定。Erlang中有动态调用,是的。但是没有消息的动态调度,这就是后期绑定的意义:要跳转到的函数指针不是在编译时定义的,而是在运行时查找的。由于Erlang中的所有函数都是某种全局函数,因此无论如何都不需要从某个类进行查找。另外,我不知道Erlang中存在什么样的保护。如果没有类、模块或其他东西,如何提供封装?对于记录,所有字段都是公共的。可以使用元组代替对象,但使用记录可能更清晰。(在Erlang中记录会转换成元组。)@Nate谢谢你,因为我以前不知道这个关键字。这里有一个顶级谷歌搜索结果仅供参考@Nate私有状态和方法是如何使用记录表示的?你能解释一下如何有效地使用记录来代替类、接口等吗?@杰夫瑞:在OO术语中,你想把所有的对象都存储在内存中,用指针来表示,或者你认为把它们存储在某种类型的数据库中(也许使用ORM)?@ ZED,现在,为了学习目的,我不会接触数据库。方法、私有状态等呢?可以创建一个模块并导出这些函数:post:save(Title,Body)->ok{error,Reason}。post:save_comment(postitle,CommentBody,CreatedBy)->ok{error,Reason}我不知道你说的“私人”是什么意思state@TP问题是如何在Erlang中进行OOP。如何使用Erlang模拟具有状态和方法的对象,同时对对象的用户隐藏细节?(当然,Erlang中没有可变状态,但对象的用户不需要知道它是如何