Making a random list in Scheme

2019-08-04 17:44发布

I am just trying to randomly make a list and use it in a larger function.

        (define make-random-list
        (if
          (= (random 2) 0) (list 2 3)
                           (list 3 2)))

This only produces the list (2 3) and I am not sure why. What is happening to cause this?

I can make the function work if I write it like this

  (define make-random-list
   (lambda (x)
   (if
    (= (random x) 0) (list 2 3)
                     (list 3 2))))

and calling (make-random-list 2)

but I do not understand why that would work and the other one would not. What is going on with scheme that would not allow the first function to produce random results?

2条回答
Animai°情兽
2楼-- · 2019-08-04 18:05

In your first snippet, you're assigning the result of a one-time computation to a variable. What you need here is to define a function that will be evaluated every time it's invoked. Your second snippet does exactly that, but there is a shorter way to express the same:

(define (make-random-list x)
(if
  (= (random x) 0) (list 2 3)
                   (list 3 2)))

Note the difference in the syntax: a function definition encloses the function definition together with the formal argument names in parentheses, while there are no parentheses around the name of a variable.

查看更多
在下西门庆
3楼-- · 2019-08-04 18:10

In Scheme, functions are defined by explicitly using a lambda like this:

(define square
  (lambda (x)
    (* x x)))

Or like this, which is shorthand for the previous syntax and implicitly is using a lambda under the hood - both flavors of procedure definition are completely equivalent:

(define (square x)
  (* x x))

The first version of your code wasn't working because this is just assigning the result of the evaluation of if to a variable called make-random-list:

(define make-random-list
  (if (= (random 2) 0)
      (list 2 3)
      (list 3 2)))

For defining a procedure in Scheme you have to use a lambda, either explicitly or implicitly. So your procedure should be defined using either of this equivalent forms:

(define make-random-list
  (lambda ()
    (if (= (random 2) 0)
        (list 2 3)
        (list 3 2)))

(define (make-random-list)
  (if (= (random 2) 0)
      (list 2 3)
      (list 3 2)))

Notice that you don't have to pass the x parameter if the only possible value is 2, simply declare a procedure with no arguments.

查看更多
登录 后发表回答