How to compare integers to array values in LISP [duplicate] - syntax-error

I just started learning Common Lisp a few days ago, and I'm trying to build a function that inserts a number into a tree. I'm getting an error,
*** - SYSTEM::%EXPAND-FORM: (CONS NIL LST) should be a lambda expression
From googling around, it seems like this happens when you have too many sets of parenthesis, but after looking at this for an hour or so and changing things around, I can't figure out where I could be doing this.
This is the code where it's happening:
(defun insert (lst probe)
(cond ((null lst) (cons probe lst))
((equal (length lst) 1)
(if (<= probe (first lst))
(cons probe lst)
(append lst (list probe))))
((equal (length lst) 2)
((cons nil lst) (append lst nil) (insertat nil lst 3)
(cond ((<= probe (second lst)) (insert (first lst) probe))
((> probe (fourth lst)) (insert (fifth lst) probe))
(t (insert (third lst) probe)))))))
I'm pretty sure it's occurring after the ((equal (length lst) 2), where the idea is to insert an empty list into the existing list, then append an empty list onto the end, then insert an empty list into the middle.

Correct! The problem is in the line right after that, where it says
((cons nil lst) (append lst nil) (insertat nil lst 3) ...
The issue is the two opening parentheses. Parentheses can change meaning in special contexts (like the cond form you're using), but in this context, the parentheses signify regular function application, just like you're probably used to. That means the first thing after the parentheses must be a function. From the perspective of the outer parentheses, the first thing is (cons nil lst), so that must be a function (which it's not).
Note that you can't just remove the parentheses, because the cons function returns a new list like you want but doesn't change the old list. You probably want something like this:
(setq lst (cons nil lst))
(setq lst (append lst nil))
(setq lst (insertat nil lst 3))
...

If you indent the function correctly, then you can see that there is an extra parenthesis in front of CONS NIL LST.
(defun insert (lst probe)
(cond ((null lst) (cons probe lst))
((equal (length lst) 1)
(if (<= probe (first lst))
(cons probe lst)
(append lst (list probe))))
((equal (length lst) 2)
((cons nil lst) (append lst nil) (insertat nil lst 3)
(cond ((<= probe (second lst)) (insert (first lst) probe))
((> probe (fourth lst)) (insert (fifth lst) probe))
(t (insert (third lst) probe)))))))
In most Lisp IDEs you can indent expressions. In LispWorks, select the whole expression and do m-x Indent Region.

To fix the immediate error, you can just add a PROGN there before (CONS NIL ...).
PROGN works by evaluating each form in it and return the value of the last form in it as its value.
However, your program still won't do what you think it'll do (I guess so). You know, in Common Lisp you use the first cons object to represent the whole non-empty list, and you can't simply replace the head cons. The better way is to return the new list as the value of the function.
(defun insert (lst probe)
(ecase (length lst)
(0 (list probe))
(1 (let ((c (first lst)))
(if (<= probe c)
(list probe c)
(list c probe))))
(2 (cond
((<= probe (first lst))
(list probe (first lst) nil (second lst) nil))
((> probe (second lst))
(list nil (first lst) nil (second lst) probe))
(t
(list nil (first lst) probe (second lst) nil))))))
Maybe you want to (setf lst (insert lst [some-number])) when you use this function.

You are right; at the line marked with "error is here", there is a syntax error:
(defun insert (lst probe)
(cond ((null lst) (cons probe lst))
((equal (length lst) 1)
(if (<= probe (first lst))
(cons probe lst)
(append lst (list probe))))
((equal (length lst) 2)
(#|Error is here|# (cons nil lst) (append lst nil) (insertat nil lst 3)
(cond ((<= probe (second lst)) (insert (first lst) probe))
((> probe (fourth lst)) (insert (fifth lst) probe))
(t (insert (third lst) probe)))))))
To the compiler/interpreter, the form reads as a function call to the "function" (cons nil list) which is not a function at all. The compiler complains here about the use of a compound form in the "operator" position, which is not a lambda (the only kind of compound form accepted in that position.)
((cons nil lst) #| <-- Form in operator position |#
(append lst nil) #| <-- First argument form |#
(insertat nil lst 3) #| <-- Second argument form |#
(cond ((<= probe (second lst)) (insert (first lst) probe)) #| Third argument |#
((> probe (fourth lst)) (insert (fifth lst) probe))
(t (insert (third lst) probe))))
I'd help with re-formulating the expression, but I am not sure what you want to accomplish here.

Related

Iterating through a nested list using filter or fold Racket

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

Symbol’s value as variable is void: false when run element-of-setp

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

Racket: Map with keys/iterating?

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

application: not a procedure racket

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

Common lisp error: "should be lambda expression"

I just started learning Common Lisp a few days ago, and I'm trying to build a function that inserts a number into a tree. I'm getting an error,
*** - SYSTEM::%EXPAND-FORM: (CONS NIL LST) should be a lambda expression
From googling around, it seems like this happens when you have too many sets of parenthesis, but after looking at this for an hour or so and changing things around, I can't figure out where I could be doing this.
This is the code where it's happening:
(defun insert (lst probe)
(cond ((null lst) (cons probe lst))
((equal (length lst) 1)
(if (<= probe (first lst))
(cons probe lst)
(append lst (list probe))))
((equal (length lst) 2)
((cons nil lst) (append lst nil) (insertat nil lst 3)
(cond ((<= probe (second lst)) (insert (first lst) probe))
((> probe (fourth lst)) (insert (fifth lst) probe))
(t (insert (third lst) probe)))))))
I'm pretty sure it's occurring after the ((equal (length lst) 2), where the idea is to insert an empty list into the existing list, then append an empty list onto the end, then insert an empty list into the middle.
Correct! The problem is in the line right after that, where it says
((cons nil lst) (append lst nil) (insertat nil lst 3) ...
The issue is the two opening parentheses. Parentheses can change meaning in special contexts (like the cond form you're using), but in this context, the parentheses signify regular function application, just like you're probably used to. That means the first thing after the parentheses must be a function. From the perspective of the outer parentheses, the first thing is (cons nil lst), so that must be a function (which it's not).
Note that you can't just remove the parentheses, because the cons function returns a new list like you want but doesn't change the old list. You probably want something like this:
(setq lst (cons nil lst))
(setq lst (append lst nil))
(setq lst (insertat nil lst 3))
...
If you indent the function correctly, then you can see that there is an extra parenthesis in front of CONS NIL LST.
(defun insert (lst probe)
(cond ((null lst) (cons probe lst))
((equal (length lst) 1)
(if (<= probe (first lst))
(cons probe lst)
(append lst (list probe))))
((equal (length lst) 2)
((cons nil lst) (append lst nil) (insertat nil lst 3)
(cond ((<= probe (second lst)) (insert (first lst) probe))
((> probe (fourth lst)) (insert (fifth lst) probe))
(t (insert (third lst) probe)))))))
In most Lisp IDEs you can indent expressions. In LispWorks, select the whole expression and do m-x Indent Region.
To fix the immediate error, you can just add a PROGN there before (CONS NIL ...).
PROGN works by evaluating each form in it and return the value of the last form in it as its value.
However, your program still won't do what you think it'll do (I guess so). You know, in Common Lisp you use the first cons object to represent the whole non-empty list, and you can't simply replace the head cons. The better way is to return the new list as the value of the function.
(defun insert (lst probe)
(ecase (length lst)
(0 (list probe))
(1 (let ((c (first lst)))
(if (<= probe c)
(list probe c)
(list c probe))))
(2 (cond
((<= probe (first lst))
(list probe (first lst) nil (second lst) nil))
((> probe (second lst))
(list nil (first lst) nil (second lst) probe))
(t
(list nil (first lst) probe (second lst) nil))))))
Maybe you want to (setf lst (insert lst [some-number])) when you use this function.
You are right; at the line marked with "error is here", there is a syntax error:
(defun insert (lst probe)
(cond ((null lst) (cons probe lst))
((equal (length lst) 1)
(if (<= probe (first lst))
(cons probe lst)
(append lst (list probe))))
((equal (length lst) 2)
(#|Error is here|# (cons nil lst) (append lst nil) (insertat nil lst 3)
(cond ((<= probe (second lst)) (insert (first lst) probe))
((> probe (fourth lst)) (insert (fifth lst) probe))
(t (insert (third lst) probe)))))))
To the compiler/interpreter, the form reads as a function call to the "function" (cons nil list) which is not a function at all. The compiler complains here about the use of a compound form in the "operator" position, which is not a lambda (the only kind of compound form accepted in that position.)
((cons nil lst) #| <-- Form in operator position |#
(append lst nil) #| <-- First argument form |#
(insertat nil lst 3) #| <-- Second argument form |#
(cond ((<= probe (second lst)) (insert (first lst) probe)) #| Third argument |#
((> probe (fourth lst)) (insert (fifth lst) probe))
(t (insert (third lst) probe))))
I'd help with re-formulating the expression, but I am not sure what you want to accomplish here.