В Схеме можно ли выразить как комбинацию логических операторов? - PullRequest
4 голосов
/ 04 февраля 2011

Легко выразить and, or и not в терминах if (с помощью локальной привязки для or).Я хотел бы знать, верно ли обратное.Моя наивная первая попытка:

(if test conseq altern) => (or (and test conseq) altern)

Однако, если test не #f и conseq равно #f, перевод оценивается как altern, что неверно.

Существует ли перевод, который оценивает правильное значение при сохранении природы короткого замыкания if?

Ответы [ 3 ]

4 голосов
/ 04 февраля 2011

Похоже, у вас есть хорошее объяснение, почему if делает чуть больше, чем and и or.Но если бы вы могли обмануть и добавить lambda, чтобы отложить фактический результат:

(define-syntax-rule (if c t e) ((or (and c (lambda () t)) (lambda () e))))
2 голосов
/ 04 февраля 2011

Попробуйте (or (and test conseq) (and (not test) altern)) в качестве общего шаблона. Отрицая test во втором and, он гарантирует, что внешняя дизъюнкция будет либо conseq#f, если test истинно, либо #faltern, если test ложно.

1 голос
/ 04 февраля 2011

Это то же самое, что и ответ Эли Барзилай, за исключением того, что вместо того, чтобы заключить его в лямбду, я заключаю его в список из 1 элемента

(if test conseq altern) => (car (or (and test (list conseq)) (list altern)))

Кстати, в Python до 2.5 была именно эта проблема. Не было хорошего способа написать условное выражение (то есть test ? conseq : altern в C, что и есть if в Scheme) в Python. Самая простая попытка была

test and conseq or altern

, который работал в большинстве случаев, но потерпел неудачу, когда conseq считается ложным в Python (то есть False, 0, пустой список, пустая строка и т. Д.). Какую именно проблему вы обнаружили выше. Исправление состояло в том, чтобы обернуть его в список (непустые списки всегда верны) и извлечь его снова:

(test and [conseq] or [altern])[0]

что выглядит ужасно. Вот почему они добавили синтаксис conseq if test else altern в Python 2.5.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...