Есть две проблемы синтаксиса с этим фрагментом:
(if (= c 1) (factorial (n)))
Для начала if
выражение в Ракетке нужны три части:
(if <condition> <consequent> <alternative>)
Первое, что нужно исправить было бы обеспечить выражение, которое будет выполняться при c
равна 1
, а другой, который будет работать, если c
не равна 1
. Скажем, что-то вроде этого:
(if (= c 1) 1 (factorial (n)))
Теперь вторая проблема: в схеме, когда вы окружаете символ со скобками это означает, что вы пытаетесь выполнить функцию. Поэтому, если вы пишете (n)
, интерпретатор считает, что n
- это функция без аргументов и которую вы пытаетесь назвать. Чтобы исправить это, просто удалите ()
вокруг n
:
(if (= c 1) 1 (factorial n))
Теперь, когда проблемы синтаксиса из пути, давайте рассмотрим логику. В схеме мы обычно используем рекурсию для выражения решений, но в какой-то момент рекурсия должна до продвигаться вперед, поэтому она в конечном итоге закончится. Если вы продолжаете передавать один и тот же параметр в рекурсию, не изменяя его, вы попадаете в бесконечный цикл. Вот правильный способ, чтобы написать рекурсивную процедуру: factorial
(define (factorial n)
(if (<= n 0) ; base case: if n <= 0
1 ; then return 1
(* n (factorial (- n 1))))) ; otherwise multiply and advance recursion
Обратите внимание, как мы уменьшаем n
на каждом шаге, чтобы убедиться, что он в конечном счете достигнет нуля, окончание рекурсии. Как только вы успокоитесь с этим решением, мы можем думать о том, чтобы сделать его лучше. Читайте о tail recursion, см., Как компилятор оптимизирует наши циклы, пока мы пишем их таким образом, что последнее, что делается на каждом пути выполнения, - это рекурсивный вызов, после чего ничего не оставалось делать после него.Например, предыдущий код можно записать более эффективно как следует, и посмотреть, как мы передаем накопленный ответ в качестве параметра:
(define (factorial n)
(let loop ([n n] [acc 1])
(if (<= n 0)
acc
(loop (- n 1) (* n acc)))))
UPDATE
После взглянуть на комментарии, я вижу что вы хотите реализовать процедуру switchcase
. Еще раз, есть проблемы с тем, как вы объявляете функции. Это неправильно:
(define fact(x)
Правильный путь таков:
(define (fact x)
И на самом деле реализации switchcase
, можно использовать вложенные if
с, как вы пытались, но это не самый лучший способ. Узнайте, как использовать выражение cond
или выражение case
, либо один сделает ваше решение проще. И в любом случае вам необходимо предоставить дополнительное условие, если c
не является ни 1
, ни 2
. Кроме того, вы смешиваете имя параметра - это c
или x
? Со всеми рекомендациями на месте, вот как ваш код должен выглядеть:
(define (switchcase c)
(cond ((= c 1) (fact c))
((= c 2) (triple c))
(else (error "unknown value" c))))
Ваш код уже вызывает функцию (например, '=') двух аргументов с двумя аргументами (например, 'c' и' 1'). Вы не вставляли 'c' и' 1' в круглые скобки, и вы также не должны обматывать 'n'. –