Почему «и» и «или» предоставляют эти результаты после получения списков?

#list #functional-programming #lisp #racket #sicp

#Список #функциональное программирование #lisp #ракетка #sicp

Вопрос:

Я использую Racket и Dr. Racket в образовательных целях.

После следующих определений переменных «x» и «y»:

 (define x (list 1 2 3))
(define y (list 4 5 6))
 

Я решил создать 3 разных списка, используя эти переменные.

Первый:

 (append x y)

>> '(1 2 3 4 5 6)
 

Второй:

 (cons x y)

>> '((1 2 3) 4 5 6)
 

Третье:

 (list x y)

>> ((1 2 3) (4 5 6))
 

После этого я решил использовать логические операторы «и» и «или» с тремя списками. Что меня удивило, так это результат. Почему это происходит? Почему «или» и «и» выбирают один из списков? Какое соотношение стоит за этим решением?

 (and (append x y) (cons x y) (list x y))

>> '((1 2 3) (4 5 6))

(or (append x y) (cons x y) (list x y))

>> '(1 2 3 4 5 6)
 

Ответ №1:

Это просто: and возвращает значение последнего выражения, которое является истинным, или #f если хотя бы одно выражение является ложным, тогда or как возвращает значение первого выражения, которое является истинным, или #f если все они ложны.

Помните: в Scheme единственным значением false является значение #f false , тогда как все остальное считается true, поэтому мы используем прозвище «truthy» — для обозначения значения, не являющегося false. В частности, в вашем коде это:

 (and (append x y) (cons x y) (list x y))
 

Возвращает значение последнего истинного выражения: (list x y) , тогда как это:

 (or (append x y) (cons x y) (list x y))
 

Возвращает значение первого истинного выражения: (append x y) .

Комментарии:

1. Это имеет место в большинстве других языков, и его можно использовать в удобных идиомах. Например, для деления на число, предотвращающее деление на ноль, вы можете написать: (and (not (= x 0)) (/ 1 x)), он вернет 1 / x, если x не равно нулю, или nil в противном случае.

2. Он возвращает не выражения, а их значения.

Ответ №2:

and и or также являются операторами потока управления

Вы могли бы подумать and и or о специальных операторах потока управления. Они не работают. Функция and получит свои аргументы, а затем может вернуть true или false .

В этом случае and и or не являются функциями, и при некоторых обстоятельствах оцениваются не все аргументы:

  • or немедленно возвращается, когда видит истинное значение
  • and немедленно возвращается, когда видит значение false

Возвращаемое значение

Оба также возвращают истинное значение, когда оно есть:

  • or возвращает первое истинное значение
  • and возвращает последнее значение true, когда все аргументы имеют значение true

Поскольку true означает не только одно логическое значение, но и большинство других объектов также являются true, вы видите, что в вашем случае он возвращает список. Only #f неверно.

Другие операторы потока условного управления

Примерами могут быть:

  • если
  • cond
  • случай
  • когда
  • если не