You're very welcome Tannar, I'll to try to explain as best I can:
(cons 10 pt1)
(cons) is used to to take the user input from pt1, combine it with 10 to turn it into a dotted pair to generate the necessary syntax for the DXF code, correct?
Almost.
cons is indeed combining the point input assigned to the variable
pt1 with the DXF Group 10 integer code, however, in this case a dotted pair is not returned since the second argument of the
cons function is a list, not an atom.
Consider the following examples:
_$ (cons 1 2)
(1 . 2)
_$ (cons "a" "b")
("a" . "b")
_$ (cons 1 '(2 3 4))
(1 2 3 4)
_$ (cons '(1 2 3) 4)
((1 2 3) . 4)
_$ (cons '(1 2 3) '(4 5 6))
((1 2 3) 4 5 6)
Notice that a dotted pair is only returned if the second
cons argument is an atom (excluding
nil, since although
nil is considered both an atom and an empty list,
cons considers
nil an empty list).
If the second argument supplied to
cons is a list, the first argument is added to the front of the list - you see this a lot when constructing a list within a loop, e.g.:
(foreach x '(0 1 2 3 4 5)
(setq lst (cons x lst))
)
_$ lst
(5 4 3 2 1 0)
Why no apostrophe when using (cons)?
The apostrophe (or quote) is used to mark an expression or symbol as a literal, to be taken at 'face-value' and not evaluated. In this case we need to evaluate the variable
pt1 to obtain the point value assigned to the symbol, and so
cons must be used. If the apostrophe is used instead, the
pt1 symbol is not evaluated:
_$ (setq pt1 '(1 2 3))
(1 2 3)
_$ (cons 10 pt1)
(10 1 2 3)
_$ '(10 . pt1)
(10 . PT1)
For a more in-depth explanation of the apostrophe, see
here.
(progn)
Reading the documentation I can't follow exactly what this function does. I read it, but just doesn't click for me? Hoping to get more insight from you if you wouldn't mind. 
The
progn function in itself doesn't actually
do all that much, it simply evaluates every expression passed to it and returns the result of the last evaluation, e.g.:
_$ (progn (setq a 10.0 b 6.0) (/ a b))
1.66667
However,
progn provides us with a convenient 'wrapper' in which we can evaluate multiple expressions and pass the set of expressions to be evaluated as a single argument to another function. Think of
progn as creating a 'block' of code, which can then be passed to another function to be evaluated.
In my example:
(defun c:mypline ( / pt1 pt2 lst )
(if (setq pt1 (getpoint "\nSpecify First Point: "))
(progn
(setq lst (list (cons 10 pt1)))
(while (setq pt2 (getpoint "\nSpecify Next Point: " pt1))
(setq lst (cons (cons 10 pt2) lst)
pt1 pt2
)
)
(entmake
(append
(list
'(000 . "LWPOLYLINE")
'(100 . "AcDbEntity")
'(100 . "AcDbPolyline")
(cons 90 (length lst))
'(070 . 0)
)
(reverse lst)
)
)
)
)
(princ)
)
Here, if the user has correctly specified a valid point at the
getpoint prompt, we then want to evaluate multiple expressions within the 'then' argument for the
if function.
However, the 'then' argument will only accept a
single expression to be evaluated, so the set of expressions to be evaluated are grouped within the
progn function, and this single expression (the
progn expression) may then be passed to the
if function as a single argument.
If
progn was
not present, the
setq expression would be taken as the 'then' argument, the
while expression would be the 'else' argument, and the
entmake expression would cause the
if function to error with too many arguments.
Note that other functions which accept multiple arguments could equally be used as such a 'wrapper', however, other such functions will come with certain restrictions and will exhibit different behaviour, for example, although
and will accept any expression, this function will cease evaluation when an expression returns a
nil value (which may be unsuitable for some situations, but perhaps suitable for others); the
+ function could be used if all expressions to be evaluated return a numerical value... etc.
However,
progn is useful in that it will accept
any expression, and will simply evaluate all supplied expressions regardless of their returned value, and returning the value of the last expression evaluated.
I describe
progn some more in
this post.
(append
(list
'(000 . "LWPOLYLINE")
'(100 . "AcDbEntity")
'(100 . "AcDbPolyline")
(cons 90 (length lst))
'(070 . 0)
)
(reverse lst)
)
The (append) function is new to me, but after reading up on the documentation I think I follow. In your other lists from the first three main routines, you used multiple arguments but did not append them. Any particular reason you did on the c:mypline routine?
In the other programs, the number of parameters is known and fixed: to create the Line we have two point variables; for the Circle we have a point variable and a numerical variable; for the Point we have a single point variable; however, for the LWPolyline, the number of parameters is
unknown since the
while loop allows the user to continuously pick points in the drawing.
Hence, rather than assigning every picked point to a separate variable, it is far easier and convenient to collect the points into a list and then append this list to the DXF data list supplied to
entmake.
Also, is the (list) function the only argument that (append) handles?
Note that the
list function is not being passed to the
append function as an argument; the
result of evaluating the
list function forms the argument for the
append function.
append will accept any number of list arguments and will return the result of appending the supplied lists into a single list. Whether the supplied lists are constructed using
list,
cons (not dotted pair),
vl-list*, or are a quoted literal list makes no difference, since a list argument is supplied in all cases.