Semx11 Posted October 6, 2022 Posted October 6, 2022 (edited) When you run (vl-list* 1 2 3), it returns (1 2 . 3) (this example is also documented for the function vl-list*) (vl-list* 1 2 3 4) returns (1 2 3 . 4) This makes no sense to me. It seems to be partially a list, and partially a dotted pair. To recreate it in vanilla lisp, you would use (setq $weirdList '(1 2 . 3)) Executing (car) or (nth 0) returns 1. (cadr) or (nth 1) returns 2 (caddr) or (nth 2) returns 'bad argument type: 3' So what is this data structure? And what is the point... how do you access the last value (if it even is a value?) I've worked with lisp for a year now and this really just confuses me lol. Wondering if someone knows what it does and can clear it up. Edited October 6, 2022 by Semx11 Quote
mhupp Posted October 6, 2022 Posted October 6, 2022 (edited) Directly off the website. Return Values The vl-list* function is similar to list, but it will place the last object in the final cdr of the result list. If the last argument to vl-list* is an atom, the result is a dotted list. If the last argument is a list, its elements are appended to all previous arguments added to the constructed list. The possible return values from vl-list* are An atom, if a single atom object is specified. A dotted pair, if all object arguments are atoms. A dotted list, if the last argument is an atom and neither of the previous conditions is true. A list, if none of the previous statements is true. Edited October 6, 2022 by mhupp Quote
Semx11 Posted October 6, 2022 Author Posted October 6, 2022 (edited) Hi @mhupp, thanks for your reply. I did read that part of the documentation obviously. But what is a dotted list? How do you access the data, and how does it differ from a list and a dotted pair? I tried searching online and trying all kinds of commands on it but I can't figure it out. Edit: and what would be a practical use-case for a dotted list? Edited October 6, 2022 by Semx11 Quote
Semx11 Posted October 6, 2022 Author Posted October 6, 2022 I figured it out. Apparently in LISP, a list is nothing but a bunch of nested cons. So (list 1 2 3 4) is the same as (cons 1 (cons 2 (cons 3 (cons 4 nil)))) This also explains (car) and (cdr). (car) takes the left value, and (cdr) the right value. Using (cdr) on a list returns everything from the 2nd value and after that. (vl-list* 1 2 3 4) returns '(1 2 3 . 4), which is the same as (cons 1 (cons 2 (cons 3 4))). So it essentially saves one extra cons. Maybe this is super basic stuff but I've only figured this out after a year of working with LISP lol. Still not clear what the use-case of a dotted list would be, maybe someone has a cool idea Just leaving this here if anyone else is curious about this too. Quote
mhupp Posted October 6, 2022 Posted October 6, 2022 A dotted list is how dxf codes are stored. http://docs.autodesk.com/ACAD_E/2012/ENU/filesDXF/WS1a9193826455f5ff18cb41610ec0a2e719-7a62.htm for example here is part of an polyline's data (-1 . <Entity name: 527c1a20>) (0 . "LWPOLYLINE") (5 . "4CCC9") (330 . <Entity name: 2770b0f0>) (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (370 . -1) (100 . "AcDbPolyline") (90 . 16) (70 . 1) (43 . 0.0) (38 . 0.0) (39 . 0.0) (10 -33.507337499427 -0.845370190263241) ... So if you wanted to know how many vertices are in the polyline you can use assoc function. (setq vert (cdr (assoc 90 (entget ("entname")))) This would look at the entity data (above) and look for item 90 and returns (90 . 16) cdr returns 16 So this is a way to store data and quickly return specific values from a list. Don't really use vl-list* so cant really give you any examples. Quote
Semx11 Posted October 6, 2022 Author Posted October 6, 2022 (edited) I think you misunderstood my question, sorry for that. DXF codes are stored in a list of dotted pairs. A dotted list is something else (apparently). A list looks like this: (cons 1 (cons 2 (cons 3 (cons 4 nil)))) which is the same as (list 1 2 3 4) which is the same as '(1 2 3 4) A list of dotted pairs looks like this: (cons (cons 1 2) (cons (cons 3 4) (cons (cons 5 6) (cons (cons 7 8 ) nil)))) which is the same as (list (cons 1 2) (cons 3 4) (cons 5 6) (cons 7 8)) which is the same as '((1 . 2) (3 . 4) (5 . 6) (7 . 8)) This is used for entget data and DXF codes, but it would look something like this: (cons (cons 0 "LWPOLYLINE") (cons (cons 5 "4CCC9") ... )) [terminated with a nil] which is the same as ((0 . "LWPOLYLINE") (5 . "4CCC9") ... ) A dotted list is simply a normal list that isn't terminated with a nil, it looks like this: (cons 1 (cons 2 (cons 3 (cons 4 5)))) which is the same as '(1 2 3 4 . 5) You can verify these examples by pasting the (cons) version into your AutoCAD console, and it will evaluate to the bottom version. Not quite sure what the use case is for a dotted list, but it's fun to know it exists, I guess Edited October 6, 2022 by Semx11 1 Quote
Semx11 Posted October 6, 2022 Author Posted October 6, 2022 19 minutes ago, mhupp said: Yeah sorry, dont see much dotted list. That's okay, thanks for your time anyway Quote
mhupp Posted October 6, 2022 Posted October 6, 2022 are you trying to use this with something or where you just looking over functions? Quote
marko_ribar Posted October 7, 2022 Posted October 7, 2022 (edited) I suppose usage of (vl-list*) function is exactly you described haphazardly - to avoid multiple consecutive usage of (cons)... Quote : (vl-list* 1 2 3 4) (1 2 3 . 4) : (vl-list* (list 1 2 3) (list 2 3 4) (list 3 4 5) 4) ((1 2 3) (2 3 4) (3 4 5) . 4) : (vl-list* (list 1 2 3) (list 2 3 4) (list 3 4 5) (list 4 5 6)) ((1 2 3) (2 3 4) (3 4 5) 4 5 6) : (vl-list* 3 (list 4 5 6)) (3 4 5 6) : (vl-list* 1 2 3 (list 4 5 6)) (1 2 3 4 5 6) : (cons 1 (cons 2 (cons 3 4))) (1 2 3 . 4) : (cons (list 1 2 3) (cons (list 2 3 4) (cons (list 3 4 5) 4))) ((1 2 3) (2 3 4) (3 4 5) . 4) : (cons (list 1 2 3) (cons (list 2 3 4) (cons (list 3 4 5) (list 4 5 6)))) ((1 2 3) (2 3 4) (3 4 5) 4 5 6) : (cons 3 (list 4 5 6)) (3 4 5 6) : (cons 1 (cons 2 (cons 3 (list 4 5 6)))) (1 2 3 4 5 6) Here are couple of useful sub functions and perhaps possible utility of (vl-list*) function usage... (defun last-pair-of-list ( lst ) (if (not (atom (cdr lst))) (last-pair-of-list (cdr lst)) (if (cdr lst) lst (cons nil lst) ) ) ) (defun is-dot-list-p ( lst / last-pair-of-list ) (defun last-pair-of-list ( lst ) (if (not (atom (cdr lst))) (last-pair-of-list (cdr lst)) (if (cdr lst) lst (cons nil lst) ) ) ) (if (listp lst) (car (last-pair-of-list lst)) ) ) (defun is-list-p ( lst / last-pair-of-list ) (defun last-pair-of-list ( lst ) (if (not (atom (cdr lst))) (last-pair-of-list (cdr lst)) (if (cdr lst) lst (cons nil lst) ) ) ) (if (listp lst) (not (car (last-pair-of-list lst))) ) ) (defun assocbylast ( val lst / last-pair-of-list lastvals pos ) (defun last-pair-of-list ( lst ) (if (not (atom (cdr lst))) (last-pair-of-list (cdr lst)) (if (cdr lst) lst (cons nil lst) ) ) ) (setq lastvals (vl-remove nil (mapcar (function (lambda ( x / v ) (if (listp x) (if (atom (cdr (setq v (last-pair-of-list x)))) (cdr v) (cadr v) ) ) )) lst ) ) ) (if (setq pos (vl-position val lastvals)) (nth pos lst) ) ) (defun butlast ( lst / last-pair-of-list pair ret ) (defun last-pair-of-list ( lst ) (if (not (atom (cdr lst))) (last-pair-of-list (cdr lst)) (if (cdr lst) lst (cons nil lst) ) ) ) (if (listp lst) (progn (if (not (car (setq pair (last-pair-of-list lst)))) (setq ret (reverse (cdr (reverse lst)))) (progn (while (not (equal lst pair)) (setq ret (append ret (list (car lst)))) (setq lst (cdr lst)) ) (setq ret (append ret (list (car lst)))) ) ) ret ) ) ) Quote : (setq lst (list (vl-list* 1 2 3 4) (vl-list* 2 3 4 5) (vl-list* 3 4 5 6) (vl-list* 4 5 6 7) (list 5 6 7 8) (list 6 7 8 9))) ((1 2 3 . 4) (2 3 4 . 5) (3 4 5 . 6) (4 5 6 . 7) (5 6 7 8) (6 7 8 9)) : (assocbylast 7 lst) (4 5 6 . 7) : (assocbylast 8 lst) (5 6 7 8) : (butlast (assocbylast 7 lst)) (4 5 6) : (butlast (assocbylast 8 lst)) (5 6 7) Also this link may be of interest : https://www.theswamp.org/index.php?topic=57748.0 Regards, M.R. HTH. Edited October 7, 2022 by marko_ribar Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.