Scheme returning wrong type to apply for list input - scheme

I am trying to write a program which will add numbers in a list. However, when I give the input as a list, Scheme does not give me an output.
My code is the following:
(define (sumlist lst)
(cond ( (pair? lst) (+ (car lst) (sumlist(cdr lst))) )))
Why does this happen? I am giving input properly, i.e, I am quoting the list.
I am giving input as follows:
(sumlist '(1 2 3))
EDIT:
I changed the question slightly. The list was not quoted in pair? 'lst and that is why I was getting an error.
Now, I am not getting an error. However, I am not getting any output either.
EDIT2:
I unquoted the list in pair? lst. However, now it is giving me the following error: Wrong type in arg2 #
I have updated the code accordingly.

Your function application syntax is wrong. Function application is always prefix in Scheme, i.e. car(lst) should be (car lst), etc.
Also, (pair? 'lst) is wrong, since you should not be quoting the argument. That will test if the symbol lst is a pair, which is obviously always false.
You need a base case for when you don't want to recurse—when you receive the empty list—which should return 0.
Putting all these together, and you should have this:
(define (sumlist lst)
(if (pair? lst)
(+ (car lst) (sumlist (cdr lst)))
0))
(I also changed cond to if since cond is unnecessary in this case.)

Related

Scheme: how to get first atom from list

I need help with one issue: I can't handle how to get the first atom from the list in SCHEME language. I think I should make a loop, something like "while" and compare each element on boolean (?atom) and print first matched item.
Unfortunately, It's difficult for me to handle scheme syntax.
Please, can you propose any solution for me?
define func ?atom:
(define (atom? x) (not (or (pair? x) (null? x))))
Recursion is not that different from the usual way yo solve problems - you just have to be careful and set some meaningful base cases. For instance, how would you solve this problem in Java? by traversing all the list, and stoping when either 1) we found the element that matches the condition or 2) there are no more elements. This is exactly what we need to do:
(define (first-atom lst)
(cond ((null? lst) #f) ; there are no more elements in the list
((atom? (car lst)) ; current element is an atom
(car lst)) ; return it
(else ; otherwise
(first-atom (cdr lst))))) ; look in the rest of the list
It works as expected:
(first-atom '((2) 42 (3)))
=> 42
(first-atom '((1) (2)(3)))
=> #f
In your question you have the definition to atom? that returns #t if the argument is an atom and #f otherwise.
The function should handle the empty list. eg. What should happen when you do this:
(first-atom '())
Thus you need to check if the argument is the empty list and return whatever you supposed to return when there are no atoms in the arguments. Then you'll have a else expression that handles the rest.
You can use first to get the first element to check if it is an atom and then return it or you recure with the rest of the list.
Now here is something very similar that finds the number of elements in a list:
(define (length lst)
(if (null? lst)
0 ; obviously a 0 length list
(+ 1 (length (cdr lst))))) ; obviously one plus whatever length the rest is
Imagine what happens if you do (length '(1 2)). It does (+ 1 (length '(2))) which again does (+ 1 (+ 1 (length '()))) which again does (+ 1 (+ 1 0)). Simple as that. All loops are recursive functions in Scheme.
You reference to while indicates you might be familiar with other programming languages. I knew C, C++, Pascal, perl, PHP, and Java when starting to learn Lisp and I suddenly realized all the languages I knew were only subtle dialects of one language, Algol. I wasn't learning my sixth language, but my second. Scheme doesn't have a while loop. It has recursion. you need to get a book and start at the first page as if you didn't know how to program at all as assimilation from Algol will point you in the wrong direction.

How do I find the number of lower case letters in Scheme Racket?

I'm trying to find the number of lower/upper case letters in a string, but there is a problem with my code:
(define case
(lambda (list)
(if(char-lower-case? (car list))
(case (cdr list))
(+ 1 (case (cdr list)))
)
))
(case (string->list "ScheMe"))
How can I solve this problem?
In your function you have two problems:
case is a predefined operator in racket/scheme
You don't test for an empty list.
Moreover, you use the parameter list, which is a primitive operator and should not be used as variable name.
Here is a working function:
(define (case1 lst)
(cond ((null? lst) 0)
((char-lower-case? (car lst)) (case1 (cdr lst)))
(else (+ 1 (case1 (cdr lst))))))
(case1 (string->list "ScheMe"))
Your code lacks a base case. (case '()) should evaluate to 0 but you get an error since you are doing car and cdr on nil.
Other things that might be wrong:
Your title indicates that you want to count lowercase letters but you increase for every uppercase.
list and case are names from the standard library. For R5RS it means undefined behaviour and for R6RS and later it means the library bindings would be unavailable. In #!racket (I guess you use this language since you tagged racket) it works as R6RS.

I have got this code to remove the last element of a list. How can i change this to remove a set word regardless of its location?

#lang racket
(define (remove-last lst)
(if (null? (cdr lst))
'()
(cons (car lst) (remove-last (cdr lst)))))
(remove-last '(Help Me Please))
This then prints out:
(Help Me)
How can I change this? For example if I wanted to remove me.
Like this, for example:
(define (remove-words lst words)
(cond
((null? lst)
'())
((member (car lst) words)
(remove-words (cdr lst) words))
(else
(cons (car lst) (remove-words (cdr lst) words)))))
then
> (remove-words '(Help Me Please) '(Me Help Not))
'(Please)
You can also use the procedures for sets:
(define (remove-words lst words)
(set-subtract lst words))
Please note that you are working with symbols here, not strings.
You can also solve the problem using filter-not and member together:
(define (remove-words lst words)
(filter-not (lambda (x) (member x words) lst))
If you want to cut down on the wordiness of that anonymous function, the tools most suited to that are curry and cut (with the latter needing a (require srfi/26) to use).
Currying a function turns it into a new function that accepts one argument, then returns another function that accepts one more argument, then again, then again, and so on until it has all the arguments it needs to call the original function. A curried version of remove-words would be called as ((remove-words lst) words) instead, and you could make it from our current implementation with (curry remove-words). This requires that the arguments be supplied in left to right order, which doesn't work for member. There's another form curryr that goes right-to-left, but because member takes an optional third argument it won't work.
You could use cut (from srfi 26) then, which lets you pick which arguments of a function you want to "lock-in" and which you want the new function to accept. (cut member <> words)creates a new function (lambda (arg) (member arg words)) and (cut * <> <> 8) creates (lambda (arg1 arg2) (* arg1 arg2 8)). So with this, remove-words looks like:
(require srfi/26)
(define (remove-words lst words)
(filter-not (cut member <> words) lst))
Although going with set-subtract is still probably the best solution since you should avoid reinventing the wheel as much as possible (unless you're trying to learn more about wheels). Nonetheless, it's very useful to have a firm grip on the general functions provided by Racket that make your life easier.

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.

How I can force scheme to return #f explicitly instead of just void?

(define every-aux
(lambda(status predicate lst)
(cond((null? lst) status)
((cond((equal? (predicate (car lst)) #t)
(set! status #t)
(every-aux status predicate (cdr lst)))
(else (set! status #f) status))))))
Above Procedure returns void if predicate does not match with every element in lst?
It does not have any problem is returning #t though if predicate matches every element of lst.
Changing the last line to
(else (set! status #f) status))))))
to
(else (set! status "#f") status))))))
returns "#f" so procedure is correct.
How I can force scheme to return #f explicitly instead of just void?
Your code is very messy:
You have a cond inside another, but cond is intended for multiple tests/results.
There is no reason to have that status modified -- Scheme uses call-by-value, so this is likely not doing whatever you think it does.
Specifically, there is no reason to use (else (set! status #f) status) -- you could just return #f directly.
The actual reason for your confusion is the weird cond nesting -- the second cond is actually used as a test, so if you make it (the inner cond) return #f, then the whole test of the outer cond is getting #f, which means that it (the outer cond) didn't get any true result, and resorts to returning an unspecified value (and if this is Racket, then that value is shown as #<void>). So if you flatten the two conds into one, your problem will go away.
Finally, if you're having problems at such a level, then you should consider using some textbook to familiarize yourself with the language. Specifically HtDP is intended to give you an easy path into getting familiar with the syntax.
#Eli Barzilay
After some I deliberation I could see the solution. Thanks for the pointers.
(define every?
(lambda (predicate list)
(if(null? list) "Empty List not allowed."
(every-aux? predicate list))))
(define every-aux?
(lambda (predicate lst)
(cond ((null? lst) #t)
((equal? (predicate (car lst)) #t) (every-aux? predicate (cdr lst)))
(else #f))))

Resources