# Function not reading all the element in a list

**URL:** <https://racket.discourse.group/t/function-not-reading-all-the-element-in-a-list/1918>\
**Category:** Questions & Answers\
**Created:** [May 4, 2023, 5:29pm UTC](https://racket.discourse.group/t/function-not-reading-all-the-element-in-a-list/1918 "2023-05-04T17:29:37Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![louberlu](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/louberlu/32/1142_2.png) [@louberlu](https://racket.discourse.group/u/louberlu)\
**Post date:** [May 4, 2023, 5:29pm UTC](https://racket.discourse.group/t/function-not-reading-all-the-element-in-a-list/1918/1 "2023-05-04T17:29:37Z")

</div>

Hi,  
I am not an English native, so, if you see any fault or incoherence, please correct me.  
I'm currently learning SCHEME language, and our teacher told us to create two programs: one which counts the number of occurrence of an element in a list, and the other which verifies if the element is present or not.  
The first program works for simple list, but for the lists with imbrication, it seems like it doesn't count all the element (the one inside the imbrication). For the second, I think it's a similar problem.

Here is what I have done for the first one:

```scheme
(define occur (lambda (x L)
                (cond
                  ((null? L) 0)
                  ((eq? x (car L)) (+ 1 (occur x (cdr L))))
                  (#t (occur x (cdr L)))
                )))

```

This is an example where it doesn't work:

```scheme
> (occur 'a '(b (a b)))
0

```

Here is the second one.

```scheme
(define ppt (lambda (x L)
              (cond
                ((null? L) #f)
                ((eq? x (car L)) #t)
                (#t #f))
              ))

```

This is an example where it doesn't work:

```scheme
> (ppt '1 '(2 (0 2 1)))
#f

```

Update:  
I have done some verification and the reason, why it doesn't work, is because of the function "cdr".

```scheme
> (cdr '(a (b c) d))
'd
> (cdr '(a (b c)))
'()

```

Do you have any suggestion?  
Thanks in advance.

---

<div class="post-metadata">

**Author:** ![samth](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/samth/32/3_2.png) [@samth](https://racket.discourse.group/u/samth)\
**Post date:** [May 4, 2023, 8:56pm UTC](https://racket.discourse.group/t/function-not-reading-all-the-element-in-a-list/1918/2 "2023-05-04T20:56:58Z")

</div>

Here's what I get from `cdr`:

```scheme
Welcome to Racket v8.9.0.3 [cs].
> (cdr '(a (b c)))
'((b c))

```

Are you using a different language, or some other library that changes what `cdr` does?

---

<div class="post-metadata">

**Author:** ![louberlu](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/louberlu/32/1142_2.png) [@louberlu](https://racket.discourse.group/u/louberlu)\
**Post date:** [May 4, 2023, 8:59pm UTC](https://racket.discourse.group/t/function-not-reading-all-the-element-in-a-list/1918/3 "2023-05-04T20:59:46Z")

</div>

No, there is only this line at the start of the code.

```scheme
#lang racket

```

---

<div class="post-metadata">

**Author:** ![samth](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/samth/32/3_2.png) [@samth](https://racket.discourse.group/u/samth)\
**Post date:** [May 4, 2023, 9:04pm UTC](https://racket.discourse.group/t/function-not-reading-all-the-element-in-a-list/1918/4 "2023-05-04T21:04:55Z")

</div>

Ok, I don't have any idea what happened with your `cdr` examples, but the problem in your functions is that you are iterating through all the elements in the list and comparing them with `x` but `'a` is not an element of the first list. The first list has only two elements: the symbol `'b` and the list `'(a b)`. If you want to look at the elements of sublists then you will need to traverse them explicitly or flatten the list first.

---

<div class="post-metadata">

**Author:** ![shawnw](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/shawnw/32/1031_2.png) [@shawnw](https://racket.discourse.group/u/shawnw)\
**Post date:** [May 5, 2023, 5:47am UTC](https://racket.discourse.group/t/function-not-reading-all-the-element-in-a-list/1918/5 "2023-05-05T05:47:59Z")

</div>

Racket's `cond` has `else`, you know. Don't need to use `#t` as a catch-all like it was Common Lisp.

Hint: You're missing the case where you need to recurse if the `car` of the list is itself a list.

```scheme
(define occur (lambda (x L)
                (cond
                  ((null? L) 0)
                  ((eq? x (car L)) (+ 1 (occur x (cdr L))))
                  ((list? (car L)) #;(Fill in the blanks))
                  (else (occur x (cdr L))))))

```

You might want to use a test other than `eq?` too.

---

<div class="post-metadata">

**Author:** ![gus-massa](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/gus-massa/32/507_2.png) [@gus-massa](https://racket.discourse.group/u/gus-massa)\
**Post date:** [May 5, 2023, 1:54pm UTC](https://racket.discourse.group/t/function-not-reading-all-the-element-in-a-list/1918/6 "2023-05-05T13:54:10Z")

</div>

> [@louberlu](#):
>
> `> (occur 'a '(b (a b)))`

Note that `'(b (a b))` is `(list b (list a b))` that is different from `(list b a b)`. The first example has an additional "container".

---

<div class="post-metadata">

**Author:** ![louberlu](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/louberlu/32/1142_2.png) [@louberlu](https://racket.discourse.group/u/louberlu)\
**Post date:** [May 11, 2023, 9:27pm UTC](https://racket.discourse.group/t/function-not-reading-all-the-element-in-a-list/1918/7 "2023-05-11T21:27:11Z")

</div>

Hello,  
Sorry for the late response. I found the solution.

```scheme
(define occur2 (lambda (x L)
                (cond
                  ((null? L) 0)
                  ((list? (car L)) (+ (occur2 x (car L)) (occur2 x (cdr L))))
                  ((eq? x (car L)) (+ 1 (occur2 x (cdr L))))
                  (#t (occur2 x (cdr L)))
                )))

```

All I had to do was to verify if (car L) was a list and use imbrication with this.

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [May 12, 2023, 5:06am UTC](https://racket.discourse.group/t/function-not-reading-all-the-element-in-a-list/1918/8 "2023-05-12T05:06:55Z")

</div>

Great Job!

Can it be simplified?

```scheme
#lang racket

;; count the number of times that 'x' occurs in the s-expression L
(define occur2 (lambda (x L)
                (cond
                  [(pair? L) (+ (occur2 x (car L)) (occur2 x (cdr L)))]
                  [else (cond [(equal? x L) 1]
                              [else 0])])))

(require rackunit)
(check-equal? (occur2 'a '(a (b a) a (b b (a) b))) 4)

```

It's true that the inner cond can be flattened, but this one clearly adheres to the s-expression template, so it reads more nicely to me. I also like the "one-or-zero" clarity of the inner cond.

---

<div class="post-metadata">

**Author:** ![louberlu](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/louberlu/32/1142_2.png) [@louberlu](https://racket.discourse.group/u/louberlu)\
**Post date:** [May 13, 2023, 5:15am UTC](https://racket.discourse.group/t/function-not-reading-all-the-element-in-a-list/1918/9 "2023-05-13T05:15:37Z")

</div>

It's simpler than mine, but my professor told us to use only the basic function of Scheme while we're still at the beginner level. So no 'if' or 'else', etc., but I will keep this one as another solution.

---

<div class="post-metadata">

**Author:** ![shawnw](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/shawnw/32/1031_2.png) [@shawnw](https://racket.discourse.group/u/shawnw)\
**Post date:** [May 13, 2023, 5:33am UTC](https://racket.discourse.group/t/function-not-reading-all-the-element-in-a-list/1918/10 "2023-05-13T05:33:59Z")

</div>

I'd call `if` simpler than `cond`... 🤔

(`cond` is often defined as a macro that expands to a series of `if`'s)

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [May 13, 2023, 7:11pm UTC](https://racket.discourse.group/t/function-not-reading-all-the-element-in-a-list/1918/11 "2023-05-13T19:11:30Z")

</div>

That makes sense. In that case, replace `else` with `#t` and you're done.
