INTELLIGENT WORK FORUMS FOR COMPUTER PROFESSIONALS
Come Join Us!
Are you a Computer / IT professional? Join TekTips now!
 Talk With Other Members
 Be Notified Of Responses
To Your Posts
 Keyword Search
 OneClick Access To Your
Favorite Forums
 Automated Signatures
On Your Posts
 Best Of All, It's Free!
*TekTips's functionality depends on members receiving email. By joining you are opting in to receive email.
Posting Guidelines
Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Simple List Function: counting all the elements in a list

I'm just learning Scheme and I'm having a hard time with it. I'm trying to write a simple function that will count all the elements in a list. For example, the list '(1(2(3)4)5 6)) has a length of 4, but contains 6 elements. This is the function I've written so far, but when I try to use it I immediately get "Error: Bad function object:0"
(define (elements theList) (if (null? theList) (0) ( (if(list? (car theList)) (+ 0 (elements (car theList))) ( + 1 (elements (cdr theList)) )) ) ))
Someone help me out. 

I intend 0 to be a number not a function. Is Scheme that weird that it thinks a number is a function name? 

A symbol that follows a nonquoted left parentheses must always denote a function. Examples: '(hello) => list with element 'hello '(0) => list with element 0 ('0 evaluates to 0) (display 'blah) => call function display with parameter 'blah (0) => call nonexistent function 0 You seem to have trouble understanding that every statement in Scheme can be regarded as a function and therefore has a result. Search in Google for "Teach yourself Scheme in fixnum days", it's a good and, most importantly, short manual for the beginner. And lastly, the ifstatement works as follows (example returns the length of the list): (define (length lst) (if (null? lst) 0 (+ (length (cdr lst)) 1)))A last tip: the function you need can be written in 4 lines with a conditional. Regards, Bert Vingerhoets vingerhoetsbert@hotmail.com http://student.vub.ac.be/~bvingerh/ Don't worry what people think about you. They're too busy wondering what you think about them. 

Now my function looks like this:
(define (try theList) (cond ((null? theList) 0) ((list? (car theList)) (+ '0 (elements (car theList)))) (else (+ '1 (cdr theList))) ))
And now I'm getting the error "Bad function object:(1 (2 (3) 4) 5 6)" when I try using that as my list. I define it like this:
(define theList '(1(2(3)4)5 6))
which I believe is correct. Am I even close in writing this function? 

In the previous post the function should be
(define (elements theList) (cond ((null? theList) 0) ((list? (car theList)) (+ '0 (elements (car theList)))) (else (+ '1 (cdr theList))) ))


Since quoted numbers evaluate to themselves, you can drop the quote ('1 evaluates to the value one, but so does 1). Think of what your function is supposed to look like: it will be recursive (why?). A recursive function always has 2 major parts: a finishing step (trivial step) and one or more constructive steps. In your function the trivial step is that where you handle the empty list. The two constructive steps are: a) the one where you have a sublist of the given list and b) the one where you have something else (an atom). My previous example: (define (length lst) ;Function receives a list (if (null? lst) ;trivial step: if the list is empty, 0 ;return 0 (+ 1 (length (cdr lst))))) ;if it's not empty, construct the result by adding the length of the first element (of which you are sure it's 1) to the length of the rest of the list (of which you aren't sure, so you apply the length function to it; it might help thinking that this length function has nothing whatsoever to do with the function you're working in) Regards, Bert Vingerhoets vingerhoetsbert@hotmail.com http://student.vub.ac.be/~bvingerh/ Don't worry what people think about you. They're too busy wondering what you think about them. 

Sorry, I didn't take a close look to your function; yes you're close. And I don't get a "bad function object" error, I get this: (define (elements theList) (cond ((null? theList) 0) ((list? (car theList)) (+ '0 (elements (car theList)))) (else (+ '1 (cdr theList))) ))
(elements thelist) +: expects type <number> as 2nd argument, given: ((2 (3) 4) 5 6); other arguments were: 1 Regards, Bert Vingerhoets vingerhoetsbert@hotmail.com http://student.vub.ac.be/~bvingerh/ Don't worry what people think about you. They're too busy wondering what you think about them. 

I think I've got it!!
(define (try theList) (cond ((null? theList) '0) ((list? (car theList)) (+ (try (car theList)) (try (cdr theList)))) (else (+ '1 (try(cdr theList)))) ))
I just wanna run through this through the experts. And if this indeed correct, then I want to thank Bert Vingerhoets for all the great help. 

Correct, if you want to add some safety, you can use the error function: (define (elements lst) (cond ((not (list? lst)) (error "elements: expects argument of type <proper list>")) ((null? lst) 0) ((list? (car lst)) (+ (try (car lst)) (try (cdr lst)))) (else (+ 1 (try (cdr lst))))))As an excercise in implementing recurrent functions, you can try to build a function to reverse a given list, a function to count all elements in the given list with support for dotted pairs, a function that generates a new list out of a given list with an element inserted at a certain position, and so on. Regards, Bert Vingerhoets vingerhoetsbert@hotmail.com http://student.vub.ac.be/~bvingerh/ Don't worry what people think about you. They're too busy wondering what you think about them. 



