I'd like to call set-union from a list of sets. How can I convert it into a form that set-union would take?
(define (return-set-list) (list (set 1) (set 2)))
(set-union (set) (return-set-list))
This returns an error for instance.
You could use apply
(apply set-union (cons (set) (return-set-list)))
Related
I have the list of values and want to take first x values from it and create (list (listof first x values) (listof next x values) and so on until this list gets empty...).
For example, given this list: (list "a" "b" "c" "d" "e" "f" "g" "h" "t")
return this: (list (list a" "b" "c") (list "d" "e" "f") (list "g" "h" "t"))
Thanks in advance :)
Remember what a datatype for a list is. Your class is probably doing something like:
;; A IntegerList is one of:
;; - '()
;; - (cons Integer IntegerList)
Given that, your template should reflect this structure. I will solve the base case (where we want to turn a list of integers into lists of one integers.
First I will define a 1List datatype as:
;; a 1List is:
;; - (cons Integer '())
Next, the purpose statement and signature for the function will be:
;; Takes a list of integers and returns a list of 1Lists of the same integers
;; IntegerList -> 1List
(define (make-1list lst)
...)
Okay cool. Now we need test cases:
(check-expect (make-1list (list 1 2 3)) (list (list 1) (list 2) (list 3)))
(check-expect (make-1list (list)) (list))
(check-expect (make-1list (list 42)) (list (list 42)))
Finally, I can make my template:
(define (make-1list lst)
(cond [(null? lst) ...]
[else ... (first lst) ... (rest lst) ...]))
(Note that it sometimes makes sense to make some of the template first, to help you guide what tests you need.)
Finally, we can fill in our code:
(define (make-1list lst)
(cond [(null? lst) '()]
[else (cons (list (first lst)) (make-1list (rest lst)))]))
And finally, are examples are also tests so we just need to run them to make sure everything works.
Now, since you want to make 3Lists instead of 1Lists, do you see how you can follow this recipe to solve the problem?
Write down your data definition.
Make your purpose statement and signature.
Make your examples.
Make your template.
Write the actual function.
Turn your existing examples into tests.
Following this pattern should help you break the problem down into smaller steps. Good luck.
Better way to accomplish this task is to use accumulators & recursion.
Hello I am looking forward to convert my existing function:
(defun checkMember (L A)
(cond
((NULL L) nil)
( (and (atom (car L)) (equal (car L) A)) T )
(T (checkMember (cdr L) A))))
To use map functions, but i honestly cant understand exactly how map functions work, could you maybe advice me how this func's work?
this is my atempt:
(defun checkMem (L A)
(cond
((NULL L) nil)
( (and (atom (car L)) (equal (car L) (car A))) T )
(T (mapcar #'checkMem (cdr L) A))))
A mapping function is not appropriate here because the task involves searching the list to determine whether it contains a matching item. This is not mapping.
Mapping means passing each element through some function (and usually collecting the return values in some way). Sure, we can abuse mapping into solving the problem somehow.
But may I instead suggest that this is a reduce problem rather than a mapping problem? Reducing means processing all the elements of a list in order to produce a single value which summarizes that list.
Warm up: use reduce to add elements together:
(reduce #'+ '(1 2 3)) -> 6
In our case, we want to reduce the list differently: to a single value which is T or NIL based on whether the list contains some item.
Solution:
(defun is-member (list item)
(reduce (lambda (found next-one) (or found (eql next-one item)))
list :initial-value nil))
;; tests:
(is-member nil nil) -> NIL
(is-member nil 42) -> NIL
(is-member '(1) 1) -> T
(is-member '(1) 2) -> NIL
(is-member '(t t) 1) -> NIL ;; check for accumulator/item mixup
(is-member '(1 2) 2) -> T
(is-member '(1 2) 3) -> NIL
...
A common pattern in using a (left-associative) reduce function is to treat the left argument in each reduction as an accumulated value that is being "threaded" through the reduce. When we do a simple reduce with + to add numbers, we don't think about this, but the left argument of the function used for the reduction is always the partial sum. The partial sum is initialized to zero because reduce first calls the + function with no arguments, which is possible: (+) is zero in Lisp.
Concretely, what happens in (reduce #'+ '(1 2 3)) is this:
first, reduce calls (+) which returns 0.
then, reduce calls (+ 0 1), which produces the partial sum 1.
next, reduce calls (+ 1 2), using the previous partial sum as the left argument, and the next element as the right argument. This returns 3, of course.
finally, reduce calls (+ 3 3), resulting in 6.
In our case, the accumulated value we are "threading" through the reduction is not a partial sum, but a boolean value. This boolean becomes the left argument which is called found inside the reducing function. We explicitly specify the initial value using :initial-value nil, because our lambda function does not support being called with no arguments. On each call to our lambda, we short-circuit: if found is true, it means that a previous reduction has already decided that the list contains the item, and we just return true. Otherwise, we check the right argument: the next item from the list. If it is equal to item, then we return T, otherwise NIL. And this T or NIL then becomes the found value in the next call. Once we return T, this value will "domino" through the rest of the reduction, resulting in a T return out of reduce.
If you insist on using mapping, you can do something like: map each element to a list which is empty if the element doesn't match the item, otherwise nonempty. Do the mapping in such a way that the lists are catenated together. If the resulting list is nonempty, then the original list must have contained one or more matches for the item:
(defun is-member (list item)
(if (mapcan (lambda (elem)
(if (eq elem item) (list elem))) list)
t))
This approach performs lots of wasteful allocations if the list contains many occurrences of the item.
(The reduce approach is also wasteful because it keeps processing the list after it is obvious that the return value will be T.)
What about this:
(defun checkMember (L a)
(car (mapcan #'(lambda (e)
(and (equal a e) (list T)))
L)))
Note: it does not recurse into list elements, but the original function did not either.
(defun memb (item list)
(map nil
(lambda (element)
(when (eql item element)
(return-from memb t)))
list))
Try this,
Recursive version:
(defun checkmember (l a)
(let ((temp nil))
(cond ((null l) nil) ((find a l) (setf temp (or temp t)))
(t
(mapcar #'(lambda (x) (cond ((listp x)(setf temp (or temp (checkmember x a))))))
l)))
temp))
Usage: (checkmember '(1 (2 5) 3) 20) => NIL
(checkmember '(1 (2 5) 3) 2) => T
(checkmember '(1 2 3) 2) => T
(checkmember '((((((((1)))))))) 1) = T
(define list45 (map number->string(build-list 1000 values)))
list45
(first (list45))
(rest (list45))
ERROR:
application: not a procedure;
expected a procedure that can be applied to arguments
I am trying to iterate through the list that i converted to strings. to do that i tried to use the first and rest functions to view everything in the list. Why am i getting errors for this?
Thanks
Just drop the parentheses around the list:
(first list45)
=> "0"
(rest list45)
=> '("1" "2" … "998" "999")
In Scheme, when you surround something between (), the interpreter evaluates that as a function application with no arguments. Given that list45 is not a function, the "application: not a procedure" error is raised. In Racket is very easy to iterate over the list:
(for ([e (in-list list45)])
(displayln e))
But if for some reason you want to use first and rest to traverse the list, here's one possibility, using explicit recursion:
(define (iterate lst)
(unless (empty? lst)
(displayln (first lst))
(iterate (rest lst))))
(iterate list45)
I have a list of lists as follows in Common Lisp of the form
((1 2) (3 4) (5 6))
and which is the value of the variable list, and I want to have three new variables whose values are the elements of the list. For instance:
list-1 (1 2)
list-2 (3 4)
list-3 (5 6)
Is there any function which does this operation?
Use setq, first (or nth and elt) to set:
(setq list-1 (first list)
list-2 (second list)
list-3 (third list))
Or destructuring-bind to bind:
(destructuring-bind (list-1 list-2 list-3) list
...)
Again, destructuring-bind binds the variables instead of assigning them (i.e., it is like let, not like setq).
The notion of binding elements of a list to names of the form list-# can be generalized.
You can create a function to generate a lambda with the ordinal list names as arguments, and a given body:
(defun make-list-lambda (n body)
(let ((list-names (loop for index from 1 to n
collect (intern (format nil "LIST-~D" index)))))
`(lambda ,list-names
(declare (ignorable ,#list-names))
,#body)))
And then create a macro to create the lambda, compile it, and apply it to the list:
(defmacro letlist (list &body body)
(let ((assignments (gensym)))
`(let ((,assignments ,list))
(apply (compile nil (make-list-lambda (length ,assignments) ',body))
,assignments))))
In this way, the assignments are localized to the lambda body:
CL-USER> (letlist '(a b c d e f)
(format t "list-1: ~A~%" list-1)
(format t "list-3: ~A~%" list-3))
list-1: A
list-3: C
NIL
Note: The forms will be compiled every time the macro is invoked, since it will not be known how many list-# arguments will be present until the list is presented!
First set your list to a variable, for instance mylist. Then spit out the required
output using the function format. I'm using CLISP. Hope this helps. This is the actual REPL output.
(setf mylist '((1 2) (3 4) (5 6)) )
((1 2) (3 4) (5 6))
(format t "list-1 ~d~%list-2 ~d~%list-3 ~d" (car mylist)
(second mylist) (last mylist))
list-1 (1 2)
list-2 (3 4)
list-3 ((5 6))
NIL
[142]>
Can someone show me how to get rid of "NIL' in the above output?
I'm new to Lisp. Just learning for fun.
how can you implement a Scheme function has-list recursively, which tests whether a list contains other list as an element. For example (has-list '(1 2 3)) should return false, and (has-list '(1 2 (3 4) 5)) should return true.
If your implementation has something like ormap, then:
(define (has-list? l) (ormap list? l))
Using or as in Dan D.'s answer will not work.
A list has a list as an element iff it is not the empty list and either its first element is a list or the rest of the list has a list as an element. The translation to Scheme code is left as an exercise for the reader.
If you need to do it recursively and without using map:
(define (has-list? lst)
(cond
((null? lst) #f)
((list? (car lst)) #t)
(else (has-list? (cdr lst)))))
(define (has-list? X) (apply or (map list? X)))