vl-sort help

vl-sort help

zph
Collaborator Collaborator
5,678 Views
58 Replies
Message 1 of 59

vl-sort help

zph
Collaborator
Collaborator

Good day!

 

Below is an excerpt of code:

 

(princ "\n qList1: ")(princ qList)
(setq qList (vl-sort qList (function (lambda (x y) (< (car x) (car y))))))
(princ "\n qList2: ")(princ qList)

 

 

And below is the what is returned:

 

 qList1: ((NEW-TEST-VAL-D . 0) (NEW-TEST-VAL-D . 0) (NEW-TEST-VAL-C . 0) (NEW-TEST-VAL-B . 0) (NEW-TEST-VAL-A . 0))
 qList2: ((NEW-TEST-VAL-A . 0) (NEW-TEST-VAL-B . 0) (NEW-TEST-VAL-C . 0) (NEW-TEST-VAL-D . 0) (NEW-TEST-VAL-D . 0))

 

 

Why doesn't this instance of vl-sort remove the duplicate dotted pair (highlighted red)?  What am I missing?

 

Thanks!

~Z

0 Likes
Accepted solutions (1)
5,679 Views
58 Replies
Replies (58)
Message 41 of 59

zph
Collaborator
Collaborator

ActivistInvestor,

 

Your response answers my question fully.  Thank you.

 

It seems the general consensus is the built in VL-SORT function is incomplete in its implementation and poorly defines what it does and how it accomplishes it (probably in great part to its incomplete implementation).

 

Thank you all for the detailed replies.  I have a much greater understanding of this topic.

 

Cheers!

~Z

0 Likes
Message 42 of 59

_gile
Consultant
Consultant

Implementations of two famous sorting algorithms

 

Insert sort, not the faster but quite simple:

 

(defun insertsort (fun lst / insert)
 
  (defun insert	(ele lst)
    (cond
      ((null lst) (list ele))
      ((apply fun (list  ele (car lst))) (cons ele lst))
      ((cons (car lst) (insert ele (cdr lst))))
    )
  )

  (if lst
    (insert (car lst) (insertsort fun (cdr lst)))
  )
)

 

 

More efficient, merge sort:

 

