Хранение состояния в функциональных языках программирования
От: DemAS http://demas.me
Дата: 16.12.09 11:21
Оценка:
Допустим я пишу программу, которая, скажем, помогает создавать расписание занятий.

У меня есть такое понятие как занятие: преподаватель, предмет и время. Пусть это будет списком (Зайчиков, Ботаника, вторник).
Что будет перечнем занятий на неделю? Список списков? Ок:

((Зайчиков, Ботаника, вторник),
(Белочкина, Физкультура, среда)
(Бобров, Слово божие, суббота))

Идем дальше — создаем функцию, которая создает одно задание на основе ответов пользователя (синтаксис Clojure, но подойтет любой Lisp или Scheme):



(defn ask_var [prompt]
   (do
      (println prompt)
      (read-line)))

(defn ask_prepod [] 
   (ask_var "prepod: "))

(defn ask_subject [] 
   (ask_var "subject: "))

(defn ask_day [] 
   (ask_var "day: "))

(defn create_line [prepod subject day]
   (cons prepod subject day))

(defn ask_line []
   (create_line (ask_prepod) (ask_subject) (ask_day)))


Теперь я могу выполнить (ask_line) и получить один предмет, который будет запрошен у пользователя.
Теперь собственно сам вопрос — а как мне организовать хранение коллекции предметов?

В ООП я бы создал клас контейнер у которого бы дергал метод add(). Здесь нет объектов, нет даже глобальной переменной, в которой я бы мог хранить перечень занятий. А значит, единственный способ (как мне кажется) — это таскать этот список как параметр во всех методах. Что-то типа этого:


(defn start [] 
   (my_loop []))

(defn my_loop [lines]
   ...
   (if (= command "add")
      (my_loop (cons (ask_line) lines)))
   ....
   my_loop(lines)
)


Работает и даже пока терпимо, но если я чуть усложню задачу — введу подчиненные справочники предметов и преподавателей, календари и временные сетки и так далее — все эти сущности мне придется передавать как параметр своей функции my_loop, что превращает код в уродство.

Как принято поступать в таких случаях?

В Erlang, кстати, есть одно (более-менее красивое решение) — на каждую сущность завести свой процесс-модуль. Процесс который хранит перечень предметов, который принимает сигналы о добавлении/удалении предметов, процесс который отвечает за преподавателей и так далее. Плюс один процесс-менеджер, который организует работу с пользователем и обменивается сообщениями с другими процессами.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.