gbhall
gbhall

Reputation: 13279

Custom function for length of a list in Scheme?

My lecturer has provided the following code:

(define (length list)
(cond (( null ? list) 0 )
(( atom ? list) 1 )
( else
( + 1 ( length (cdr list))))

However it wouldn't compile and Scheme kept waiting for input, so I rewrote it in a way that looks tider to me and noticed it had 2 missing brackets (please note this is the first time I've touched Scheme, I'm not sure of the correct way of laying it out and writing it):

(define 
    (hello list)
    (cond 
        (( null ? list) 0 )
        (( atom ? list) 1 )
        (else
            (+1
                ( hello (cdr list))
            )
        )
    )
)

I also renamed it to hello just to make it obvious that this is my code executing.

Running it however gets the following error:

]=> (hello '(a b c))

;Unbound variable: ?

What's wrong with my function?

Upvotes: 1

Views: 3594

Answers (3)

Óscar López
Óscar López

Reputation: 236004

Your hello procedure suffers from an excessive amount of white space :P . I understand you were trying to improve its readability, but in doing so you introduced a couple of errors. Also notice that in Scheme, the usual way to write closing parenthesis is all in the same line, not in separate lines (unlike what's done with curly braces in other programming languages).

Here's the recommended way to format your code, also fixing the syntax errors:

(define (hello lst)
  (cond ((null? lst) 0)
        ((atom? lst) 1)
        (else (+ 1 (hello (cdr lst))))))

Be aware that:

  • There must not be a white space between null and ?, same thing for atom and ?: the procedures are called null? and atom?, not null and atom, and a single ? means nothing
  • There must be an space between + and 1, the procedure for addition is called + not +1
  • It's a bad idea to call a parameter list, that name clashes with the built-in procedure list, so I renamed it to lst

As a side note: the procedure as written is unnecessarily complex, noting that the length as defined does not take in consideration the nested lists, it could have been expressed as simple as this:

(define (hello lst)
  (cond ((null? lst) 0)
        (else (+ 1 (hello (cdr lst))))))

Upvotes: 4

Robert Fisher
Robert Fisher

Reputation: 598

Firstly, the names of the functions are “null?” and “atom?”. Since you’ve separated the “?” from them with a space, Scheme is treating the question marks as if they are separate symbols instead of being part of the function names.

Also, you will want to use “+ 1” separated with a space instead of “+1” for the same reason. The name of the function is “+” and “1” is its first argument.

Upvotes: 0

sepp2k
sepp2k

Reputation: 370172

(null ? list)

This calls the function null with the arguments ? and list. However, as the error message states, there is no variable named ? (nor is there a function named null, but Scheme didn't get that far, so the error message didn't mention it).

There is however a function named null?, which is almost certainly the function you meant to call. So:

(null? list)

Note that the ? in null? is simply part of the function name and you can't put a space in the middle of a name.

The same applies to (atom ? list) on the next line.

Upvotes: 1

Related Questions