锁定老帖子 主题:关于函数式编程中函数不产生副作用的困惑
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-12-21
我对这点有不理的地方。比如对于生产者,消费者问题,用函数式编程如何解决?因为没有类成员或全局变量可以被改变,那么用什么功能来表示那个容纳生产者生产出来的产品的容器呢? 最起码生产者身产了产品后需要改变容器的值,而消费者读取了容器的产品后也要改变容器的值。函数式编程的每一个符号都是 final 的是否意味着这个容器也是不可改变的?如果不可改变那么用函数式编程如何实现生产者,消费者问题? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-12-21
这两种概念是正交的.
|
|
返回顶楼 | |
发表时间:2006-12-21
虽然已知lambda等价图灵机,试试写一个出来还是很有意思的:
Producter.createProducter("producter 1").notify(message,Consumer.create("No.1"),Consumer.create("No.2")....) define producter.nofiy: params.ifExist().next().invokeConsumeMessage(message).ifExist().next().invokeConsumMessage(message)...好变态! |
|
返回顶楼 | |
发表时间:2006-12-21
wolfsquare 写道 这两种概念是正交的.
麻烦讲的再清楚一些,木有看懂,谁和:函数不产生副作用是正交的。 你的代码也木有看懂:( 可以讲清楚点么? |
|
返回顶楼 | |
发表时间:2006-12-21
消息通信机制实现一个简单的生产者消费者问题,貌似复杂了点
-module(demo). -export([main/0]). -export([producer/2,consumer/1,queue/2]). producer(QueuePid, Id) -> timer:sleep(500), QueuePid ! {produce, Id}, io:format("Producer:Put Produce ~p~n", [Id]), producer(QueuePid, Id+1). consumer(QueuePid) -> QueuePid ! {get_produce, self()}, receive {produce, ProduceId} -> io:format("Consumer:Get Produce ~p~n", [ProduceId]); any -> ok end, timer:sleep(600), consumer(QueuePid). queue(List, []) -> io:format("Queue:List is ~p~n", [List]), receive {produce, ProduceId} -> queue(List ++ [ProduceId], []); {get_produce, ConsumerPid} -> case List of [] -> queue([], [ConsumerPid]); [H|T] -> ConsumerPid ! {produce,H}, queue(T, []) end end; queue([], WaitingConsumerPids) -> io:format("Queue:Waiting consumers size is ~p~n", [length(WaitingConsumerPids)]), receive {produce, ProduceId} -> [H|T] = WaitingConsumerPids, H ! {produce, ProduceId}, queue([],T); {get_produce, ConsumerPid} -> queue([], WaitingConsumerPids ++ [ConsumerPid]) end. main() -> QueuePid = spawn(?MODULE, queue, [[], []]), spawn(?MODULE, consumer, [QueuePid]), spawn(?MODULE, producer, [QueuePid, 0]). |
|
返回顶楼 | |
发表时间:2006-12-21
这就是传说中的Erlang?
|
|
返回顶楼 | |
发表时间:2006-12-22
对于命令式的优点,函数语言当然不会做事不管。在Haskel中,通过构造monad可以获得普通命令式的副作用功能。其中state monad就是很好的例子。
可以看看这里,描述state monad,且有一个示列程序:http://bbs.btant.com/thread-409-1-1.html |
|
返回顶楼 | |
发表时间:2006-12-29
没有副作用也就是不改变世界
|
|
返回顶楼 | |
发表时间:2007-06-07
靠monad是一个有效率保证的手段。其实,在解决必须要改变状态的问题时,FP 采取的手段是:不停的产生新的、拥有已改变过属性的对象(此时原对象不变),然后利用函数的参数为此对象添加与原对象相同的名字(但二者不再同一层空间中),再去操作这个对象,如此反复(所以,正则尾递归是至关重要的)。
看起来这样做效率低下,但如果使用编译型的FP语言时会发现几乎没有性能损失(具体优化措施见《现代编译原理》一书),差别仅在于是用栈分配还是堆分配。 在解决IO问题上,Haskell为方便起见还是用了monad。但真正应该作的是,使用延续(不停地用上文中的方法绑定函数的编程风格):每一次I/O都返回下一次IO要用到的另一个函数。这样每个函数的状态都不变(支持等式推理,即函数的参数->值维持数学映射),整个IO过程却完成了。 |
|
返回顶楼 | |
发表时间:2007-07-18
javavsnet 写道 因为函数式编程的每一个符号都是 final 的,没有函数产生过副作用。因为从未在某个地方修改过值,也没有函数修改过在其作用域之外的量并被其他函数使用(如类成员或全局变量)。
我对这点有不理的地方。比如对于生产者,消费者问题,用函数式编程如何解决?因为没有类成员或全局变量可以被改变,那么用什么功能来表示那个容纳生产者生产出来的产品的容器呢? 最起码生产者身产了产品后需要改变容器的值,而消费者读取了容器的产品后也要改变容器的值。函数式编程的每一个符号都是 final 的是否意味着这个容器也是不可改变的?如果不可改变那么用函数式编程如何实现生产者,消费者问题? 容器不可改变,但是可以被丢弃的,然后用新的容器替代它。 这个方式的关键是确定什么时候完全丢弃旧容器,这比较影响时间和空间效率。 |
|
返回顶楼 | |