Звучит так, будто вы застряли в бесконечном цикле.
Я предполагаю, что либо days-between-months
, либо days-between-years
вызывает себя бесконечно.
Например, days-between-months
предполагает, что m1
<= <code>m2. Но если вы называете это с помощью m1
> m2
, похоже, что оно будет продолжать называть себя «навсегда» - продолжайте пытаться увеличивать m1
, пока оно не станет равным m2
, но никогда не будет, потому что оно уже больше , (Ну, «никогда», или, по крайней мере, долгое время, пока целое значение не обернется.)
Практически, есть два способа решения этой проблемы.
Способ "защитного программирования" заключается в изменении вашего теста if
с (= m1 m2)
на (<= m1 m2)
. Многие программисты сделали бы это.
В способе Написание твердого кода можно сказать, подождите, проблема в том, что вызывающая сторона передает бессмысленные значения функции: вызывающая сторона должна быть исправлена, скорее чем функция, молча скрывающая ошибку. Если вам нравится такой подход, вы бы добавили assert
в такой язык, как C, или здесь вы могли бы сделать что-то вроде (when (> m1 m2) (error))
, чтобы преднамеренно вызвать ошибку. Или в Racket, вы можете использовать contract
, и он будет жаловаться, если вы попытаетесь нарушить требуемые условия.
После многих лет написания кода я предпочитаю второй подход. Но вы найдете хорошие аргументы в обоих направлениях. Кроме того, это зависит от природы системы, которую вы кодируете, от того, предпочитаете ли вы, чтобы она была "хрупкой" по отношению к сбоям, чтобы вы могли их находить и исправлять, или путалась как можно лучше. Также некоторые люди применяют хрупкий подход в «отладочных» сборках и терпимый к выпущенному продукту.
Наконец, ваш код вызывает пару функций, которые не определены в том, что вы предоставили (например, month-length
и year-length
), и проблемы могут быть там вместо или в дополнение к тому, что я упомянул.