Как использовать кешированные данные на функциональном языке, таком как Erlang?
В последнее время я немного читал о функциональных языках. Начиная с 10 лет развития OO, мне трудно понять, как на земле можно указать чистый функциональный подход (т.е. Тот же метод, называемый с теми же параметрами, делает то же самое) при проблеме, где обычно (в программе OO) мне нужно будет кэшировать данные.
-
Допустим ли мы, что в программе может быть актер, который не является неизменным (т.е. кеш). Я просто смотрел презентацию Джо Армстронга на infoq, и он казался довольно догматичным в этом отношении!
-
Допустим ли мы, что поиск данных может быть дорогостоящим (потому что мы никогда не можем его кэшировать)? Если да, то каким образом мы можем управлять, например, загрузкой какого-либо общего ресурса (например, базы данных).
-
Есть ли какая-то волшебная фея, о которой я еще не знаю, которая решает всю проблему, а затем делает приятную чашку чая.
Конечно, поиск Google для "Erlang Cache", кажется, возвращает справедливые результаты...
Ответы
Ответ 1
Это данные, которые должны быть неизменными в Эрланге, а не в актерах.
Долгоживущие актеры обычно живут в хвостовой рекурсивной функции, аргументы которой служат их состоянием и, безусловно, могут меняться между вызовами.
-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
, состояние "актер" изменяется, хотя все задействованные данные неизменяемы.
Ответ 2
Запомните функцию. Кэш - это просто список/словарь и, следовательно, может быть реализован исключительно функционально.
Ответ 3
Нет причин, чтобы кэш и функциональный язык не могли жить вместе. Чтобы быть функциональным, вам просто нужно подчиниться ограничению, вызывающему одну и ту же функцию с теми же аргументами, что и тот же ответ.
Например: get_data (Query, CacheCriteria)
Просто потому, что get_data использует кеш, это не значит, что он не работает. Пока вызывается get_data с тем же Query, а аргументы CacheCriteria всегда возвращают одно и то же значение, тогда язык можно считать функциональным.