Я смотрю на функциональное программирование и борюсь с одной точкой.. Как я делаю следующее без изменяемого состояния?
Предположите, что у меня есть сервер.. и клиенты пытаются соединиться.. и каждый клиент дает серверу число и сказан текущее общее количество.
Теперь без изменяемого состояния сервер не может сохранить общее количество..., таким образом, я думаю, что каждый клиент действительно создает новый сервер, содержащий новое общее количество.. или может быть вычислен новый сервер, содержащий запись и ссылающийся на старый сервер так общее количество.
НО.. как клиент находит сервер? Кто-то должен держать на текущий экземпляр сервера.. таким образом, у них есть изменяемый переменный 'сервер'.
Независимо от того, что я делаю.. Я всегда заканчиваю с изменяемой переменной более высокий объем.
Мысли?
Описанный вами сценарий может быть реализован следующим образом (псевдокод):
let keepTrackOfTotal(total) =
let conn = waitForConnection()
let x = readIntFrom(conn)
let newTotal = total + x
writeIntTo(conn, newTotal)
keepTrackOfTotal(newTotal)
let main() = keepTrackOfTotal(0)
Здесь мы используем рекурсию, чтобы получить бесконечный цикл, который отслеживает общее количество без изменяемых переменных.
По крайней мере, в Erlang это делается так, что сам процесс имеет имя.
Таким образом, пока цикл сервера постоянно запускает новые версии самого себя (вызывая ту же функцию в конце вызова, как в отличном псевдокоде sepp2k) и вводя сумму в качестве параметра, все ваши клиенты связываются с этим процессом. по имени, чтобы они все еще могли его найти.
Примерно так (на C ++). У нас есть сервер со статическим указателем, каждый экземпляр объекта сервера неизменен
#include <pthread.h>
#include <iostream>
#include <stdlib.h>
#include <memory>
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
class Server
{
public:
Server(int n) : m_n(n){}
static void Add(int n)
{
pthread_mutex_lock( &mutex1 );
std::auto_ptr<const Server> srv(getInstance());
server = new Server(srv->m_n + n);
pthread_mutex_unlock( &mutex1 );
}
static int GetTotal()
{
std::auto_ptr<const Server> srv(getInstance());
return srv->m_n;
}
private:
static const Server* getInstance()
{
if (server == NULL)
server = new Server(0);
return new Server(server->m_n);
}
static volatile const Server* server;
int const m_n;
};
volatile const Server* Server::server = NULL;
Каждый вызов getInstance () возвращает неизменяемый объект Server. Вы можете вызвать метод GetTotal (), когда другой поток работает в методе Add.