# Efficient Variables

Every variable used in an AutoLisp routine uses up system resources. You've probably been advised before now, not to use too many SETQ's. LISP, itself was originally a functional language, without any variables. Here is a typical example of how we all go about collecting the values required for our routines.

```	(setq "oldecho" (getvar "CMDECHO"))
(setq "oldhigh" (getvar "HIGHLIGHT"))
(setq "oldsnap" (getvar "OSMODE"))
(setq pt1 (getpoint "\Enter First Point : "))
(setq pt2 (getpoint "\Enter Second Point : "))
(setq thk (getdist "\Enter Thickness : "))
(setq qty (getint "\Enter Number Required : "))
```

Programmatically, there is nothing wrong with this coding, except that seven (7) variables are used, each of which takes up system resources. As well as this, each variable will need to be declared as Local to prevent a scattering of loose variables all over the place.

A much better way of storing your variables is to place them in a list. Here's one way of doing this :

```	(setq AList (append (list (getvar "CMDECHO")) AList))
(setq AList (append (list (getvar "HIGHLIGHT")) AList))
(setq AList (append (list (getvar "OSMODE")) AList))
(setq AList (append (list (getpoint "\Enter First Point : ")) AList))
(setq AList (append (list (getpoint "\Enter Second Point : ")) AList))
(setq AList (append (list (getdist "\Enter Thickness : ")) AList))
(setq AList (append (list (getint "\Enter Number Required : ")) AList))
```

If we ran this sequence of coding, the variable AList would contain something like this :

`	(5 10.0 (660.206 391.01 0.0) (411.014 548.932 0.0) 32 1 0)`

Now this is a lot better. Every variable stored in one list and only one variable to declare. To retrieve any of the values, we would simply do the following :

`	(setvar "OSMODE" (nth 4 AList))`

This, of course would return 32, the value of the Snap that we previously saved.

The problem with this though, is remembering which value belongs to what. To achieve this we would need to keep track of the order in which we passed the values to our list. Wouldn't it be great if we could pass a label along with each value so that we could easily retrieve the value by just quoting the label. By using 'Associative Lists' we can do just that.

Have a look at this :

```(setq AList (append (list (cons "OLDECHO" (getvar "CMDECHO"))) AList))
(setq AList (append (list (cons "OLDHIGH" (getvar "HIGHLIGHT"))) AList))
(setq AList (append (list (cons "OLDSNAP" (getvar "OSMODE"))) AList))
(setq AList (append (list (cons "PT1" (getpoint "\Enter First Point : "))) AList))
(setq AList (append (list (cons "PT2" (getpoint "\Enter Second Point : "))) AList))
(setq AList (append (list (cons "THK" (getdist "\Enter Thickness : "))) AList))
(setq AList (append (list (cons "QTY" (getint "\Enter Number Required : "))) AList))
```

This coding would return something like this :

```(("QTY" . 6) ("THK" . 12.0) ("PT2" 809.113 523.118 0.0) ("PT1" 356.314 646.115 0.0)
("OLDSNAP" . 32) ("OLDHIGH" . 1) "OLDECHO" 0)
```

Now, to retrieve any value from this list, irrespective of it's position in the list, we would simply do something like this :

`	(setvar "OSMODE" (cdr (assoc "OLDSNAP" AList)))`

This, again would return 32.

Now, by converting the construction of the list, and the retrieving of values from the list, into functions, we have an elegant and sophisticated way of storing our variables in an efficient and practical manner. Following, is an AutoLisp routine that can be used, with just a wee bit of modification, in any situation to make the storage of your variable much more efficient :

```(defun c:efflist ( / AnItem item MainList)

(setq AnItem (getvar "OSMODE"))
;get the snap setting

(AList "OLDSNAP" AnItem)

(setq AnItem (getvar "HIGHLIGHT"))
;get the highlight setting

(AList "OLDHIGH" AnItem)

(setq AnItem (getvar "CMDECHO"))
;get the command echo setting

(AList "OLDECHO" AnItem)

(setvar "Osmode" 32)
;reset snap to intersection

(setvar "Highlight" 0)
;switch off highlight

(setvar "Cmdecho" 0)
;switch off command echo

(setq AnItem (getpoint "\nSelect First Point : "))
;get the first point

(AList "FirstPoint" AnItem)

(setq AnItem (getpoint AnItem "\nSelect Second Point : "))
;get the second point

(AList "SecondPoint" AnItem)

(setq AnItem (getpoint AnItem "\nSelect Third Point : "))
;get the third point

(AList "ThirdPoint" AnItem)

(setq AnItem (getpoint AnItem "\nSelect Fourth Point : "))
;get the fourth point

(AList "FourthPoint" AnItem)

(command "Line" (RList "FirstPoint")
(RList "SecondPoint")
(RList "ThirdPoint")
(RList "FourthPoint")
"C"
)
;retrieve all the point values and draw the shape

(setvar "OSMODE" (RList "OLDSNAP"))
;retrieve and reset snap

(setvar "HIGHLIGHT" (RList "OLDHIGH"))
;retrieve and reset highlight

(setvar "CMDECHO" (RList "OLDECHO"))
;retrieve and reset command echo

(princ)

);defun

;This function constructs the list and adds it to the main list
(defun AList (Name Val)

(setq item (list (cons Name Val)))
;construct list

(setq MainList (append item Mainlist))
;add it to the main list

);defun

;This function retrieves the values from the main list
(defun RList (TheName)

(cdr (assoc TheName MainList))
;retrieve value from list

);defun
(princ)
```

After running this routine, the value of the variable MainList would look something like this :

```(("FourthPoint" 456.598 514.007 0.0) ("ThirdPoint" 676.92 293.827 0.0)
("SecondPoint" 1030.95 526.155 0.0) ("FirstPoint" 576.636 732.669 0.0)
("OLDECHO" . 0) ("OLDHIGH" . 1) ("OLDSNAP" . 32))
```