Ошибка оператора if-else в схеме с использованием хитрости

Полный новичок в Scheme здесь.

Я застрял на проблеме со схемой на какое-то время. Я не понимаю, как это правильно закодировать. Я посмотрел везде на этом сайте и на других, и я просто не могу заставить это работать.

проблема: определить функцию Square, которая возводит в квадрат свои параметры. Если параметр не является числом, вывести сообщение invalid_input.

Вот что я пробовал:

(define (square x) (cond
                      ((number? x) (* x x))
                      (else (display "invalid_input\n"))
                   )
)

Я также пробовал это:

 (define (square x) (cond
                       ((number? x) (* x x))
                       ((not (number? x)) (display "invalid_input\n"))
                    )
 )

И это:

(define (square x) (if 
                   (number? x) (* x x) (display "invalid_input\n")
                   )
)

Ни один из них не сработал, когда я вызываю квадрат вот так (квадрат h). Я продолжаю получать эту ошибку в Linux

scheme@(guile-user)> (square h)
;;; <stdin>:44:0: warning: possibly unbound variable `h'
<unnamed port>:44:0: In procedure #<procedure 7fcc7d0a0b60 at <current input>:44:0 ()>:
<unnamed port>:44:0: In procedure module-lookup: Unbound variable: h
Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.

Разве он не должен печатать invalid_input, поскольку «h» не является числом? помогите мне здесь, пожалуйста. Спасибо


person Cali_boy23    schedule 31.08.2020    source источник
comment
Личный анекдот: я много боролся с пониманием структуры lisp-языков, пока не отказался от повторения макета, который я использовал с другими языками. Lisp не является языком с блочной структурой, и его внешний вид только сбивает с толку.   -  person molbdnilo    schedule 31.08.2020


Ответы (2)


Функции всегда оценивают свои аргументы в Scheme. С (square h) h является несвязанной переменной; при оценке h выдается ошибка, поскольку h не привязана. Вы можете увидеть, что определения OP работают должным образом, попробовав (square 'h) или (square "h"). В первом случае 'h — символ, а во втором "h" — строка; это не числа, поэтому печатается "invalid_input".

OP должен работать в соответствии с lispy-соглашениями при форматировании кода схемы; это очень плохой стиль в лиспах - раскидывать закрывающие скобки по нескольким строкам. Вот тот же код в более читабельном стиле, характерном для лиспов:

(define (square x)
  (cond ((number? x) (* x x))
        (else
         (display "invalid_input\n"))))
person ad absurdum    schedule 31.08.2020
comment
Ооооооо. Я понимаю, что вы имеете ввиду. Спасибо за совет. Вчера я буквально впервые попробовал Scheme или любого потомка Lisp. - person Cali_boy23; 31.08.2020

Ваш код работает нормально. Но вы должны определить h, чтобы использовать его.

$ guile
GNU Guile 2.0.13
Copyright (C) 1995-2016 Free Software Foundation, Inc.

Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.

Enter `,help' for help.

Ваша функция правильная.

scheme@(guile-user)> (define (square x)
  (if (number? x)
      (* x x)
      (display "invalid_input\n")))

И работает как положено:

scheme@(guile-user)> (square 5)
$1 = 25

Но если вы передадите неопределенное значение, вы получите ошибку:

scheme@(guile-user)> (square h)
;;; <stdin>:6:0: warning: possibly unbound variable `h'
<unnamed port>:6:0: In procedure #<procedure 5595e9575c20 at <current input>:6:0 ()>:
<unnamed port>:6:0: In procedure module-lookup: Unbound variable: h

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
scheme@(guile-user) [1]> ,q

Вы должны убедиться, что h определено.

scheme@(guile-user)> (let ((h 5)) (square h))
$2 = 25

Это то же самое, что и в любом другом языке. Попробуйте на С:

int square (int x) {
  return x * x;
}

int main (int argc, char** argv)
{
  printf ("%d", square (h));
}
person ceving    schedule 31.08.2020
comment
Это то же самое, что и в любом другом языке не соответствует действительности. Некоторые языки предоставляют значения по умолчанию для неинициализированных переменных; например, в Lua несвязанный h по умолчанию будет равен nil. Даже в C статические переменные инициализируются нулем. - person ad absurdum; 31.08.2020
comment
@exnihilo У них будет значение по умолчанию, если вы их объявите. Но он даже не объявил переменную. - person ceving; 31.08.2020
comment
Нет необходимости объявлять переменные в Lua или в некоторых других языках. - person ad absurdum; 31.08.2020
comment
@exnihilo Мне кажется, я был прав, никогда не касаясь Lua, если это просто очередной Bash. - person ceving; 31.08.2020
comment
@ceving: Что ж, в сценариях оболочки вы можете сказать set -u, чтобы решить эту проблему. Я не знаю, есть ли у Lua эквивалент: надеюсь, что да. - person ; 31.08.2020
comment
Я понимаю, что вы имеете в виду, но я не пытался передать переменную в свою функцию Square, я просто пытался проверить, является ли ввод числом или не числом. - person Cali_boy23; 31.08.2020
comment
@ Cali_boy23 Тогда вам нужно передать строку вместо числа: (square "5"). Или используйте символ. Но символы заключены в одинарные кавычки с префиксом: (square 'five). В противном случае Scheme оценит их, и это приведет к ошибке, с которой вы столкнулись. - person ceving; 01.09.2020