Здравствуйте, _hum_, Вы писали:
__>Стоит задача создания специализированного языка для задания программы действий некоторому устройству по схеме: фиксируемая ситуация -> действие на нее. При этом ставятся ограничения, чтобы язык был достаточно простым для обучения и экспрессивным (программы на нем просты и читабельны). Выбрал декларативный подход (без использования понятия именованных изменяемых ячеек памяти) с реализацией просто по схеме: задается логическое условие на ситуацию и после него прописывается действие. Но столкнулся со следующей трудностью. Мне нужно, чтобы в этом языке можно было легко задавать следующее условие: "для определения ситуации вычисли данное выражение E в контексте С1, затем в контексте C2 и сравни результат". Вопрос, как в декларативном программировании проще и естественнее ввести понятие контекста (будет ли это тогда вообще декларативным программированием?). Какие подводные камни здесь могут быть (по аналогии с подводными камнями в виде побочных эффектов в нечистых функциональных языках программирования). Может быть, есть какой-то известный язык, где подобное реализовано?
Если явная передача контекста в каждое вычисление слишком замусоривает код, то можно посмотреть в сторону монады Reader (Хаскелл). С помощью нее легко описать вычисление, допускающее чтение значений из заданного окружения (контекста).
type User = String
type Password = String
type UsersTable = [(User,Password)]
-- контекстом служит таблица
pwds :: UsersTable
pwds = [("Bill","123"),("Ann","qwerty"),("John","2sRq8P")]
-- возвращает длину пароля пользователя или -1, если такого пользователя нет
getPwdLen :: User -> Reader UsersTable Int
getPwdLen person = do
mbPwd <- asks $ lookup person
let mbLen = fmap length mbPwd
let len = fromMaybe (-1) mbLen
return len
Используем
> runReader (getPwdLen "Ann") pwds
6
> runReader (getPwdLen "Ann") []
-1