如何在Erlang等函数式语言中使用缓存数据?

时间:2009-06-15 17:16:59

标签: functional-programming erlang immutability

我最近一直在阅读有关函数式语言的文章。在10多年的OO开发过程中,我发现很难理解人们如何能够指出纯函数式方法(即使用相同参数调用的相同方法也是如此在一个问题,通常(在OO程序中)我需要缓存数据。

  • 我们是否承认在程序中可能需要一个不可变的actor(即缓存)。我只是看了presentation by Joe Armstrong on infoq,他在这方面似乎非常教条!

  • 我们是否承认查找数据可能很昂贵(因为我们永远无法缓存它)?如果是这样,我们如何控制某些共享资源(例如数据库)上的负载

  • 是否有一些神奇的尘埃,我还不知道,这解决了整个问题,之后又喝了一杯茶。

当然谷歌搜索“Erlang Cache”似乎会返回一些结果......

3 个答案:

答案 0 :(得分:4)

Memoize the function。缓存只是一个列表/字典,因此可以以纯粹的功能方式实现。

答案 1 :(得分:3)

没有理由缓存和功能语言不能共存。为了实现功能,您只需遵守使用相同参数调用相同函数的约束,即可获得相同的答案。

例如:get_data(Query,CacheCriteria)

仅仅因为get_data使用缓存并不意味着它不起作用。只要使用相同的Query调用get_data,并且CacheCriteria参数始终返回相同的值,那么语言就可以被认为是有效的。

答案 2 :(得分:3)

这是必须在Erlang中不可变的数据,而不是演员。

长寿的演员通常生活在一个尾递归函数中,其参数作为状态,当然可以在不同的调用之间改变。

-module(cache).
-export([start/0, get_c/1, put_c/2, clear/1]).

start() -> register(spawn(fun () -> loop(dict:new()) end), cache).

loop(Dict) -> receive
                {get, From, Key} -> From ! {cache_result, Key, dict:fetch(Key, Dict)};
                {set, Key, Value} -> NewDict = dict:store(Key, Value, Dict),
                                     loop(NewDict);
                %% etc.
              end

put_c(Key, Value) -> cache ! {set, Key, Value}
%% etc.

当你致电put_c时,即使涉及的所有数据都是不可变的,演员的“状态”也会改变。