In a schema can be expressed as a combination of boolean operators?

It is easy to express and , or and not in terms of if (using local binding for or ). I would like to know if the opposite is true. My naive first attempt:

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

However, if test not #f , but conseq is #f , the translation evaluates to altern , which is incorrect.

Is there a translation that evaluates the correct value while preserving the nature of the if short circuit?

+4
source share
3 answers

It looks like you have a good explanation of why if does a little more than and and or . But if you can trick and add lambda to delay the actual result:

 (define-syntax-rule (if cte) ((or (and c (lambda () t)) (lambda () e)))) 
+4
source

Try (or (and test conseq) (and (not test) altern)) as a generic template. Denying test in the second and , he guarantees that the external conseq will be either conseq ∨ #f if test is true, or #f ∨ altern if test is false.

+2
source

This is the same as Eli Barzilay's answer, but instead of wrapping it in lambda, I will wrap it in a list of 1 element

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

By the way, Python before 2.5 had this exact problem. There was no good way to write a conditional expression (i.e. test ? conseq : altern in C, which is if in the schema) in Python. The simplest attempt was

 test and conseq or altern 

which worked in most cases but failed when conseq is considered false in Python (i.e. False, 0, empty list, empty string, etc.). What kind of problem did you find above. The fix was to wrap it in a list (non-empty lists are always true) and extract it again:

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

which looks ugly. That's why they added the conseq if test else altern in Python 2.5.

+1
source

Source: https://habr.com/ru/post/1338446/


All Articles