0
votes
(define (min list)
 (cond ((empty? (car list) '"It is empty"))  <- Problem is here. Code work without this line.
       ((empty? (cdr list)) (car list))         ;to check list is empty
       ((< (car list) (min (cdr list))) (cdr list))
       (else (min (cdr list) ))))

I am very new to scheme Programming language. I am trying to get minimum value from the list. When I put (), the program gives me an error: cdr: contract violation expected: pair? given: '(). What I am trying to do here is I want to print out It is empty when user type (). Is it possible do like that in Scheme programming?

3
Do you want to check if the first element of a list (car) is empty? Or do you want to check if the list is empty? You can not take the first element from a list, if the list is empty. First you have to check, if the list is empty. And if it is not empty, you can take the first element. Example: (if (pair? some-list) (car some-list)). If something is a pair, you can take the first element. Otherwise not.ceving

3 Answers

0
votes

You can find the answer to this question--and so much more--in How To Design Programs, 2e, a textbook written by the developers of the Racket language.

In this case, you want to be using the template for functions on lists. This is covered in section II, more specifically section 9.1.

0
votes

The structure of a list in Scheme and other Lisp-languages is based on cons-cells. Each cons-cell contains a value (the car) and a pointer to the next cons cell (the cdr, pronounced see-dar) in the list, like this:

         +-+-+                  
         |1|----+               
         +-+-+  |               
                +-+-+           
                |2|---+         
                +-+-+ |         
                      +-+-+     
                      |3| |     
                      +-+-+

The final cons-cell, where the list ends, contains a nil. In Scheme notation, a cons-cell looks like this:

(1 . 2)

So a list, without any syntactic sugar, would look like this:

(1 . (2 . (3 . (4 . nil))))

An empty list, consists of a cons cell that looks like this:

(nil)

Notice that the empty list has no car? An empty list is treated like a nil, so this:

(1 . (2 . (3 . (4 . ()))))

Works just like the previous one.

Now, when you use the syntactic sugar, lists look like this:

(1 2 3 4)

But the underlying structure is the same. So, to test if you have an empty list, test if it's nil (which Scheme does with the empty? function). So, instead of calling empty? on the car of the list, which is wrong thinking as well as an error, call it on the list. So your function should look like:

(define (min list)
 (cond ((empty? list "It is empty"))
       ((empty? (cdr list)) (car list))
       ((< (car list) (min (cdr list))) (cdr list))
       (else (min (cdr list) ))))

Notice that the second arm does not check that the list is empty, as your comment says: it checks if the list has only one or no element. If your cdr is empty, but your car isn't (which the second arm allows), then you have a one element list:

(foo . ())

Hope this helps!

For more information on how to improve your specific function, look at Oscar Lopez's answer to this question.

0
votes

I think you want to print empty list or get min value, right?

(define (min list)
      (if (null? list)
          "It's empty."
          (let loop ([loop_list list]
                     [min_value (car list)])
            (if (null? loop_list)
                min_value
                (loop
                 (cdr loop_list)
                 (if (< min_value (car loop_list)) min_value (car loop_list)))))))