(define test (lambda args
(if (= (length args) 1) (display (car args))
(begin (display (car args))
(test (cdr args))))))
I was looking for it on the net and didnt find the answer, I was able to get a variable number of arguments to my func, but how do i pass them not as a single list to the next iteration?
To be more clearer, if i call :
(test (list 1 1) (list 2 2) (list 3 3))
i was exepcting to get :
(1 1) (2 2) (3 3)
but i get :
(1 1) ((2 2) (3 3))
Thanks in advance!
args will be a list of the arguments passed to test. The first time you pass it three lists, so args will be a list of those three lists. Recursively you pass it (cdr args), which is a list of the last two lists, so now args is a list containing the list that has the last two lists. That is, args is (((2 2) (3 3))) where you want ((2 2) (3 3)). You can fix it by applying the test function to the list:
(apply test (cdr args))
Which, if (cdr args) is ((2 2) (3 3)), is the same as doing:
(test (2 2) (3 3))
(define (test . args)
(if (= (length args) 1)
(display (car args))
(begin
(display (car args))
(apply test (cdr args)))))
Related
I need to iterate through a list with sublists in Racket using list iteration and filtering, one of the lists is a nested list, I tried using "list?" and "car" to iterate inside but of course that would only apply to the first value of the sublist.
Is there a way to iterate through the whole nested list using list iteration and filtering?
(define (count-evens lst)
(length
(filter
(lambda (x)
(cond
[(and (list? x)
(and (number? (car x))
(eq? (modulo (car x) 2) 0)))
#t]
[(and (number? x)
(eq? (modulo x 2) 0))
#t]
[else
#f]))
lst)))
(count-evens '(1 2 5 4 (8 4 (b (10 3 3))) 3))
=> 3
Should return => 5
I would use a recursive function to do this but the assignment doesn't allow it.
"...assignment doesn't allow [recursive functions]"
Not sure what is allowed for this assignment, but
in ye olden days we processed recursive data structures with stacks...
(define (count-evens lst)
(define (lst-at stack) ;; (car stack) = index in deepest sub-list
;; produce list cursor within lst indexed by stack
(do ([stack (reverse stack) (cdr stack)]
[cursor (list lst) (list-tail (car cursor) (car stack))])
((null? stack) cursor)))
(do ([stack (list 0)
(cond
[(null? (lst-at stack))
(cdr stack)] ;; pop stack
[(pair? (car (lst-at stack)))
(cons 0 stack)] ;; push stack
[else ;; step through current (sub)list
(cons (+ 1 (car stack)) (cdr stack))])]
[count 0
(let ([item (car (lst-at stack))])
(if (and (number? item) (even? item)) (+ 1 count) count))])
((null? (lst-at stack)) count)))
> (count-evens '(1 2 5 4 (8 4 (b (10 3 3))) 3)) ;=>
5
Following SICP's instruction, I rewrite its intersection-set as:
(defun intersection-set (set1 set2)
(cond ((or (null set1) (null set2)) '())
((element-of-setp (car set1) set2)
(cons (car set1)
(intersection-set (cdr set1) set2)))
(t (intersection-set (cdr set1) set2))))
(defun element-of-setp(x set)
(cond ((null set) false)
((equal x (car set)) t)
(t (element-of-setp x (cdr set)))))
(intersection-set (list 1 2) (list 2 3 4))
Running it reports the following error:
element-of-setp: Symbol’s value as variable is void: false
However, element-of-setp on its own seems to work properly:
#+begin_src emacs-lisp :tangle yes
(defun element-of-setp(x set)
(cond ((null set) false)
((equal x (car set)) t)
(t (element-of-setp x (cdr set)))))
(element-of-setp 1 (list 1 2 3))
#+end_src
#+RESULTS:
: t
What's the problem?
However, element-of-setp on its own seems to work properly:
Unfortunately, the test you used did not cover all the possible cases.
If you try instead:
(element-of-setp 5 (list 1 2 3))
Then the function is going to reach the case where the list is empty, and in that it will evaluate false, which is most likely undefined; as stated in the comment, boolean values in Emacs-Lisp are represented by nil and non-nil values (atoms).
I'm a newbie to scheme programming and I was writing small codes when I encountered the following issue and couldn't reason about it satisfactorily.
(define (at_i lst i)
(if (eq? i 0)
(car lst)
(at_i (cdr lst)
(- i 1) )))
Evaluation of (at_i '(1 2 3 4) 0) returns 1.
Now lets define same procedure with a lambda syntax.
(define (at_i lst i)
(lambda (vec x)
(if (eq? x 0)
(car vec)
(at_i (cdr vec)
(- x 1) )))
lst i)
But now Evaluation of (at_i '(1 2 3 4) 0) returns 0, which is not in the list and in general, it returns element at index-1.
I don't understand why this is happening.
Note: I just realized its not returning element at index - 1 but the index itself. The reason for this has been well explained below by #Renzo. Thanks!
First, you should indent properly the code if you intend to learn the language, since code indentation is very important to understand programs in Scheme and Lisp-like languages.
For instance, your function correctly indented is:
(define (at_i lst i)
(lambda (vec x)
(if (eq? x 0)
(car vec)
(at_i (cdr vec) (- x 1))))
lst
i)
From this you can see that you are defining the function at_i exactly as before in terms of a function with two parameters (lst and i), and whose body is constitued by three expressions: the first lambda (vec x) ... (- x 1)))), which is an (anonymous) function (lambda) which is not called or applied, the second, which is the first parameter lst, and finally the third which is the second parameter i. So, when the function at_i is called with two arguments, the result is the evaluation of the three expressions in sequence, the first two values are discarded (the function and the value of lst), and the result is the value of the second parameter i. This is reason for which the result of (at_i '(1 2 3 4) 0) is 0, since it is the value of i.
A proper redefinition of the function in lambda form would be the following, for instance:
(define at_i
(lambda (vec x)
(if (eq? x 0)
(car vec)
(at_i (cdr vec) (- x 1)))))
(at_i '(1 2 3 4) 0) ;; => 1
in which you can see that the name at_i, through the define, is associated to a two parameter function which calculates correctly the result.
eq? is memory object equality. Only some Scheme implementations interpret (eq? 5 5) as #t. Use = for numbers, eqv? for values, and equal? for collections.
(define (index i xs) ; `index` is a partial function,
(if (= i 0) ; `i` may go out of range
(car xs)
(index (- i 1) ; Tail recursion
(cdr xs) )))
Your second function returns the index because you missed parenthesis around the lambda's application. It should be
(define (index i xs)
((lambda (i' xs')
(if (= i' 0)
(car xs')
(index (- i' 1) ; Not tail-recursive
(cdr xs') )))
i xs))
But this is verbose and differs semantically from the first formulation.
You say you are defining the "same procedure with a lambda syntax", but you are not. That would be (define at_i (lambda lst i) ...). Instead, you are effectively saying (define (at_i lst i) 1 2 3), and that is 3, of course.
In your particular case, you defined the procedure at_i to return (lambda (vec x) ...), lst and i. Now, if you call (at_i '(1 2 3 4) 0), the procedure will return 0, since that is the value of i at this point.
I've got some function func and want to apply it on a list lst, so I used map but I need to have the first and last element of the list evaluated with some other function func2.
So basically I want this:
(map (lambda (x)
(cond [(isBeginningOfList? lst) (func2 x)]
[(isEndOfList? lst) (func2 x)]
[else (func x)]))
lst)
Obviously this doesn't work.
How can I achieve this functionality?
Can I somehow get a key of each list entry? Like lambda(key,val) and then compare (equal? key 0) / (equal? key (length lst))?
There's for/list with in-indexed and that does what you describe:
(define (f lst f1 f2)
(define last (sub1 (length lst)))
(for/list (((e i) (in-indexed lst)))
(if (< 0 i last)
(f1 e)
(f2 e))))
then
> (f '(1 2 3 4 5) sub1 add1)
'(2 1 2 3 6)
You can use a map on all the elements except the first and the last one and treat those two separately. In this way you avoid those comparisons which you would do for every element.
(define special-map
(λ (lst f1 f2)
(append (list (f1 (car lst)))
(map f2 (drop-right (cdr lst) 1))
(list (f1 (last lst))))))
Example
Let's try to increment the first and the last elements and decrement all the others.
> (special-map '(1 2 3 4 5) add1 sub1)
'(2 1 2 3 6)
Later edit
I changed (take (cdr lst) (- (length lst) 2)) with (drop-right (cdr lst) 1).
i am new to racket. i am trying create a list from the input of the user and when the value 0 is entred the first three elements are printed.
here is the code:
#lang racket
(define lst '())
(define (add)
(define n(read))
(if (= n 0)
;then
(
list (car lst) (cadr lst) (caddr lst)
)
;else
(
(set! lst (append lst (list n)))
(add)
)
)
)
(add)
i tested the program with the values 1 2 3 4 5 0
but i keep getting this error:
application: not a procedure;
expected a procedure that can be applied to arguments
given: #<void>
arguments...:
'(1 2 3)
can anyone help me figure out what's wrong.
If you have more than one expression in the "then" or "else" parts, you must enclose them inside a begin, because a pair of () in Scheme are used for function application - that explains the error you're getting. Try this:
(define (add)
(define n (read))
(if (= n 0)
; then
(list (car lst) (cadr lst) (caddr lst))
; else
(begin
(set! lst (append lst (list n)))
(add))))
I had a similar problem, in a function i called a parameter with the same name of a structure, so, trying to create an instance of that structure i got the same error.
example:
> (struct example (param1 param2) #:transparent)
> (define e (example 1 2))
> e
(example 1 2)
> (define (fn e)
(example (example-param1 e) 0))
> (fn e)
(example 1 0)
> (define (fn example)
(example (example-param1 example) 0))
> (fn e)
application: not a procedure;
expected a procedure that can be applied to arguments
given: (example 1 2)
arguments...:
I hope this helps
Your code have a few problems, for example it will fail if you enter less than 3 elements. Also, it is not considered good style to define variables at the module level.
I'd suggest the following:
(define (add)
(define (sub cnt lst)
(define n (read))
(if (= n 0)
(reverse lst)
(if (< cnt 3)
(sub (add1 cnt) (cons n lst))
(sub cnt lst))))
(sub 0 '()))