(defun mergesort (fun lst / merge aggregate)

  (defun merge (fun l1 l2)
    (cond
      ((and l1 l2)
       (if (fun (car l1) (car l2))
	 (cons (car l1) (merge fun (cdr l1) l2))
	 (cons (car l2) (merge fun l1 (cdr l2)))
       )
      )
      (l1)
      (l2)
    )
  )

  (defun aggregate (fun lst acc)
    (cond
      ((cdr lst)
       (aggregate fun
		  (cddr lst)
		  (cons (merge fun (car lst) (cadr lst)) acc)
       )
      )
      ((car lst)
       (aggregate fun
		  nil
		  (cons (merge fun (car lst) (car acc)) (cdr acc))
       )
      )
      ((cdr acc)
       (aggregate fun acc nil)
      )
      (T (car acc))
    )
  )

  (aggregate (eval fun) (mapcar 'list lst) nil)
)

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 43 of 59

ActivistInvestor
Mentor
Mentor

 

I asked a simple question, which was what if the function passed into your (sort) function uses the LIST function?

 

And you say, it is okay as long as I don't try to use the list function within the function' 

 

As long as you don't try to use the list function within what function?  The (sort) function, or the function that's passed into the (sort) function's first argument?

 

 

Command: (defun sort (fun list) (mapcar (function (lambda (n)(nth n list))) (vl-sort-i list fun)))
SORT

Command: (setq some-list '(10 4 8 16 2 11 6))
(10 4 8 16 2 11 6)

Command: (sort '(lambda (a b) (apply '> (list a b))) some-list)
; error: bad function: (10 4 8 16 2 11 6)

 

 


@john.uhden wrote:

@ActivistInvestor wrote, "What if the function argument (or any function it calls) uses the (list) function?"

 

You also quoted me... "The lurkers should note that I used list as an argument, which is okay as long as I don't try to use the list function within the function since arguments are treated as local."  But what do you care.  You seem to approve of errors.

 


 

0 Likes
Message 44 of 59

john.uhden
Mentor
Mentor

Why, within the sort function, of course.  You just demonstrated that.

 

For all I care, the input argument could be igzlpig, or might that some day become an AutoCAD function?

John F. Uhden

0 Likes
Message 45 of 59

ActivistInvestor
Mentor
Mentor

What I show is not the list function being used within the sort function.

 

What I show is the list function being used in the function that's passed to the sort function.

 

Since you seem to be misinterpreting what 'within' means, let's try it another way:

 

 

Command: (setq some-list '(10 4 8 16 2 11 6))
(10 4 8 16 2 11 6)

Command: (defun my-comparer (a b) (apply '> (list a b)))
MY-COMPARER

Command: (defun sort (fun list) (mapcar (function (lambda (n)(nth n list))) 
(vl-sort-i list fun)))
SORT

Command: (sort 'my-comparer some-list)
Backtrace:
[0.80] (VL-BT)
[1.76] (*ERROR* "bad function: (10 4 8 16 2 11 6)")
[2.71] (_call-err-hook #<SUBR @00000000300edde0 *ERROR*> "bad function: (10 4 8 
16 2 11 6)")
[3.65] (sys-error "bad function: (10 4 8 16 2 11 6)")
:ERROR-BREAK.60 nil
[4.57] (ill-fun-hk 2 11)
[5.51] (LIST 2 11)
[6.45] (MY-COMPARER 2 11)
[7.39] (#<SUBR @000000002ded8980 nil> (4 . 2) (5 . 11))
[8.34] (sort-i (10 4 8 16 2 11 6) #<SUBR @000000002e03a1b0 MY-COMPARER> nil)
[9.27] (VL-SORT-I (10 4 8 16 2 11 6) MY-COMPARER)
[10.21] (SORT MY-COMPARER (10 4 8 16 2 11 6))
[11.15] (#<SUBR @00000000300113b8 -rts_top->)
[12.12] (#<SUBR @000000002ded8700 veval-str-body> "(sort 'my-comparer 
some-list)" T #<FILE internal>)
:CALLBACK-ENTRY.6 (:CALLBACK-ENTRY)
:ARQ-SUBR-CALLBACK.3 (nil 0)

@john.uhden wrote:

Why, within the sort function, of course.  You just demonstrated that.

 

For all I care, the input argument could be igzlpig, or might that some day become an AutoCAD function?


 

0 Likes
Message 46 of 59

john.uhden
Mentor
Mentor

I am not misinterpreting anything.

If a function FOO calls a function BAR and BAR calls the LIST function, then the LIST function falls within the FOO function,

 

I take it that there wouldn't be a problem naming the input argument IGZLPIG, that is unless I have created an IGZLPIG function that I want to use within the SORT function.  But hat's okay as it will probably just create an error.  Once again, it's up to the author.

John F. Uhden

0 Likes
Message 47 of 59

ActivistInvestor
Mentor
Mentor

@john.uhden wrote:

I am not misinterpreting anything.

If a function FOO calls a function BAR and BAR calls the LIST function, then the LIST function falls within the FOO function,

 

I take it that there wouldn't be a problem naming the input argument IGZLPIG, that is unless I have created an IGZLPIG function that I want to use within the SORT function.  But hat's okay as it will probably just create an error.  Once again, it's up to the author.


Any user-defined function should be able to rely on other user-defined functions not changing the definition of built-in, or reserved symbols.

 

As far as name collisions between user-defined functions verses built-in ones using reserved symbols, higher-order functions should ensure they use sufficiently-unique symbols for local variables, because the problem can occur regardless of whether a local symbol is LIST or IGZLPIG.

 

And it's not up to the author, it's up to all the authors whose use each other's functions without requiring them to have intimate knowledge of their implementation details.

0 Likes
Message 48 of 59

john.uhden
Mentor
Mentor

Well I don't think it's up to @dbroad if I use one of his functions.  It's up to me to learn what it does and how it works.  However it's not up to me if you use one.  In fact it's not up to me if you use one of mine.

John F. Uhden

0 Likes
Message 49 of 59

ActivistInvestor
Mentor
Mentor

@john.uhden wrote:

Well I don't think it's up to @dbroad if I use one of his functions.  It's up to me to learn what it does and how it works.  However it's not up to me if you use one.  In fact it's not up to me if you use one of mine.


I see, so what you're trying to suggest is that you are not at fault if your (sort) function fails because the programmer that used it, passed a function that at some point, calls the LIST function. That's entirely the fault of the programmer that used your (sort) function, right?

 

 

0 Likes
Message 50 of 59

john.uhden
Mentor
Mentor
Well then, I guess that none of us should contribute anything. Might as
well shut this place down.

John F. Uhden

0 Likes
Message 51 of 59

john.uhden
Mentor
Mentor

Just to clear up the confusion...

I trust that the symbol names used herein will never be used by Autodesk.

 

(defun igzlpig-sort (funkshun nput-list)
 (mapcar (function (lambda (n)(nth n nput-list))) (vl-sort-i nput-list funkshun))
)

Command: (igzlpig-sort '< '("zebra" "ant" "dog" "cat" "ant" "zebra"))
("ant" "ant" "cat" "dog" "zebra" "zebra")

Command: (igzlpig-sort '> '("zebra" "ant" "dog" "cat" "ant" "zebra"))
("zebra" "zebra" "dog" "cat" "ant" "ant")

Command: (igzlpig-sort '> (list 12 pi 9.33 -1 6.67))
(12 9.33 6.67 3.14159 -1)

Command: (igzlpig-sort '< (list 12 pi 9.33 -1 6.67))
(-1 3.14159 6.67 9.33 12)

John F. Uhden

0 Likes
Message 52 of 59

thsa2501
Enthusiast
Enthusiast

hii,

i want to know how its working lambda function here which i red marked. here, what is (cdr a) &     (cdr b)i am much confusing

 

kindly clarify me

!list1
((A . 4) (B . 3) (C . 2) (D . 1) (D . 1))
(vl-sort list1 '(lambda (a b) (< (cdr a) (cdr b))));i am confusing here.what input comes here

 

0 Likes
Message 53 of 59

ВeekeeCZ
Consultant
Consultant
((A . 4) (B . 3) (C . 2) (D . 1) (D . 1))

 

The function sorts the given list of pairs by the second members of the pairs.

(cdr '(A . 4)) returns 4. 

 

A very similar example is described in help HERE 

Message 54 of 59

_gile
Consultant
Consultant

car and cdr are fundamental basics of all LISP dialects.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 55 of 59

thsa2501
Enthusiast
Enthusiast

hi,

thanks for the reply.

((A . 4) (B . 3) (C . 2) (D . 1) (D . 1))

'(lambda ( a b) (< (cdr (A . 4)) (cdr (B . 3)))

is this correct?

thanks advance

0 Likes
Message 56 of 59

ВeekeeCZ
Consultant
Consultant

No.

What's your goal, post a list before and desired sorted list after.

0 Likes
Message 57 of 59

thsa2501
Enthusiast
Enthusiast

hi,

thanks for the reply.i know fundamentals of car ,cdr functions.

but, I don't know how its working in lambda function because of (lambda ( a b)).

what is a & b

for example the list(setq lst '((1 2 3) (2 5 6) (4 5 7)))

 (cdr a) =(2 5 6) (4 5 7),it is coming when i put the command line

(cdr b)= ???

thanks advance

0 Likes
Message 58 of 59

Kent1Cooper
Consultant
Consultant

@thsa2501 wrote:

.... I don't know how its working in lambda function because of (lambda ( a b)).

what is a & b

for example the list(setq lst '((1 2 3) (2 5 6) (4 5 7)))

 (cdr a) =(2 5 6) (4 5 7),it is coming when i put the command line

(cdr b)= ???


The 'a' and 'b' are stand-ins for the two items in each comparison of pairs of items in the list.  In the case of that sample list, you want the (cadr) function if you want to compare the second items in the sublists -- (cdr) gets the second item from a dotted pair, but from an ordinary list it gets the entire list of items starting with the second one [cuts off the first item].  To get the second item from a [non-dotted-pair] list, use (cadr), which is getting the first item [the a] from the list with its original first item removed [the dr].

Applying the lambda to a list in which the second items of the sublists are all different, so that the order after sorting is apparent:

(setq lst '((1 8 3) (2 4 6) (9 3 0) (4 6 7)))

then

(vl-sort lst '(lambda (a b) (< (cadr a) (cadr b))))
returns

((9 3 0) (2 4 6) (4 6 7) (1 8 3))

What it's doing is saying "When comparing the items in this list, with each possible pair of items to compare [the 'a' and 'b'], if the second item in 'a' is less than the second item in 'b', then 'a' goes before 'b' in the result."

Kent Cooper, AIA
Message 59 of 59

thsa2501
Enthusiast
Enthusiast

hii kent,

sorry for the delay,

thank you so much for the brief information about what I asked here. i have completely understood now that function.

thanks to everyone who replies to me.

best regards 

Hussain

0 Likes