drodil
drodil

Reputation: 2346

SCHEME: Objects in a list

I have a list of objects in scheme as described below. How is it possible to call objects functions when for example taking the first element out of the list?

(define persons false)
(define length 10)

(let loop ((n 0))
    (if (< n length)
        (begin
            (define newp (make-person))
            (send newp setage (- 50 n))

            (cond
                 ((= n 0)
                        (set! persons (list newp)))
                 (else
                        (set! persons (cons persons newp)))
            )

            (loop (+ n 1))
        )
     )
 )

 (define (firstpersonage)
     (send (car persons) getage)
 )

When calling the firstpersonage I am getting error message that there is no such method. Is there way to "cast" the first object to be "person" type?

Thanks!

Upvotes: 3

Views: 699

Answers (2)

Inaimathi
Inaimathi

Reputation: 14065

First, please do learn to indent Lisp correctly.

Second, your problem is that you've decided to use a pile of side effects to construct a list of people in Scheme (and as a consequence, you tripped over one of the finer points of list construction).

What I would do in this situation is write

(define persons
  (map (lambda (n)
         (let ((newp (make-person)))
           (send newp setage (- 50 n))
           newp))
       (iota 10)))

(define (firstpersonage)
  (send (car persons) getage))

That is, define person to be the list of ten people of descending ages from 50 to 41. Doing it this way avoids the possibility for many bugs, including the one you just got bitten by.

If you absolutely, positively can't bear to part with your set!s, the error seems to be in the line

(set! persons (cons persons newp))

cons doesn't append two lists, it adds a new element to the head of a list. For example

(cons 3 (list 2 1)) => (3 2 1)

If you do it in the reverse way, you won't quite get what you're looking for

(cons (list 1 2) 3) => ((1 2) . 3)

Upvotes: 2

Jonas
Jonas

Reputation: 86

You're getting the error because you're using cons the wrong way; you're not constructing a proper list. (cons persons newp) creates a new pair and puts persons in the car and newp in the cdr, so when you're done, what's in the car of persons is not one of those person-objects. You might find that (cdr persons) is a person-object though, and that you can do (send (cdr persons) getage) just fine. And (cdar persons) and (cdaar persons)are person-objects too. So it kind of is a list, only the items are in the cdrs and the tails are in the cars (until you get to the initial list that you created with (list newp) where it's the other way around again).

Anyway, if you switch it around so it goes (cons newp persons) it should work.

Upvotes: 1

Related Questions