Долго не мог понять, каую же магию таят в себе чистые функции, и вот наконец проблеск:
(and state1 state2 (change-state)
; этот код может изменить состояние
; мы можем написать этот код в более привычно-костыльной форме:
(if (and state1 state2) (change-state))
; суть от этого не меняется
; этот код основывается на сайд-эффектах и сам создает его
; оформим его в виде функции
(define code (lambda() (and state1 state2 (change-state))))
; теперь мы можем менять состояние делая вызов функции - мы добились просто более краткой записи кода, но пока у нас нет никакой абстракции.
; ту же функцию мы могли бы записать так:
(define code (lambda() (and (get-state1) (get-state2) (change-state))))
; это ничего не меняет, ненужное усложненние
; eсли в нашем приложении имеют значение только эти 3 состояния, то такой код нас устроит во всех отношениях
; однако если у нас есть разные программные объекты которые пользуются тем же принципом, "если это и это тогда это", мы должны обобщить это в виде функции:
(define sup-code (lambda(x y) (and (get-state x) (get-state y) (change-state))))
; данная абстракция не использует напрямую сайд-эффекты, но все еще сама является источником его, исправим это
(define sup-code (lambda(x y z state) (and (get-state x) (get-state y) (z state))))
; мы получили абстракцию которая сама может быть объектом манипуляций, и до тех пор пока она является объектом манипуляций, она не вызовет сайд-эффектов. Если же она будет вызвана, посредством своих аргументов, она создаст сайд-эффекты. Иными словами мы получили СЛОЙ АБСТРАКЦИИ!!!