For example, we can write down
(and #t 1 0) ; 0
(and 1 #t 0) ; 0
(and 1 0 #t) ; #t
(or 0 #t #f) ; 0
(or #t 0 #f) ; #t
(or #t #f 0) ; #t
I think these are two questions
- why they accept non-boolean?
- how should I interpret results in the mind model?
For example, we can write down
(and #t 1 0) ; 0
(and 1 #t 0) ; 0
(and 1 0 #t) ; #t
(or 0 #t #f) ; 0
(or #t 0 #f) ; #t
(or #t #f 0) ; #t
I think these are two questions
https://docs.racket-lang.org/guide/conditionals.html should be able to answer both of your questions.
emmm...yes, but still think it's weird XD.
The key thing here is that and and or are not logical operators.
They are instead "short-circuting" operators, which means they don't evaluate all arguments if the result is clear from the first arguments.
The or operation returns the first "true" (non-false) value.
> (or #f #t (/ 1 0))
#t
The evaluation was "short-circuited" in the sense that (/ 1 0) was never evaluated.
The second thing to keep in mind is that #f is the only false value and all other values count as true.
This variation of the first example shows that #t can be replaced with any non-false value:
> (or #f 42 (/ 1 0))
42
In short:
or operation returns the first "true" (non-false) value.#f.Similarly:
and operation returns the last "true" value, if all arguments are "true".#f.An common use of and is:
(and <check-some-condition> <evaluate-expression>)
where the expression would result in an error, of the condition isn't met.
See more on short-circuiting here:
One special case of
(and <check-some-condition> <evaluate-expression>)
that I find interesting is using
(and <some-value> #t)
to "convert" any "true" value to #t. In other words, with this expression the result will be either #t or #f (the latter if <some-value> is #f).