Схема PLT нуб:Логические и/или не являются процедурами?
Вопрос
Я пытаюсь создать генератор таблиц истинности для курса цифровой электроники, потому что именно так я развлекаюсь в свободное время и не осуждаю себя.
В любом случае, я решил, что у меня будет хэш со строковым эквивалентом операторов в качестве ключей и процедурами Scheme, которые соответствуют этим операторам в качестве значений.
Например.
(define operator-table #hash(("+" . or) ("*" . and)))
Поэтому я мог бы сделать что-то вроде
(lambda (a b) ((hash-ref operator-table (string-ref input-str i)) a b))
Теперь я понимаю, что вышеизложенное, вероятно, не будет работать правильно, но в нынешнем виде я даже не могу с этим повозиться, пока не сделаю это правильно, потому что, по-видимому, and
и or
являются особенными в Scheme.В REPL, если я наберу not
он отвечает #<procedure:not>
.Но если я дам это and
или or
, там говорится and: bad syntax in: and
.Есть ли версия процедуры and
Я могу использовать?Или мне нужно сделать один с lambda
?Или я что-то совсем упускаю?
Единственная причина, по которой я не стал использовать лямбду с самого начала, заключается в том, что я не хочу потерять возможности встроенной функции переменной арности. and
[Я могу сделать (and #t #f)
а также (and #t #f #f #t #f #t)
].
Решение
Если вы хотите использовать функциональную форму and
и or
(с тем ограничением, что они не будут замыкаться) и не потеряют свойство арности переменной, тогда вы легко можете это сделать:
(define (and* . xs) (andmap values xs))
(define (or* . xs) (ormap values xs))
(values
— это идиоматическая тождественная функция в схеме (PLT).)
Другие советы
Да, они не могут быть процедурами, потому что Scheme (как и большинство языков) является «нетерпеливым» языком: каждый аргумент процедуры оценивается до того, как процедура возьмет на себя управление (получит значения аргументов). and
и or
необходимо «короткое замыкание» — остановить вычисление аргументов, как только станет известен окончательный результат — чтобы они не могли быть обычными процедурами/функциями на любом активном языке («ленивые» языки, такие как Haskell — где каждый аргумент оценивается только в том случае, когда и по мере необходимости - это совсем другая порода, и не нуждаться это различие между «обычной функцией» и «специальной формой»…но, увы, Scheme не из таких!).