explain subfunction

explain subfunction

thsa2501
Enthusiast Enthusiast
1,074 Views
11 Replies
Message 1 of 12

explain subfunction

thsa2501
Enthusiast
Enthusiast

hi everyone,

kindly explain this subfunction(i got it from leemac website). I understand this subfunction is removing duplicate items, but I don't know how it's working. what does working which I red marked? it too confusing for me. why he put it into this "LM:Unique" inside function.

(defun LM:Unique ( l ) (if l (cons (car l) (LM:Unique (vl-remove (car l) (cdr l)) ) ) ) )

0 Likes
Accepted solutions (1)
1,075 Views
11 Replies
Replies (11)
Message 2 of 12

hak_vz
Advisor
Advisor
Accepted solution

This is recursive function, a function that calls itself and his technique is known as recursion.

LM:UNIQUE  repeats in the way that it creates new list consisting of  first element in a list (car l) combined with the  result of function vl-remove running over rest of the list (cdr l). It runs as long function parameter returned is a list.

 

Here you have another way to create unique list

(defun unique (lst)(if (and (and lst)(listp lst))(vl-remove-if '(lambda (x)(member x (setq lst (cdr lst)))) lst)))
Command: (unique '(1 2 3 3 3 4))
(1 2 3 4)
Command: (unique '(1 (2 3) (2 3) 3 3 4))
(1 (2 3) 3 4)

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 3 of 12

john.uhden
Mentor
Mentor

@hak_vz 

I like it, but I'm missing something...

Why did you use member instead of vl-position?

It's not as though you were avoiding vl* functions.

John F. Uhden

0 Likes
Message 4 of 12

hak_vz
Advisor
Advisor

@john.uhden 

There was no particular reason for using function member, so vl-position can be used instead.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 5 of 12

Kent1Cooper
Consultant
Consultant

@john.uhden wrote:

.... Why did you use member instead of vl-position? ....


When you want to know whether an item is a member of a list, (member) is the obvious function.  (vl-position) may be faster as you have pointed out before, but the difference would be meaningless unless you have a large number of such lists to uniquify all at once.  Neither returns anything directly usable for the task at hand except in that both returns are not nil if the item is in the list -- either way of getting that will do the job.

 

What I wonder about is this part:

... (if (and (and lst) (listp lst)) ...

Why  (and lst) ?  Wouldn't this serve the purpose?

... (if (and lst (listp lst)) ...

[It's curious that you can't just do:

... (if (listp lst) ...

but that's not sufficient to know that 'lst' exists, because for whatever reason, (listp nil) returns  T.]

Kent Cooper, AIA
Message 6 of 12

ВeekeeCZ
Consultant
Consultant

@Kent1Cooper wrote:

... (if (listp lst) ...

but that's not sufficient to know that 'lst' exists, because for whatever reason, (listp nil) returns  T.]


 

...so what you can do is ... (if (vl-consp lst) ...

0 Likes
Message 7 of 12

john.uhden
Mentor
Mentor
I think his fingers were stuttering.
Yes, nil is also a list of zero items.
What boggles my mind is the purpose of dotted pairs.
Yes, they are technically a list, but you can't always treat them as you
would a conventional list.

Command: (listp '(1 . 4))
T

Command: (setq a '(0 . "LINE"))
(0 . "LINE")

Command: (listp a) T

Command: (length a) ; error: bad list: "LINE"

Command: (nth 0 a) 0

Command: (mapcar 'print a)
0 ; error: bad list: "LINE"

Command: (apply '+ a) ; error: bad argument list tail: "LINE"

Command: (setq b '(1 . 2))
(1 . 2)

Command: (apply '+ b) ; error: bad argument list tail: 2

Command: (foreach x a (print x))

0 ; error: bad argument type: consp "LINE"

Command: (apply 'max b) ; error: bad argument list tail: 2

John F. Uhden

0 Likes
Message 8 of 12

john.uhden
Mentor
Mentor
But vl-consp doesn't differentiate a list from a dotted pair...
Command: (vl-consp '(1 . 3))
T

Command: (vl-consp '(1 2 3))
T

But this will...
Command: (vl-list-length '(1 . 3))
nil

Command: (vl-list-length '(1 2 3))
3

John F. Uhden

0 Likes
Message 9 of 12

Kent1Cooper
Consultant
Consultant

@john.uhden wrote:
....
But this will...
Command: (vl-list-length '(1 . 3))
nil
Command: (vl-list-length '(1 2 3))
3

But getting back to the task at hand, that won't suffice by itself to know that 'lst' exists as well as being a list, because non-existence is still a list with no items in it, similar to the result from (listp):

 

Command: (vl-list-length nil)
0

 

not T as (listp) returns, but not nil, either (vl-consp) at least makes that determination in one function, even if it can't tell a list from a dotted pair.

Kent Cooper, AIA
0 Likes
Message 10 of 12

john.uhden
Mentor
Mentor
There's always the (atom ...) function which requires a quoted symbol.
(and (atom (quote lst))(listp lst)) ; maybe?
Or just (= (type lst) 'LIST) ;; Not good enough
Therefor:
(defun really_a_list (lst)
(and (= (type lst) 'LIST)(vl-list-length lst))
)
Command: (really_a_list '()) nil
Command: (really_a_list 2) nil
Command: (really_a_list '(62 . 5)) nil
Command: (really_a_list '(2 3)) T

John F. Uhden

0 Likes
Message 11 of 12

thsa2501
Enthusiast
Enthusiast

hi @hak_vz 

thank you so much for your reply. I completely understand now.

0 Likes
Message 12 of 12

hak_vz
Advisor
Advisor
... (if (and (and lst) (listp lst)) ...

This is just the way of writing test I picked up in 35 years of programming

If we are sure that function parameter is a list then testing is not needed.

In lisp we can write

(if l)

One of my professors at informatics faculty has stated "for easier code readability don't leave lone parameter, but try to show what you ask". So instead I sometime write (if (and l)).

 

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes