How to Apply Cond?

How to Apply Cond?

CodeDing
Advisor Advisor
1,215 Views
21 Replies
Message 1 of 22

How to Apply Cond?

CodeDing
Advisor
Advisor

Can someone explain to me why this works:

(cond (nil) (1) ("a"))

 

But this does not work (nor simple variations using 'quote):

(apply 'cond (mapcar 'list '(nil "1" "a")))

 

I'm sure it has something to do with symbols & evaluations, etc. But I can't quite grasp it.

Is there a way that I can apply the COND function to an unknown list size?

 

Best,

0 Likes
1,216 Views
21 Replies
Replies (21)
Message 2 of 22

paullimapa
Mentor
Mentor

when you do this:

(mapcar 'list '("1" "a"))

you'll end up with this:

(("1") ("a"))

to compare apples to apples what you really want is this:

(apply 'cond '(nil 1 "a"))

now you'll get the same result which is: nil

 

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 3 of 22

CodeDing
Advisor
Advisor

I don't understand your explanation.

 

When we run:

(apply 'cond '(nil 1 "a"))

...we get nil. Which is not what is returned when we run:

(cond (nil) (1) ("a"))

We instead get 1 returned.

 

My hopeful result when trying to use apply to cond is to have 1 returned.

Is that possible?

0 Likes
Message 4 of 22

paullimapa
Mentor
Mentor

problem has to do with how the cond statement is structured in the first place. You should follow this format:

https://help.autodesk.com/view/ACDLT/2024/ENU/?guid=GUID-7BA45202-D95F-4F2D-8D83-965024826074

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 5 of 22

CodeDing
Advisor
Advisor

Just for full transparency, I understand I could take DIFFERENT approaches to receive the desired similar result.

Something like:

(setq myList '(nil 1 "a"))
(car (vl-remove nil myList))

 

I was just exploring this (apply 'cond ...) concept in lisp and want to understand:

1) if it's possible

2) if not, why?

0 Likes
Message 6 of 22

paullimapa
Mentor
Mentor

did you look at the link I provided to understand how the cond function is supposed to be structured?


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 7 of 22

CodeDing
Advisor
Advisor

Yes, I understand how cond is built.

 

I got something to work though:

 

(eval (cons 'cond (mapcar 'list '(nil 1 "a"))))

 

 

That returns 1 like expected.

 

But still doesn't help me understand why (apply 'cond ...) will not work

 

0 Likes
Message 8 of 22

paullimapa
Mentor
Mentor

you've could have gotten the same result by doing even this:

(car(list(cond (nil) (1) ("a"))))

Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 9 of 22

CodeDing
Advisor
Advisor

...that's just (cond ...) with more steps?

😅

The concept I'm trying to understand is how to take a list of unknown length and apply Cond to it.

Why can I take an unknown list of any length and any data types, such as:

(nil (1.0 2.0 3.0) nil "a" 0 <Entity name: 2adfb477d70> nil)

or even

(nil <Entity name: 2adfb477d70> "ABC" nil (1.0 2.0 3.0) "a" nil <Selection set: 5da>)

or even

(0 1 2 3 4 5 6)

or even

(nil nil nil nil nil nil 0)

or even

(<Selection set: 5da> <Selection set: 5db> nil <Selection set: 5dc>)

 

...and how come I can do this:

 

(eval (cons 'cond (mapcar 'list myList)))

 

...but not this:

 

(apply 'cond (mapcar 'list myList))

 

0 Likes
Message 10 of 22

paullimapa
Mentor
Mentor

That has again to do with the structure of the cond function.

It's suppose to be passed an evaluation function for each item.

As long as the item fails, it'll move on to the next.

But also with the cond function it'll automatically default to the next as the answer when it's not given the structure it's looking for.

So since your first item is (nil) that's not true and the next item of (1) is also not in the structure it's looking for it'll automatically return that as the result without moving on to the next.

So to properly pass a set of items to the cond function you'll have to provide each item with an evaluation function and not just the item by itself.


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 11 of 22

komondormrex
Mentor
Mentor

@CodeDing wrote:

But this does not work (nor simple variations using 'quote):

 

 

(apply 'cond (mapcar 'list '(nil "1" "a")))

 

 

 

cond operates on list [multiple lists].

(mapcar 'list '(nil "1" "a")) will give a ONE list with three sublists ((nil) ("1") ("a")) which cond start to process starting with (nil) sublist. as there  a nil in first place in the sublist interpreter will think it is a function and gives you the error because it's not. that is why you never can feed cond with multiple lists using mapcar only. eval is very good to use in that approach.

0 Likes
Message 12 of 22

Sea-Haven
Mentor
Mentor

Are you trying to replace this 

 

(cond
((= 1 ans)(do1))
((= 2 ans)(do2))
((= 3 ans)(do3))
((= 4 ans)(do4))
...............
)

 

With cond of (1 do1)(2 do2)(3 do3)..........

0 Likes
Message 13 of 22

CodeDing
Advisor
Advisor

That has again to do with the structure of the cond function.

It's suppose to be passed an evaluation function for each item.


If it's supposed to be passed an "evaluation function" for each item, then can you explain how this works:

(cond (nil) (1) ("a"))

^^^ this layout is not passing "evaluation functions" yet still returns 1 correctly

 


But also with the cond function it'll automatically default to the next as the answer when it's not given the structure it's looking for.


You keep mentioning that the structure is wrong, which I assume you mean I should be passing items in a ((test) (result)) format... but according to the documentation, if not result is passed then the evaluation of the test is returned instead:

"If there is only one expression in the sublist (that is, if result is missing), the value of the test expression is returned."

 


@paullimapa wrote:

So to properly pass a set of items to the cond function you'll have to provide each item with an evaluation function and not just the item by itself.


^^^ according to the documentation, this does not appear to be correct.

0 Likes
Message 14 of 22

paullimapa
Mentor
Mentor

what documentation are you referring to that's telling you this?


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 15 of 22

CodeDing
Advisor
Advisor

cond operates on list [multiple lists].

(mapcar 'list '(nil "1" "a")) will give a ONE list with three sublists ((nil) ("1") ("a")) which cond start to process starting with (nil) sublist. as there  a nil in first place in the sublist interpreter will think it is a function and gives you the error because it's not. that is why you never can feed cond with multiple lists using mapcar only. eval is very good to use in that approach.


Your explanation seems to help a bit, so can you help explain why this function returns "T"?

(apply 'cond '(t 1 "a"))

And why this function returns "nil"?

(apply 'cond '(nil 1 "a"))
0 Likes
Message 16 of 22

CodeDing
Advisor
Advisor
0 Likes
Message 17 of 22

CodeDing
Advisor
Advisor

No, your data is referring to a structured format. I'll refer you to review my response in message 9.

0 Likes
Message 18 of 22

CodeDing
Advisor
Advisor

Been trying to review this posting for some further understanding. I know it's not Autolisp, but should be same principle.

http://www.reduce-algebra.com/lisp-docs/allman1se29.html 

0 Likes
Message 19 of 22

paullimapa
Mentor
Mentor

"If there is only one expression in the sublist (that is, if result is missing), the value of the test expression is returned."

So the way I read this statement is that if you only have one test situation in your sublist then it'll return the test result of the only one expression.

For example if your cond statement looks like this:

 

(cond (a))

 

And since a does not exists the test result of nil is returned.

When you add a 2nd item to the sublist:

 

(cond (a) (1))

 

Then when the test evaluation of the first item fails the test evaluation of the next item in the sublist is returned in this case it's the number 1 which has the value of 1.

Now if you set a to something like this:

 

(setq a "abc")

 

The cond statement this time returns the successful evaluation result of the first item of "abc".

Using the apply function with cond operates the same when written like this:

 

(apply 'cond '(a))

 

But I think the way the code is written for the apply function with cond only evaluates the first element. So when the first element in this case b fails then it just stops and returns nil.

 

(apply 'cond '(b a))

 

correction:

If you want to use the cond Instead of using cond function just use eval unction on an unknown length list of items I'm more comfortable with using forever function like this:

 

; setup sample 
; variables with value = a & b
; varibles with nil = c & d
; list of a b c d = curlst
; list with nil = newlst
(setq a "abc" b "def" c nil d nil curlst (list a b c d) newlst nil)
; use foreach to loop through each item in the list and run cond function 
(foreach itm curlst (setq newlst (append newlst (list (eval itm)))))
; returns newlst which gives you evaluation results on each item:

 

For curlst: (list a b c d)

Returns newlst: ("abc" "def" nil nil)

Now you can examine the list results & compare to the original list 

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 20 of 22

komondormrex
Mentor
Mentor

@CodeDing wrote:

so can you help explain why this function returns "T"?

 

(apply 'cond '(t 1 "a"))

 

And why this function returns "nil"?

 

(apply 'cond '(nil 1 "a"))

 


unsure thing. that depend on how apply will operate with cond. seems that these expressions return the value of list first member, no matter what it is. t, nil, variable, constant except of it is list. and results of those expressions i can't obtain with direct use of cond.

thus (cond (t 1 "a")) gives "a" and (cond (nil 1 "a")) gives nil.

0 Likes