Что происходит в предложении «cond» схемы, когда «else» опущено?

Я в процессе изучения Scheme. Недавно я потратил (слишком много!) времени, пытаясь найти ошибку в программе, прежде чем понял, что мне не хватает слова «else» в предложении cond. Но поведение в таких обстоятельствах кажется немного странным. Экспериментируя с условиями с помощью простой программы (ниже), «что угодно» отображается, как и ожидалось, в предложении else, но также отображается, но без «else», отображается с окружающими двойными кавычками и неинтерпретируемым новым строка напечатана буквально. Кто-нибудь может объяснить мне, что происходит? ТИА.

   (define (foo x)
    (cond ((eq? x 0) (display "zero\n"))
          (display "whatever\n")))

   (define (bar x)
    (cond ((eq? x 0 ) (display "zero\n"))
          (else (display "whatever\n"))))

In the repl window:
Welcome to DrScheme, version 4.1.5 [3m].
Language: Pretty Big; memory limit: 128 megabytes.
> (foo 0)
zero
> (bar 0)
zero
> (foo 2)
"whatever\n"
> (bar 2)
whatever
> 

person Leonard    schedule 01.05.2009    source источник


Ответы (2)


"другое" - это просто синоним "истинного". Условие можно читать как серию тестов, где первый верный тест приводит к оценке этой формы.

(cond  ( (test) (do this) )
       ( (test) (do this) ) )

Вот твой первый

 (cond ((eq? x 0) (display "zero\n"))
        (display "whatever\n")))

cond смотрит на (eq? x 0) и определяет, что это ложь. Следующее предложение (display "whatever\n"). Он смотрит на display, и поскольку display не nil, это правда. Затем он оценивает строку "whatever\n", которая просто оценивается сама по себе. Таким образом, значение cond равно "whatever\n".

А вот и второй:

(cond ((eq? x 0 ) (display "zero\n"))
       (else (display "whatever\n"))))

Здесь первый тест ложен, и он переходит ко второму, который равен else и который оценивается как истина. (Если подумать, вот что означает «иначе» в обычном «если-то-иначе»: «истинно для всех случаев, когда ни один из предыдущих тестов не был верен».)

Теперь за ним следует форма (display "whatever\n"). Это функция, которая отправляет строковый аргумент на консоль и ничего не возвращает, потому что это то, что делает дисплей. В другой схеме он может вернуть строковое значение, а также распечатать его, и в этом случае вы увидите

whatever
"whatever\n"
person Charlie Martin    schedule 01.05.2009
comment
На самом деле, по крайней мере, в схеме R5RS else не является синонимом истины. Это просто идентификатор, который распознает макрос. - person Luis Casillas; 01.03.2012
comment
что с точки зрения эксплуатации по-прежнему является синонимом истины.\ - person Charlie Martin; 02.03.2012

В функции foo оператор cond оценивает display как условие для проверки. Поскольку действительно существует символ с именем display, он оценивается как истина, поэтому "whatever\n" затем оценивается как результат (foo 2).

person Greg Hewgill    schedule 01.05.2009
comment
Ваш ответ был удивительно ясным и в равной степени заслуживает принятого ответа. Я дал его Чарли за то, что он печатал. Огромное спасибо. - person Leonard; 02.05.2009