Допустим я пишу программу, которая, скажем, помогает создавать расписание занятий.
У меня есть такое понятие как занятие: преподаватель, предмет и время. Пусть это будет списком (Зайчиков, Ботаника, вторник).
Что будет перечнем занятий на неделю? Список списков? Ок:
((Зайчиков, Ботаника, вторник),
(Белочкина, Физкультура, среда)
(Бобров, Слово божие, суббота))
Идем дальше — создаем функцию, которая создает одно задание на основе ответов пользователя (синтаксис 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, кстати, есть одно (более-менее красивое решение) — на каждую сущность завести свой процесс-модуль. Процесс который хранит перечень предметов, который принимает сигналы о добавлении/удалении предметов, процесс который отвечает за преподавателей и так далее. Плюс один процесс-менеджер, который организует работу с пользователем и обменивается сообщениями с другими процессами.