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

(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))))

Related

In Scheme, does `or` and `and` short circuit?

Do and and or short circuit in Scheme?
The following are two implementation of lat? (list of atoms). One uses cond … else and the other uses or and and. I was wondering if they are equivalent and the answer to that hinges on whether or and and have short circuit evaluation in Scheme.
(define lat?
(lambda (l)
(cond
((null? l) #t)
((atom? (car l)) (lat? (cdr l)))
(else #f))))
uses cond and else
(define lat?
(lambda (l)
(or (null? l)
(and (atom? (car l))
(lat? (cdr l))))))
uses or and and
I think or short-circuits. Why? I know (car ()) and (cdr ()) each produce Error: Attempt to apply…. If or didn’t short-circuit, then (lat? ()) would eventually evaluate (car ()) and produce the error. However, (lat? ()) does not produce the error, therefore (via Modus Tollens) or short-circuits. Is this correct? And does and short-circuit?
Yes, they both short-circuit per r6rs specification (didn't find html version of r7rs online but here a link to the pdf version of r7rs specification, see section 4.2):
If there are no <test>s, #t is returned. Otherwise, the expressions are evaluated from left to right until a <test> returns #f or the last <test> is reached. In the former case, the and expression returns #f without evaluating the remaining expressions. In the latter case, the last expression is evaluated and its values are returned.
and & or is subsequently defined in terms of test.

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.

Null use in a small Scheme script

I'm just learning how to write in Scheme and hitting a road block with the use of Null. I have the script below from this video series...
https://www.youtube.com/watch?v=Qqext1NwmqM&index=2&list=PLgyU3jNA6VjRMB-LXXR9ZWcU3-GCzJPm0
Script...
(define (my-map fn lst)
(if (null? lst)
null
(cons (fn (car lst)) (my-map fn (cdr lst)))))
This is just redefining the map function in Scheme. It fails at the third line as "null: undefined. cannot reference undefined identifier" when I pass a function and a list.
I just copied what the video shows so not sure why it's failing. If I switch out null for '(), that works. Anyone know why?
It's quite possible that your Scheme interpreter doesn't have the null symbol bound to the '() value, as this is not required by the language specification. Either do this:
(define null '())
Or equivalently this, as you already guessed:
(define (my-map fn lst)
(if (null? lst)
'()
(cons (fn (car lst))
(my-map fn (cdr lst)))))
Notice that the latest Scheme report states that (null? obj) should return #t
if obj is the empty list, otherwise returns #f
So it's ok to define null as '().

All: A Function Returning True if and only if All Elements of a List are True

I am looking for a built-in function in Racket that will return True iff all the items in a list are true.
I tried:
(define (all lst)
(when
(equal? lst '())
#t)
(if (not (car lst))
#f
(all (cdr lst))))
Giving error:
car: contract violation
expected: pair?
given: '()
A couple of testcases:
(all '(#t #f #t)) ; #f
(all '(#t #t #t)) ; #t
Could you please either fix it or point me to the built-in function?
(I googled, but got no meaningful result)
You've already accepted another answer that explains a nice way to do this, but I think it's worth pointing out what was wrong in your attempt, because it was actually very close. The problem is that true from the when block is completely ignored. It doesn't cause the function to return. So even when you have the empty list, you evaluate the when, and then keep on going into the other part where you call car and cdr with the same empty list:
(define (all lst)
(when ; The whole (when ...) expression
(equal? lst '()) ; is evaluated, and then its result
#t) ; is ignored.
(if (not (car lst))
#f
(all (cdr lst))))
A very quick solution would be to change it to:
(define (all lst)
(if (equal? lst '())
#t
(if (not (car lst))
#f
(all (cdr lst)))))
At that point, you can simplify a little bit by using boolean operators rather than returning true and false explicitly, and clean up a little bit by using empty?, as noted in the other answer:
(define (all lst)
(or (empty? lst)
(and (car lst)
(all (cdr lst)))))
You were actually very close at the start.
If you're looking for a builtin solution, you'll probably want to take a look at andmap, which applies a predicate over an entire list and ands the results together.
You could use this to implement all very simply.
(define (all lst)
(andmap identity lst))
By using identity from racket/function, all will just use the values in the list as-is. Instead of using identity explicitly, you could also use values, which is just the identity function on single values, so it's a somewhat common idiom in Racket.
There are two kinds of lists: empty ones and pairs.
Therefore we have the following structure:
(define (all xs)
(cond
[(empty? xs) ...]
[(pair? xs) ...]
[else (error 'all "expected a list, got: " xs)]))
Since all elements in the empty list are true, we get:
(define (all xs)
(cond
[(empty? xs) #t]
[(pair? xs) ...]
[else (error 'all "expected a list, got: " xs)]))
If a list begins with a pair, then all elements of the list are true,
if both the first element of the list and the rest of the elements of the list are true:
(define (all xs)
(cond
[(empty? xs) #t]
[(pair? xs) (and (first xs) (all (rest xs)))]
[else (error 'all "expected a list, got: " xs)]))
Note that part of the problem in your program is the use of when.
The result of
(when #t
'foo)
'bar
is 'bar. The construct when is only useful if you are using side effects (such as caused by set! and friends).
All is a higher order folding function. Scheme refers to these as "reductions" and reduce is available in SRFI-1
In Gauche Scheme:
(use srfi-1)
(define (all list-of-x)
(reduce (lambda (x y)
(and x y))
#t
list-of-x))
Will return #f or a value that evaluates to true. For example:
gosh> (all '(1 2 3))
1
If that's OK, then we're done. Otherwise we can always get #t with:
(use srfi-1)
(define (all-2 list-of-x)
(if (reduce (lambda (x y)
(and x y))
#t
list-of-x)
#t
#f))
And then wind up with:
gosh> (all '(1 2 3))
#t

Scheme getting last element in list

Im trying to write a simple scheme function that returns the last element of a list. My function looks like it should work, but I managed to fail on something:
(define (last_element l)(
(cond (null? (cdr l)) (car l))
(last_element (cdr l))
))
(last_element '(1 2 3)) should return 3
DrRacket keeps on giving me the errors:
mcdr: contract violation
expected: mpair?
given: ()
Since (null? '()) is true, I don't get why this doesn't work.
This is a function I think I will need for a homework assignment (writing the function last-element is not the assignment), and the instructions say that I cannot use the built-in function reverse, so I can't just do (car (reverse l))
How do I fix this function?
Your syntax is totally wrong. You have an extra set of parentheses around the body of the function, not enough around the cond clauses, and your recursive case isn't even within the cond, so it gets done whether the test succeeds or fails. The following procedure should work:
(define (last_element l)
(cond ((null? (cdr l)) (car l))
(else (last_element (cdr l)))))
Just to add: in professional-level Racket, the last function is a part of the racket/list library.
you can retrieve the last element of a list by calling
(define (lastElem list) (car (reverse list)))
or, recursively using if built-in
(define (last list)
(if (zero? (length (cdr list)))
(car list)
(last (cdr list))))
You can also do it like this.First find the lenght of a list by cdring it down.Then use list-ref x which gives the x element of the list.
For example list-ref yourlistsname 0 gives the first element (basically car of the list.)And (list-ref
yourlistsname (- length 1)) gives the last element of the list.

Resources