What is the difference between '('() 2 3) and '(() 2 3) in Scheme? - scheme

I just found out, that:
(null? (car '('() 2 3)))
returns false, and:
(null? (car '(() 2 3)))
returns true.
What's the difference between this two formats?

Remember that 'X is just an abbreviation for the two element list: (quote X).
So (car '(() 2 3)) is an abbreviation for (car (quote (() 2 3))), while (car '('() 2 3))) is an abbreviation for (car (quote ((quote ()) 2 3))).
Since (quote something) evaluates to something, when the system evaluates (car (quote ((quote ()) 2 3))) the first step of evaluation produces: (car ((quote ()) 2 3)). And the car of that list produces its first element, that is (quote ()).
So it is not null, and the result is false.

Related

How to invert the predicate here?

I have the following filter procedure:
; (2) filter
(define (filter test sequence)
; return a list of the elements that pass the predicate test
(let ((elem (if (null? sequence) nil (car sequence)))
(rest (if (null? sequence) nil (cdr sequence))))
(cond ((null? sequence) nil)
((test elem) (cons elem (filter test rest)))
(else (filter test rest)))))
And here would be an example of using it to return the even-numbered elements of a list:
(define even? (lambda (x) (= (modulo x 2) 0)))
(define sequence '(1 2 3 4 5 8 9 11 13 14 15 16 17))
(filter even? sequence)
; (2 4 8 14 16)
Is there a simple way to use the not test to invert the selection? For example, I thought the following might work:
(filter (not even?) sequence)
But it returns an error. I can define odd separately, of course:
(define odd? (lambda (x) (not (even? x))))
But I'm trying not to do this. Is there a way to write the odd procedure without defining it directly, but instead using the not directly like I'm trying to do above?
There is a complement function in Common Lisp that does what I think you are looking for. complement is a higher-order procedure that takes a procedure as its argument, and returns a procedure that takes the same arguments as the input procedure and performs the same actions, but the returned truth value is inverted.
Racket has a similar procedure, negate, and it is easy enough to implement this in Scheme:
(define (complement f)
(lambda xs (not (apply f xs))))
> (filter even? '(1 2 3 4 5))
(2 4)
> (filter (complement even?) '(1 2 3 4 5))
(1 3 5)
> (> 1 2 3 4 5)
#f
> ((complement >) 1 2 3 4 5)
#t
And in Racket:
scratch.rkt> (filter even? '(1 2 3 4 5))
'(2 4)
scratch.rkt> (filter (negate even?) '(1 2 3 4 5))
'(1 3 5)
scratch.rkt> (> 1 2 3 4 5)
#f
scratch.rkt> ((negate >) 1 2 3 4 5)
#t
The general answer to this is to simply compose not and the function you care about. Racket has a compose function which does this, but you can easily write a simple one yourself:
(define (compose-1 . functions)
;; simple-minded compose: each function other than the last must
;; take just one argument; all functions should return just one
;; value.
(define (compose-loop fns)
(cond
((null? fns)
(λ (x) x))
((null? (cdr fns))
(car fns))
(else
(λ (x) ((car fns) ((compose-loop (cdr fns)) x))))))
(compose-loop functions))
Making it efficient and more general takes more work of course.
Then you can define odd? (which is already defined of course):
(define odd? (compose-1 not even)
Or in fact define a more general CL-style complement function:
(define (complement f)
(compose-1 not f))
One option is to write an invert function which will curry things along (so the initial function still accepts one argument) until the final evaluation occurs:
(define invert (lambda (func) (lambda (x) (not (func x)))))
(define sequence '(1 2 3 4 5 6 8 9 11 13 14 15 16 17))
(filter (invert even?) sequence)
; (1 3 5 9 11 13 15 17)

Scheme append function workflow

Hello I am looking at the append function
(define ( append x y )
(if (null? x)
y)
(cons (car x)
(append (cdr x)
y))))
I understand how the list is generated but when the first list x is empty we directly return y,I don't see how we connect it to the first list "x".Does the process go like this (cons a1(cons a2....(cons an y).. )) and how does the program understand to plug in y at (cons an y),Is it because in the end the expression is (cons an-1 ,append (cdr x) y ) and the result of (append (cdr x ),y) is y?
Your function has an error in it such that is in parsing has one closing parens too much in the end. I thin kit's because you close if just after y. Because of that it will always do the last expression and it fails when x is empty.
The correct append looks like this:
(define (append x y)
(if (null? x)
y
(cons (car x)
(append (cdr x)
y))))
I like to explain recursive functions by simplest to general so we start off with the obvious, the base case:
(append '() '(3 4))
This will be #t for x being null? and the result is (3 4). Now lets try with a one element list as x:
(append '(2) '(3 4))
This is #f for x being `null? thus you can substitute it with:
(cons (car '(2))
(append (cdr '(2))
'(3 4)))
We can evaluate the accessors on '(2):
(cons 2 (append '() '(3 4))
Since we did the base case before we know the answer to the append part, which is '(3 4) so we end up with:
(cons 2 '(3 4)) ; ==> (2 3 4)
Lets do a new x:
(append '(1 2) '(3 4))
Here as the previous x is not null? so you substitute with the alternative again:
(cons (car '(1 2))
(append (cdr '(1 2))
'(3 4)))
As the previous time we can evaluate the accessors:
(cons 1
(append '(2)
'(3 4)))
Notice that again we have familiar arguments to append so we could just substitute that with our last result, however I take the step before so you see the pattern you noticed:
(cons 1 (cons 2 (append '() '(3 4)))) ; ==>
(cons 1 (cons 2 '(3 4))) ; ==>
(cons 1 '(2 3 4)) ; ==>
; ==> (1 2 3 4)
So if you have a 12 element x it gets 12 cons nested before hitting the base case and then it evaluates the the inner to the outer since list are always created from end to beginning since the functions need to evaluate their arguments before applying.

writing filter function using foldr?

Currently trying to write a filter function that takes a list of procedures and a list of numbers, deletes the procedures that does not return true on every element of the list of numbers.
What I have done is the following, currently taking a single procedure and runs through the list to create a list stating whether the procedure is true or false for each element.
Using foldr, or map if required (non recursive)
(define (my-filter ps xs)
(foldr (λ (x y)
(cons (ps x) y)) '() xs))
How do I delete the procedure if it has at lease one #f?
i.e.
currently
> (my-filter even? '(1 2 3 4))
(#f #t #f #t)
> (my-filter even? (2 4))
(#t #t)
want
> (my-filter (list even?) '(1 2 3 4))
(list)
> (my-filter (list even?) '(2 4))
(list even?)
You can solve this by using Racket's built-in andmap procedure, which tests if a condition is true for all elements in a list - like this:
(define (my-filter ps xs)
(foldr (lambda (f acc)
(if (andmap f xs) ; if `f` is true for all elements in `xs`
(cons f acc) ; then add `f` to the accumulated output
acc)) ; otherwise leave the accumulator alone
'() ; initially the accumulator is an empty list
ps)) ; iterate over the list of functions
Notice that we do not "delete" functions from the output list, instead at each step we decide whether or not we should add them to the output list.
The advantage of foldr is that it preserves the same order as the input list, if that's not a requirement, foldl is more efficient because internally it uses tail recursion. Either way, it works as expected:
(my-filter (list even?) '(1 2 3 4))
=> '()
(my-filter (list even?) '(2 4))
=> '(#<procedure:even?>)
Start with some wishful thinking. Say we have a know of knowing if all xs return #t for any given f
(define (my-filter fs xs)
(foldr (λ (f y)
(if (every? f xs)
(cons f y)
y))
'()
fs))
Now let's define every?
(define (every? f xs)
(cond [(null? xs) #t]
[(f (car xs)) (every? f (cdr xs))]
[else #f]))
Let's check it out for (list even?)
(my-filter (list even?) '(1 2 3 4)) ; ⇒ '()
(my-filter (list even?) '(2 4)) ; ⇒ '(#<procedure:even?>)
Let's add another test in the mix
(define (gt3? x) (> x 3))
(my-filter (list even? gt3?) '(2 4)) ; ⇒ '(#<procedure:even?>)
(my-filter (list even? gt3?) '(4 6)) ; ⇒ '(#<procedure:even?> #<procedure:gt3?>)
Cool !
If you want to see "pretty" procedure names instead of the #<procedure:...> stuff, you can map object-name over the resulting array
(map object-name (my-filter (list even? gt3?) '(4 6))) ; ⇒ '(even? gt3?)
Even though foldl will give you a reversed output, I still think it would be better to use foldl in this case. Just my 2 cents.

Checking if a number occurs in a list of numbers

Write a procedure called direct-num-occurs? that checks whether a number occurs in a list of numbers. Examples:
> (direct-num-occurs? 1 '(2 3 1 4))
;=> #t
> (direct-num-occurs? 1 '(2 3 5 4))
;=> #f
This is what I tried:
(define direct-num-occurs?
(lambda (num ws)
(cond
[(null? ws) #f]
[(equal? num (car ws)) #t]
[else (direct-num-occurs? (cdr ws) num)])))
But I'm getting an error that says expected a pair.
For future reference, you're re-implementing the member procedure:
(define (direct-num-occurs? n lst)
(if (member n lst) #t #f))
... But I guess you're trying to write it from scratch. The implementation shown is basically correct, except that you passed the arguments in the wrong order in the last line. This should fix it:
(define direct-num-occurs?
(lambda (num ws)
(cond
[(null? ws) #f]
[(equal? num (car ws)) #t]
[else (direct-num-occurs? num (cdr ws))])))
Of course, it works as expected:
(direct-num-occurs? 1 '(2 3 1 4))
=> #t
(direct-num-occurs? 1 '(2 3 5 4))
=> #f

Error in scheme when using cadr

Can anyone clarify what this error means?
cadr: expects argument of type <cadrable value>; given (1)
cadr means car and cdr. (i.e, return the car of the cdr of a list). Both the following expressions have the same effect:
> (car (cdr '(1 2 3 4)))
2
> (cadr '(1 2 3 4))
2
(cadr '(1)) will fail because (cdr '(1)) evaluates to null.

Resources