2013-05-23 3 views
1

Мой преподаватель предоставил следующий код:Пользовательская функция для длины списка в схеме?

(define (length list) 
(cond ((null ? list) 0) 
((atom ? list) 1) 
(else 
(+ 1 (length (cdr list)))) 

Однако он не будет компилировать и схема хранится в ожидании ввода, поэтому я переписал его таким образом, что выглядит Tider мне и заметил, что это было 2 недостающие скобки (пожалуйста, обратите внимание, что это первый раз, когда я прикоснулся Scheme, я не уверен, как правильно класть его и писать его):

(define 
    (hello list) 
    (cond 
     ((null ? list) 0) 
     ((atom ? list) 1) 
     (else 
      (+1 
       (hello (cdr list)) 
      ) 
     ) 
    ) 
) 

я переименовал его в hello просто сделать это очевидным, что это мой код.

Забегая однако получает следующее сообщение об ошибке:

]=> (hello '(a b c)) 

;Unbound variable: ? 

Что случилось с моей функции?

+1

К сожалению, редактирование в процессе очистки форматирования также устранило ошибку. :) –

+0

Да, я поддержал это. – GoZoner

ответ

4

Ваша процедура hello страдает от избыточного количества пробелов: P. Я понимаю, что вы пытались улучшить его читаемость, но при этом вы ввели пару ошибок. Также обратите внимание, что в схеме обычный способ записи закрывающейся скобки находится в одной строке, а не в отдельных строках (в отличие от того, что сделано с фигурными фигурными скобками на других языках программирования).

Вот рекомендуемый способ форматирования кода, а также исправления ошибок синтаксиса:

(define (hello lst) 
    (cond ((null? lst) 0) 
     ((atom? lst) 1) 
     (else (+ 1 (hello (cdr lst)))))) 

Имейте в виду, что:

  • Там не должно быть белое пространство между null и ?, то же самое для atom и ?: процедуры называются null? и atom?, а не null и atom и один ? ничего не значит
  • Там должно быть пространство между + и 1, процедура сложения называется + не +1
  • Это плохая идея, чтобы вызвать параметр list, что имя столкновения с встроенная процедура list, поэтому я переименовал его в lst

в качестве примечания: порядок, как написано излишне сложным, отметив, что длина, как определено не принимать во внимание вложенные списки можно было бы выразить так просто:

(define (hello lst) 
    (cond ((null? lst) 0) 
     (else (+ 1 (hello (cdr lst)))))) 
+0

А, спасибо тебе, Оскар! Какое блестящее объяснение и такое аккуратное и аккуратное форматирование. Я хочу, чтобы ты был здесь, чтобы научить меня. Вы не представляете, насколько я ценен, всех вас, ребята. Единственное, что я нахожу странным, это то, как вы возвращаете число int. Как он узнает, что это то, что он возвращает? Посмотрев на это, похоже, что последнее значение - это то, что он возвращает. Например. '0' и' 1'. Однако на 'else' это указано на фронте. Так ли это просто предположить, что любой int - это то, что он вернет? – gbhall

+0

Почему, спасибо за добрые слова :) Процедура всегда возвращает целое число: оно либо возвращает целое число в базовых случаях, либо возвращает его при рекурсивном вызове. Но рекурсивный вызов также возвращает целое число, добавляя его к результату повторения по остальной части списка, что в итоге также возвращает целое число. Это красота рекурсии! –

+0

Добро пожаловать :) Так что 'cond' не может вернуть ничего, кроме int? И да, я люблю рекурсию :) – gbhall

1
(null ? list) 

Это вызывает функцию null с аргументами ? и list. Однако, как указано в сообщении об ошибке, нет переменной с именем ? (и нет функции с именем null, но Scheme не зашел так далеко, поэтому сообщение об ошибке не упоминало об этом).

Однако существует функция с именем null?, что почти наверняка является функцией, которую вы хотели назвать. Итак:

(null? list) 

Обратите внимание, что в ?null? просто часть имени функции, и вы не можете поставить пробел в середине имени.

То же самое относится к (atom ? list) на следующей строке.

+0

Черт белой комнаты, это меня беспокоило. Спасибо, sepp. – gbhall

0

Во-первых, имена функций «null?» И «atom?». Поскольку вы отделили «?» От них пробелом, Scheme обрабатывает вопросительные знаки, как если бы они были отдельными символами, а не являлись частью имен функций.

Кроме того, по той же причине вы захотите использовать «+ 1», разделенные пробелом вместо «+1». Имя функции - «+», а «1» - первый аргумент.

+0

Спасибо, Роберт. – gbhall

Смежные вопросы