Обратите внимание, что, как определено, (med . rest)
эквивалентно (cadr rest)
(за исключением того, что med
принимает только три значения). Лично я ожидал бы, что функция, которая должна возвращать медиану значений, вернет, ну, в общем, медиана , независимо от порядка в списке. Например, (med 4 2 5)
вернет 4, а (3 0 9 6 5)
вернет 5.
Что касается синтаксической ошибки (которая не имеет большого значения для написания med
, поскольку есть лучший способ использования sort
, length
и list-ref
), вы не ставьте свои скобки в правильных местах. Вот еще один способ написать то, что у вас есть сейчас, выстраивая термины с их братьями и сестрами и справа от их предков:
(if (and (
(<x y)
(<y z)
y
if
(and (
(<y x)
(<x z)
x
z
) ) ) ) )
Формат if
:
(if test-expr true-expr false-expr)
Все ваши условия являются подусловиями условного соглашения, и здесь нет true-expr
или false-expr
. Вы хотели бы написать свой код как:
(if (and ...)
y
(if (...) ; we know that (not (and (< x y) (< y z))
x
z))
Обратите внимание, что вы могли бы упростить последующие тесты, поскольку знаете, что предыдущие тесты являются ложными.
Вы также можете использовать cond
, который более понятен, чем вложенная последовательность if
s:
(cond (test result)
(test result)
(test result)
... )
Для вашего кода это будет:
(cond ((and ...) y)
((...) x)
(else z))
В else
нет ничего особенного (это скорее синтаксическая конструкция, чем выражение, не то чтобы она имела большое значение). Вместо этого вы можете использовать любое значение, которое оценивается как true (например, #t
).
Помните, круглые скобки окружают как функцию, так и аргументы в Лиспе ((foo 1 2 3)
, а не foo(1, 2 ,3)
), в отличие от математических обозначений, где круглые скобки окружают только аргументы.