Ссылочная прозрачность означает, что если вы связываете некоторую переменную x
с выражением e
, вы можете заменить все вхождения x
на e
без изменения результата. Например:
(let ((e (* pi 2)))
(list (cos e) (sin e)))
Выше можно написать:
(list (cos (* pi 2))
(sin (* pi 2)))
Полученное значение эквивалентно первому для некоторого полезного определения эквивалентности (здесь equalp
, но вы можете выбрать другое). Сравните это с:
(let ((e (random))
(list e e))
Здесь выше, каждый вызов random
дает различный результат (статистически), и, таким образом, поведение отличается, если вы повторно используете один и тот же результат несколько раз или генерируете новый после каждого вызова.
Специальные переменные похожи на дополнительные аргументы для функций, они могут влиять на результат результата, просто будучи привязанными к различным значениям. Рассмотрим *default-pathname-defaults*
, который используется для построения путей.
Фактически, для данной привязки этой переменной каждый вызов (merge-pathnames "foo")
возвращает один и тот же результат. Результат изменяется, только если вы используете одно и то же выражение в другом динамическом контексте, что ничем не отличается от вызова функции с другими аргументами.
Основная трудность заключается в том, что специальная переменная скрыта, т. Е. Вы можете не знать, что она влияет на некоторые выражения, и поэтому вам нужны их документированные и ограниченные по количеству.
Что нарушает ссылочную прозрачность, так это наличие побочных эффектов, используете ли вы лексические или специальные переменные. В обоих случаях место изменяется как часть выполнения функции, что означает, что вам нужно учитывать , когда и , как часто вы его называете.
У вас могли бы быть лучшие предложения, если бы вы немного объяснили, как организован ваш код. Вы сказали, что у вас много специальных переменных из-за prototyping , но при рефакторинге, который вы хотите сделать, это выглядит так, как будто вы хотите сохранить прототипный код в основном нетронутым. Может быть, есть способ упаковать вещи хорошим модульным способом, но мы не можем помочь, не зная больше о том, зачем вам нужно много специальных переменных и т. Д.