user3241846
user3241846

Reputation: 677

Let error AND returning/printing a "string" for scheme procedure

my function checks simple values and should have output/return depending on the result. I have 2 problems: 1. when I replace the let value (-1) of runner with the expression (randint (-5 10)), where randint is another procedure that returns a random number between -5 and 10, it doesnt work

  1. I want to return/print a string for the first two if statements if they are true, dont know how to do that in scheme.

Here is the code:

(define (check)
  (let (runner(randint -5 10)
    (cond ((and (< runner 1) (> runner -3))
           (display "yes"))
          ((and (< runner -2) (> runner -6))
           (display "no"))
          ((> runner 0)
           (display runner))))))

Here is the code for randint:

(define random
(let ((a 69069) (c 1) (m (expt 2 32)) (seed 19380110))
 (lambda new-seed
 (if (pair? new-seed)
 (set! seed (car new-seed))
 (set! seed (modulo (+ (* seed a) c) m)))
 (/ seed m))))

(define (randint . args)
 (cond ((= (length args) 1)
 (floor (* (random) (car args))))
 ((= (length args) 2)
 (+ (car args) (floor (* (random) (- (cadr args) (car args))))))
 (else (error 'randint "usage: (randint [lo] hi)"))))

Upvotes: 0

Views: 1738

Answers (3)

&#211;scar L&#243;pez
&#211;scar L&#243;pez

Reputation: 235994

Apart from the syntax problems pointed by @Rptx, there's one killer bug in your code: you can't have one-armed ifs in Racket (meaning: they must have a consequent and an alternative). You can either nest them, or better yet: use cond, which is perfect for testing multiple conditions. This should work:

(define (check)
  (let ((runner (randint -5 10)))
    (cond ((and (< runner 1) (> runner -3))
           "yes")
          ((and (< runner -2) (> runner -6))
           "no")
          ((> runner 0)
           runner))))

Use it like this:

(display (check))

Regarding the issue with randint: Now that you have posted the code I can confirm that the problem was in the way that you were passing the parameters. As shown above, this is the correct way:

(randint -5 10)

Upvotes: 3

Sylwester
Sylwester

Reputation: 48745

It really hurts my eyes to see 3 expressions in a implicit begin with each their own if without alternative. Here is a version using cond (only because it's 2 terms and an alternative) Also notice that it's enough with one < with the bounds on each side of your variable rather than splitting it up in two with a logical and between.

(define (check)
  (let ((runner -1))
    (cond ((< -3 runner 1)  "yes")
          ((< -6 runner -2) "no")
          (else "runner"))))

(display (check)) ; ==> void, displays the result of check

Upvotes: 2

Rptx
Rptx

Reputation: 1189

There are several mistakes in your code.

  1. You are missing parens around check. You are currently defining check as a variable, not as a procedure.
  2. You are missing a procedure to print.
  3. Print and return are not the same thing. The procedure will return what the last statement of the body of let returns. In your case, it will return 'runner if (> runner 0) is true, or false otherwise.
  4. If you don't post the error you get when you use randint We can't know what is wrong.

Here is a working version of your procedure:

(define (check)
  (let ((runner -1))
    (if (and (< runner 1) (> runner -3)) (display "yes"))
    (if (and (< runner -2) (> runner -6)) (display "no"))
    (if (> runner 0) (car '(runner))))) 

Upvotes: 1

Related Questions