Получение #f или False в конце результата из функции определения фильтра в схеме (SCM) - PullRequest
2 голосов
/ 19 апреля 2019

Я работаю над книгой SICP. Я использую SCM в Windows вместо самой программы Scheme. Когда я запускаю функцию фильтра ниже, я получаю (1 3 5. #F), как показано ниже в окне кода. Я не могу понять, как точка и ложное значение добавляются к нечетным целым числам.

    (define (filter odd? lst)
        (cond ((null? lst) nil)
              ((odd? (car lst))
               (cons (car lst)
                     (filter odd? (cdr lst))))
              (else (filter odd? (cdr lst)))))

    (filter odd? (list 1 2 3 4 5))

    (1 3 5 . #f)

Я ожидаю получить (1 3 5) в качестве результата, а не (1 3 5. #F).

Ответы [ 3 ]

2 голосов
/ 19 апреля 2019

nil не является отчетом Схемы, определяемым сегодня как привязка верхнего уровня.Если он существует в реализации, он может иметь любое значение, поэтому вы не можете зависеть от него.SICP использовал более раннюю версию Scheme, чем R4RS, и поэтому никакие современные реализации сегодня не будут полностью ее поддерживать.Я использую DrRacket , так как он поддерживает многие языки отчетов, имеет хороший отладчик и IDE, а вероятность синтаксических ошибок уменьшается из-за того, что он отступает от кода во время записи.Он имеет язык совместимости с SICP , поэтому код SICP работает без необходимости перепрыгивать через слишком много обручей.

Исторически Scheme пришла от Lisp, и Lisp не различает пустой список и значение false.Схема вводила #t и #f, но сохраняла тот факт, что пустой список считался ложным, пока они не изменили его, так что только #f ложно, а все остальное считается правдивым.nil был связыванием для () в ранних отчетах, поэтому, возможно, SCM изменил его на #f, когда они сделали изменение, так как CL часто использует nil для ложного значения и () для пустого списка,даже если они просто два представления одного и того же значения.

Многие реализации представляют свои собственные привязки в верхней части отчета, которому они соответствуют.Использование их фиксирует их вкус, поэтому лучше всего придерживаться стандарта кода.DrRacket интерпретирует отчеты очень строго, чем другие реализации, так что программа R6RS, написанная на DrRacket, скорее всего, будет работать без изменений в других реализациях, совместимых с R6RS.Стандарты это круто!

0 голосов
/ 19 апреля 2019

Я думаю, что проблема со строкой:

    (cond ((null? lst) nil)

и значение nil. В книге, взятой из схемы, я верю nil эквивалентно пустому списку '(). Я подозреваю, что СКМ считает nil эквивалентным ложному #f. Поэтому, если вы замените nil на '(), вы можете получить ожидаемые результаты.

0 голосов
/ 19 апреля 2019

Когда я получаю поведение, я не понимаю, я добавляю отладочный вывод в программу.Что происходит, когда вы говорите:

(define (filter odd? lst)
    (display lst) (newline)
    (cond ((null? lst) (display "1") (newline) nil)
          ((odd? (car lst))
            (display "2") (newline)
            (cons (car lst)
                  (filter odd? (cdr lst))))
          (else (display "3") (newline)
                (filter odd? (cdr lst)))))

Вы увидите аргументы, передаваемые при каждом рекурсивном вызове, и вы узнаете, какая ветвь cond была выбрана при каждом рекурсивном вызове.Это обычно показывает мне проблему.

...