I have an symbol that evaluates to (quote ("all")). I would like to append "tests" to the end of the list, and get (quote ("all" "tests")) but I didn't find how to :
(define make-flags ''("all"))
(append make-flags '("tests")) ; Resolves to (quote ("all") "tests")
I suppose I would have to remove the quote by evaluate the make-flags twice and re-quote it, but I didn't find how to.
Yes, you'd need to remove the quote first. Try this:
(define make-flags ''("all"))
`'(,(append (cadr make-flags) '("tests")))
=> ''("all" "tests")
It works because make-flags is just a list of this form: (quote (quote ("all"))) and we can navigate it in the usual way with car and cdr.
The second you evaluate ''("all") you get the list (quote ("all")) and it is not a quoted list at all. This is a list of to elements, the symbol quote and the list ("all"). If you want to add an element to the second element you do it by recreating the outer list and replacing the second with the new list with the added element:
(define (add-second-element ele lst)
`(,(car lst) (,#(cadr lst) ,ele) ,#(cddr lst)))
(add-second-element 'goofy '((donald dolly) (mickey) (chip dale)))
; ==> (donald (mickey goofy) (chip dale))
(add-second-element "tests" ''("all"))
; ==> (quote ("all" "tests"))
If you're not too familiar with quasiquote it's possible to do it without since quasiquote is just fancy syntax sugar for cons and append:
(define (add-second-element-2 ele lst)
(cons (car lst) (cons (append (cadr lst) (list ele)) (cddr lst))))
(add-second-element-2 'goofy '((donald dolly) (mickey) (chip dale)))
; ==> (donald (mickey goofy) (chip dale))
Of course if the first element is always quote and there are only two elements these can easily be simplified in both versions.
Related
(define (min list)
(cond ((empty? (car list) '"It is empty")) <- Problem is here. Code work without this line.
((empty? (cdr list)) (car list)) ;to check list is empty
((< (car list) (min (cdr list))) (cdr list))
(else (min (cdr list) ))))
I am very new to scheme Programming language. I am trying to get minimum value from the list. When I put (), the program gives me an error: cdr: contract violation expected: pair? given: '(). What I am trying to do here is I want to print out It is empty when user type (). Is it possible do like that in Scheme programming?
You can find the answer to this question--and so much more--in How To Design Programs, 2e, a textbook written by the developers of the Racket language.
In this case, you want to be using the template for functions on lists. This is covered in section II, more specifically section 9.1.
The structure of a list in Scheme and other Lisp-languages is based on cons-cells. Each cons-cell contains a value (the car) and a pointer to the next cons cell (the cdr, pronounced see-dar) in the list, like this:
+-+-+
|1|----+
+-+-+ |
+-+-+
|2|---+
+-+-+ |
+-+-+
|3| |
+-+-+
The final cons-cell, where the list ends, contains a nil. In Scheme notation, a cons-cell looks like this:
(1 . 2)
So a list, without any syntactic sugar, would look like this:
(1 . (2 . (3 . (4 . nil))))
An empty list, consists of a cons cell that looks like this:
(nil)
Notice that the empty list has no car? An empty list is treated like a nil, so this:
(1 . (2 . (3 . (4 . ()))))
Works just like the previous one.
Now, when you use the syntactic sugar, lists look like this:
(1 2 3 4)
But the underlying structure is the same. So, to test if you have an empty list, test if it's nil (which Scheme does with the empty? function). So, instead of calling empty? on the car of the list, which is wrong thinking as well as an error, call it on the list. So your function should look like:
(define (min list)
(cond ((empty? list "It is empty"))
((empty? (cdr list)) (car list))
((< (car list) (min (cdr list))) (cdr list))
(else (min (cdr list) ))))
Notice that the second arm does not check that the list is empty, as your comment says: it checks if the list has only one or no element. If your cdr is empty, but your car isn't (which the second arm allows), then you have a one element list:
(foo . ())
Hope this helps!
For more information on how to improve your specific function, look at Oscar Lopez's answer to this question.
I think you want to print empty list or get min value, right?
(define (min list)
(if (null? list)
"It's empty."
(let loop ([loop_list list]
[min_value (car list)])
(if (null? loop_list)
min_value
(loop
(cdr loop_list)
(if (< min_value (car loop_list)) min_value (car loop_list)))))))
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
#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.
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.
I was wondering, how do you check if every element in a list is an integer or not? I can check the first element by using (integer? (car list), but if I do (integer? (cdr list), it always returns false (#f) because the whole of the last part of the list is not an integer as a group.
In this case let's say list is defined as.
(define list '(1 2 5 4 5 3))
(define get-integers
(lambda (x)
(if (null? x)
"All elements of list are integers"
(if (integer? (car x))
(get-integers (cdr x))
"Not all elements are an integer"))))
Practical Schemes provide functions for doing tests across whole sequences. An application of the andmap function, for example, would be appropriate. Racket provides a for/and to do something similar. If you really needed to write out the loop by hand, you'll be using recursion.
What you need to do is test each element in the list to see if it satisfies a condition (being an integer, in this case). When you evaluate (integer? (car list)) on a list of integers, you're checking if the first element in the list is an integer, and that's fine. But the expression (integer? (cdr list)) tests if a list is an integer (because cdr returns a list), and that won't work - you need to test the next element in the list, and the next, and so on until the list is empty.
There are several ways to do the above, the most straightforward would be to recur on the list testing each element in turn, returning false if a non-integer element was found or true if all the list was consumed without finding a non-integer element, like this:
(define (all-integers? lst)
(cond ((null? lst) #t)
((not (integer? (car lst))) #f)
(else (all-integers? (cdr lst)))))
A more practical approach would be to use a built-in procedure, like this:
(andmap integer? lst)
andmap will check if all the elements in lst evaluate to true for the given predicate. For example:
(andmap integer? '(1 2 3))
> #t
(andmap integer? '(1 "x" 3))
> #f
SRFI-1 uses the terms every and any rather than andmap and ormap. match can also be used:
(define list-of-integers?
(lambda (lst)
(match lst
(((? number?) ..1) #t)
(_ #f))))