Best way to check if a list is not null? - scheme

In Common Lisp, if I wanted to check whether a list was not null, I could simply use the list itself as the condition, since all non-nil lists are considered as true. However, I find that in Scheme, doing the same will make Scheme think that I am trying to call a function. Is there a better way to check whether or not a list is null in Scheme than to define another function that does (not (null? x))?

In Scheme, everything that's not #f is truthy, so '() is considered #t in if statements.
Thus,
(if '() "true" "false") => "true"
(not '()) => #f
Using (not (null? x)) is the most straightforward way of checking if a list is not null: it describes exactly what you want, and in corner cases where you're given something that's not a list, it will give you different behavior:
(if (not (null? #t)) "true" "false") => "true"
(if (not #t) "true" "false") => "false"

If you know that it's a list, you can use (pair? x), since every list is either a pair or '().

Related

true and false null values in lisp vs scheme

I want to use the function in a scheme program im writing however im unsure ho to translate the T & Nil values within the function. Can nil essentially be written as '() in scheme?
(define (listword (lambda (word)
(cond
((isvowel (car word)) (novowel word))
(T (novowel word NIL))))))
To avoid confusion I'll take Common Lisp as an exemplar of a 'traditional' Lisp and call it 'Lisp' below, as opposed to Scheme: Scheme is also a Lisp of course but I want to have to type less.
Both Lisp and Scheme use the common convention that there is a single distinguished false object with everything else being true. In the construction of lists, both Lisp and Scheme also need to have a special distinguished 'empty list' element which is also unique. Lisp then chooses to pun, making the empty list and false be the same object: Scheme does not, and treats them as distinct. Additionally, Lisp provides a name for the empty list object, while Scheme does not, and Scheme also does not treat the empty list object as self-evaluating while Lisp does. Both languages provide a canonical true object as well, but again Lisp provides a name for it while Scheme doesn't. In both languages the true and false objects are self-evaluating.
So.
(Common) Lisp:
all objects are true except for the empty list, () -- (if () 1 2) evaluates to 2;
the empty list is self-evaluating -- (eq '() ()) is true;
the empty list is unique -- (eq () ()) and (eq () '()) are both true, as is (eq () (cdr (list 1))) for instance;
the empty list has a name, NIL -- (eq nil ()) & so on;
there is a canonical true object whose name is T and whose value is T;
while it is perhaps disputed, I think it is better to use NIL when you want to talk about false and () when you want to talk about the empty list.
Scheme:
all objects are true except for the special false object which is #f -- (if #f 1 2) evaluates to 2 while (if x 1 2) evaluates to 1 for x having any value not eq? to #f;
#f is self-evaluating --(eq? #f '#f) is true;
#f is unique;
#f has no special name in the sense that there is no symbol whose value it is (this is probably not the right terminology in Scheme);
there is a canonical true object, #t, although all objects are true other than #f;
there is a unique empty list object, () -- this object is not the same as #f, is not self-evaluating and does not have a name, so (eq? #f '()) is false, but (eq? '() '()) is true, as is (eq? '() (cdr (list 1))), while (if '() 1 2) evaluates to 1 and (eq? () 1) is an error.
Disclaimer: my knowledge of CL is better than my knowledge of Scheme.
In Common Lisp nil/'nil/()/'() represents the same value nil and it is both the empty list and the one false value. In Scheme they are two different values, '() for the empty list and #f as the false value. When translating Common Lisp one needs to determine if the value represents a false value or an empty list. In some cases you will have the empty list being used as a boolean and thus you would need to do (not (null? v)) where CL just does v. The reason for this is that only #f is false in Scheme and thus the empty list is a true value. (if '() #t #f) ; ==> #t
In Common Lisp t can be replaced by #t, but in Scheme there are special symbols in some forms like else in cond that is the idiomatic way to do the alternative term.
I guess you're translating some Common Lisp code to Scheme. In Scheme, the T at the end of a cond expression can be replaced by true, but the idiomatic way is to use an else. And NIL is just the empty list '(), sometimes aliased as null.
Also, be careful with how you define a procedure, you wrote an incorrect opening parenthesis in the first line - the correct way is:
(define listword
(lambda (word)
...))
Or equivalently (and perhaps more idiomatic):
(define (listword word)
...)

Scheme: solving task WITHOUT using if/cond?

So I've gotten rather simple task, in theory.
"Create a procedure where you take an integer as a parameter. If the integer is 0, return 0. If the integer is less than 0, return -1. If the integer is more than 0, return 1.
Solve this task without using if/cond(the only special forms allowed, are define, and, or)."
A very unpractical task, but a requirement for my course nonetheless. I've been stuck with this task for hours now, so I'd love some input!
Keep in mind that the procedure must return -1, 0 or 1. #t or #f are not good enough.
Both and and or are special versions of if. Eg.
(and a b) ; is the same as
(if a b #f)
(and a b c ...) ; is the same as
(if a (and b c ...) #f)
(or a b) ; is the same as
(if a
a ; though a is only evaluated once!
b)
(or a b c ...) ; is the same as
(if a
a ; though a is only evaluated once!
(or b c ...))
Notice that for 3 or more elements the result has and or or in it. You just apply the same transformation until you have something with just if.
If you want something like:
(if a 'x 'y)
You see that its obviously (or (and a 'x) 'y) since it turns into
(if (if a 'x #f)
(if a 'x #f)
'y)
Know that every value except #f is considered a true value. The basic method of doing this in "reverse" is knowing how and and or short circuits like if. If you need a special value returned instead of the result of a predicate you use and:
(and (null? x) 'empty-result)
If you need a false value to continue logic you use or
(or (and (null? x) 'empty-result)
(and (pair? x) 'pair-result))
If you need a default and have a or you just add it.
(or (and (null? x) 'empty-result)
(and (pair? x) 'pair-result)
'default-result)
If you happen to have and in the outer you need to wrap an or to get the default-result:
(or (and ...)
'default-result)
Good luck!
Here's a pretty simple implementation:
(define (signum n)
(or (and (zero? n) 0)
(and (positive? n) 1)
(and (negative? n) -1)))
Edit: I wrote my answer before I read Sylwester's post, but you should definitely read it for the theory of how this construction works.

using an abstraction

If the predicate bit? returns #t if the items is 1 or 0
(define bit?
(lambda (item)
(if (equal? item 0)
#t
(if (equal? item 1)
#t
#f))))
how can i use bit? in a new procedure, all-bits? that returns #t if all items in the list are bits? I can't figure it out
this is what i tried.
(define all-bits?
(lambda (ls)
(cond
[(null? ls) #t]
[(equal? (car ls all-bits?)) bit?]
[else (all-bits? ls (cdr ls))]))
The 2nd of your cond conditions is entirely wrong. It is syntactically wrong; equal? takes two parameters, car only takes one and bit also requires one, yet you are passing 1, 2 and 0 parameters, respectively. It also makes no sense: your helper function bit? is designed to test a single item, yet you're not testing anything with it. Why is all-bits? in that line at all?
The 3rd cond line is syntactically wrong: again, you're passing two parameters to a function that only takes one.
You need to be saying 'Return true if the first atom is a bit and the second atom is a bit and (and so on, and so on). That structure simply isn't represented in your code.
I'd also argue that all-bits should return false for the empty list and true where you have a list with a single bit, but maybe (all-bits? '()) ==> #t was specified in the original course question.
To do it your way (true for the empty list), your cond should only have two statements;
(cond
((null? l) #t)
(else ("Return true if the first atom is a bit **and** if the second atom is a bit **and** the third (and so on, and so on, recursively)"))
To do it my way, it would look like this:
(cond
((null? l) #f)
((and (null? (cdr l)) ("something here to test that (car l) is a bit")) #t)
(else ("Return true if the first atom is a bit **and** if the second atom is a bit **and** the third (and so on, and so on, recursively)")).
Should be clear that the bits in quotes are not real code.
I haven't done your homework for you, but I hope all my comments have made it more clear what you have to do. Even if you try to do your version rather than mine, mine actually includes a big hint to how you should structure the final line.
If you haven't yet been shown how to use and, use nested if statements.

empty list without empty word in Scheme

I am writing a recursion function returning an empty list in the base case. However the output of functions shows "empty" word in the my list, which I don't want.Like this;
(list (list 'abc) (list 'def) empty (list 'ghi))
How can I prevent this? Thanks.
The problem is probably because Racket has several printing styles for values. Try changing it (in the language selection dialog) to "write" or whatever it's called, which should make it output ((abc) (def) () (ghi)) instead.
The empty that you see in the result is not a "word" -- note that it's not quoted. If you do expect an empty list in the result, then it looks like you got one. You can even check for that:
> (empty? (third (list (list 'abc) (list 'def) empty (list 'ghi))))
#t
Without knowing details, my best guess would be something like
(let ((result (recursive-call ...)))
(if (null? result) (resursive-call (cdr whatever-list))
(cons result (cdr whatever-list)))
Essentially, just check if the result is the empty list, and if so, don't put it into the list that you're returning.

Function in Scheme that checks whether the length of a list is even

Hi I have edited the code for function in scheme that checks whether the length of a list is even.
(define even-length?
(lambda (l)
(cond
((null? l)#f)
((equal? (remainder (length(l)) 2) 0) #t)
(else #f))))
Is it corrrect?
You seem to have the syntax for if and cond all mixed up. I suggest referring to the language reference. if only has two clauses, and you don't write else for the else clause. (Hint: You shouldn't need an if for this function at all.)
Also, consider whether it makes sense to return null if the list is null; probably you want to return #t or #f instead.
Oh yeah, and rewrite your call of length to be a proper prefix-style Scheme function call.
The code is clearly wrong -- your %2 assuming infix notation, where Scheme uses prefix notation. The syntax of your if is wrong as well -- for an if, the else is implicit (i.e. you have if condition true-expression false-expression. In this case, you're trying to return #t from one leg and #f from another leg -- that's quite unnecessary. You can just return the expression that you tested in the if.
Edit: one other detail -- you should really rename this to something like even-length?. Even if I assume that it's a predicate, a name like even would imply to me that (even 3) should return #f, and (even 4) should return #t -- but in this case, neither works at all.
Edit2: Since mquander already gave you one version of the code, I guess one more won't hurt. I'd write it like:
(define (even-length? L) (even? (length L)))
I don't like using lower-case 'l' (but itself) much, so I've capitalized it. Since even? is built in, I've used that instead of finding the remainder.
Running this produces:
> (even-length? `(1 2 3))
#f
> (even-length? `(1 2 3 4))
#t
>
This is different from what you had in one respect: the length of an empty list is 0, which is considered an even number, so:
(even-length? `())
gives #t.
(define even-length? (lambda (l)
(even? (length l))))
Usage:
(even-length? '(1 2 3 4))
#t
(even-length? '(1 2 3 ))
#f
As others pointed out, there is indeed a predicate to check evenness of a number, so why not using it?
EDIT: I just saw Jerry Coffin wrote the same function witht the same example... Sorry for repeating :-)

Resources