0

Total newbie to Scheme here.

I've been stuck on a scheme problem for sometime now. I don't understand how to code this right. I've looked every where on this site and others, and I just can't get this to work.

the problem: define a function Square that squares its parameters. If the parameter is not a number, print the message "invalid_input".

Here is what I have tried:

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

I've also tried this:

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

And this:

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

None of these have worked when I call square like this (square h). I keep getting this error on 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.

Shouldn't it print "invalid_input" since 'h' is not a number? help me out here please. thank you

Cali_boy23
  • 19
  • 1
  • 1
    Personal anecdote: I struggled a lot with understanding he structure of lisp-y languages until I gave up on replicating the layout I used with other languages. Lisp is not a block-structured language, and making it look like one only confuses. – molbdnilo Aug 31 '20 at 06:40

2 Answers2

2

Functions always evaluate their arguments in Scheme. With (square h), h is an unbound variable; when h is evaluated, an error is issued since h is not bound. You can see that the OP definitions work as intended by trying (square 'h) or (square "h"). In the first case 'h is a symbol, and in the second "h" is a string; these are not numbers, so "invalid_input" is printed.

OP should work on following lispy conventions when formatting Scheme code; it is very bad style in lisps to scatter closing parentheses over multiple lines. Here is the same code in a more readable style, typical of lisps:

(define (square x)
  (cond ((number? x) (* x x))
        (else
         (display "invalid_input\n"))))
ad absurdum
  • 19,498
  • 5
  • 37
  • 60
  • 1
    Oooohhhh. I see what you mean. Thank you for the tip. Yesterday was literally my first attempt at Scheme or any Lisp descendant whatsoever. – Cali_boy23 Aug 31 '20 at 19:15
2

Your code works fine. But you have do define h in order to use it.

$ 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.

Your function is correct.

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

And works as expected:

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

But if you pass an undefined value, you will get an error:

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

You have to make sure, that h is defined.

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

This is the same as in every other language. Try it in C:

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

int main (int argc, char** argv)
{
  printf ("%d", square (h));
}
ceving
  • 21,900
  • 13
  • 104
  • 178
  • "_This is the same as in every other language_" is not true. Some languages provide default values for uninitialized variables; e.g., in Lua an unbound `h` would default to `nil`. Even in C static variables are zero-initialized. – ad absurdum Aug 31 '20 at 07:03
  • @exnihilo They will have a default value, if you declare them. But he did not even declare the variable. – ceving Aug 31 '20 at 07:21
  • There is no need to declare variables in Lua, or in some other languages. – ad absurdum Aug 31 '20 at 07:22
  • @exnihilo It seems to me that I was right never touching Lua, if it is just another Bash. – ceving Aug 31 '20 at 07:24
  • @ceving: Well, in shell scripts you can say `set -u` which stops that problem. I don't know if Lua has an equivalent: I hope so. –  Aug 31 '20 at 10:29
  • I see what you mean ceving, but i wasn't trying to pass a variable into my Square function, i was basically just trying to verify whether the input is a number or a non-number. – Cali_boy23 Aug 31 '20 at 19:16
  • @Cali_boy23 Then you have to pass a string instead of a number: `(square "5")`. Or use a symbol. But symbols have be quoted with a prefixed single quote: `(square 'five)`. Otherwise Scheme will evaluate them and this will result in the error you are facing. – ceving Sep 01 '20 at 06:30