something confusing about define-key (and the issue of when to quote an argument) - emacs

It seems one is not supposed to quote KEYMAP when using define-key.
(define-key org-remember-mode-map "\C-c\C-r" 'org-remember-kill)
I'm confused because I think that all arguments of a function that is not quoted are evaluated, and according to the help, define-key is a function, not a macro. I don't see why the value of KEYMAP can be modified after a call of define-key.
(defun increment-value (a)
(setq a (+ 1 a)))
(setq my-num 10)
(increment-value my-num)
my-num ; ===> 10
Update: The answers explain everything, but for those still confused, let me clear up with more examples.
My increment-value example above is equivalent to this:
(let ((n 0))
(print n) ; prints 0
(let ((a n))
(setq a (+ 1 a))
(print a) ; prints 1
)
(print n) ; prints 0
)
What's going on above is, I think, similar to what's going on in this some-map example:
(let ((some-map '(1 2)))
(print some-map) ; prints (1 2)
(let ((a some-map))
(setq a (list 4 (second a)))
(print a) ; prints (4 2)
)
(print some-map) ; prints (1 2)
)
What's going on in define-key is similar to this second some-map example:
(let ((some-map '(1 2)))
(print some-map) ; prints (1 2)
(let ((a some-map))
(setcar a 4)
(print a) ; prints (4 2)
)
(print some-map) ; prints (4 2)
)
Now read the answers again with these three examples in mind and you will get it. Read also http://www.emacswiki.org/emacs/ListModification

You aren't actually changing what 'org-remember-map is (a pointer to a particular list structure), you are modifying the actual structure. Read this info page for details on modifying lists.
Specificially, if you take a look at the documentation for 'make-keymap:
(make-keymap &optional string)
Construct and return a new keymap, of
the form (keymap CHARTABLE . ALIST).
CHARTABLE is a char-table that holds
the bindings for all characters
without modifiers. All entries in it
are initially nil, meaning "command
undefined". ALIST is an assoc-list
which holds bindings for function
keys, mouse events, and any other
things that appear in the input
stream. Initially, ALIST is nil.
You'll see that keymap is a list with three elements. Let me draw that for you (yay M-x artist-mode):
org-remember-map
|
|
v
+----+----+ +----+----+
| | | --+--->+ / | \ |
+-+--+----+ +-/--+--\-+
| | |
v v v
keymap CHARTABLE ALIST
So, the value of the 'org-remember-map is something like the above structure, and when you define a key, what you are doing is changing what is pointed to in the ALIST blob part of the structure.

you're confusing value and name-value mapping.
in your increment-value function, you're not changing a's value as much as changing the mapping of the name a to a new value.
Fundamentally, there is no way to change the value of 10. 10 is 10!
But in the first case, you can either modify the mapping of the name org-remember-mode-map to a fully different map (set a new value), or you can alter the map pointed by that name (its current value). This is what define-key does.
Illustration:
(setq a '(1 2)) -> (1 2)
(setcar a 4) -> 4
a -> (4 2)

Everything you write is completely correct. The thing you are missing is that lists (keymaps are represented as lists) are not values themselves, but containers of values. Thus, you can pass a list to a function and have that function change the values of the list, but the list you have is still the same list.
All the details are in the Cons Cell Type section of the elisp manual.

Related

function (OccurencesOfPrimes < list >) which counts the number of primes in a (possibly nested) list

I am working on problem to get the occurence of Prime in a list in lisp.
Input:
Write a function (OccurencesOfPrimes < list >) which counts the number of primes in a (possibly nested) list.
Output: Example: (OccurencesOfPrimes (((1)(2))(5)(3)((8)3)) returns 4.
I am using the below code but getting the error like:
(
defun OccurencesOfPrimes (list)
(loop for i from 2 to 100
do ( setq isPrime t)
(loop for j from 2 to i
never (zerop (mod i j))
(setq isPrime f)
(break)
)
)
(if (setq isPrime t)
(append list i)
)
)
)
LOOP: illegal syntax near (SETQ ISPRIME F) in
(LOOP FOR J FROM 2 TO I NEVER (ZEROP (MOD I J)) (SETQ ISPRIME F) (BREAK)
)
Any help.
It is important to keep the format consistent with the expected conventions of the language. It helps when reading the code (in particular with other programmers), and can help you see errors.
Also, you should use an editor which, at the minimum, keep tracks of parentheses. In Emacs, when you put the cursor in the first opening parenthesis, the matching parenthesis is highlighted. You can spot that you have one additional parenthesis that serves no purpose.
(
defun OccurencesOfPrimes (list)
(loop for i from 2 to 100
do ( setq isPrime t)
(loop for j from 2 to i
never (zerop (mod i j))
(setq isPrime f)
(break)
)
)
(if (setq isPrime t)
(append list i)
)
) ;; <- end of defun
) ;; <- closes nothing
In Lisp, parentheses are for the computer, whereas indentation is for humans. Tools can automatically indent the code according to the structure (the parenthesis), and any discrepancy between what indentation you expect and the one being computed is a hint that your code is badly formed. If you look at the indentation of your expressions, you can see how deep you are in the form, and that alone helps you understand the code.
Symbol names are dash-separated, not camlCased.
Your code, with remarks:
(defun occurences-of-primes (list)
;; You argument is likely to be a LIST, given its name and the way
;; you call APPEND below. But you never iterate over the list. This
;; is suspicious.
(loop
for i from 2 to 100
do
(setq is-prime t) ;; setting an undeclared variable
(loop
for j from 2 to i
never (zerop (mod i j))
;; the following two forms are not expected here according
;; to LOOP's grammar; setting IS-PRIME to F, but F is not
;; an existing variable. If you want to set to false, use
;; NIL instead.
(setq is-prime f)
;; BREAK enters the debugger, maybe you wanted to use
;; LOOP-FINISH instead, but the NEVER clause above should
;; already be enough to exit the loop as soon as its
;; sub-expression evaluates to NIL.
(break)))
;; The return value of (SETQ X V) is V, so here your test would
;; always succeed.
(if (setq is-prime t)
;; Append RETURNS a new list, without modifying its
;; arguments. In particular, LIST is not modified. Note that "I"
;; is unknown at this point, because the bindings effective
;; inside the LOOP are not visible in this scope. Besides, "I"
;; is a number, not a list.
(append list i)))
Original question
Write one function which counts all the occurrences of a prime number in a (possibly nested) list.
Even though the homework questions says "write one function", it does not say that you should write one big function that compute everything at once. You could write one such big function, but if you split your problem into sub-problems, you will end with different auxiliary functions, which:
are simpler to understand (they do one thing)
can be reused to build other functions
The sub-problems are, for example: how to determine if a number is a prime? how to iterate over a tree (a.k.a. a possibly nested list)? how to count
the occurrences?
The basic idea is to write an "is-prime" function, iterate over the tree and call "is-prime" on each element; if the element is prime and was never seen before, add 1 to a counter, local to your function.
You can also flatten the input tree, to obtain a list, then sort the resulting
list; you iterate over the list while keeping track of the last
value seen: if the value is the same as the previous one, you
already know if the number is prime; if the previous number differs, then
you have to test if the number is prime first.
You could also abstract things a little more, and define a higher-order tree-walker function, which calls a function on each leaf of the tree. And write another higher-order function which "memoizes" calls: it wraps around a
function F so that if you call F with the same arguments as before,
it returns the result that was stored instead of recomputing it.
Example
I'll combine the above ideas because if you give that answer to a teacher you are likely to have to carefully explain what each part does (and if you can, great for you); this is not necessarily the "best" answer, but it covers a lot of things.
(defun tree-walk-leaves (tree function)
(typecase tree
(null nil)
(cons
(tree-walk-leaves (car tree) function)
(tree-walk-leaves (cdr tree) function))
(t (funcall function tree))))
(defun flatten (tree &optional keep-order-p)
(let ((flat nil))
(tree-walk-leaves tree (lambda (leaf) (push leaf flat)))
(if keep-order-p
(nreverse flat)
flat)))
(defun prime-p (n)
(or (= n 2)
(and (> n 2)
(oddp n)
(loop
for d from 3 upto (isqrt n) by 2
never (zerop (mod n d))))))
(defun count-occurences-of-prime (tree)
(count-if #'prime-p (remove-duplicates (flatten tree))))
(count-occurences-of-prime '(((1)(2))(5)(3)((8)3)))
=> 4
If, instead, you don't want to remove duplicates but count the multiple times a prime number occurs, you can do:
(count-if (memoize #'prime-p) (flatten tree))
... where memoize is:
(defun memoize (function &key (test #'equalp) (key #'identity))
(let ((hash (make-hash-table :test test)))
(lambda (&rest args)
(let ((args (funcall key args)))
(multiple-value-bind (result exists-p) (gethash args hash)
(values-list
(if exists-p
result
(setf (gethash args hash)
(multiple-value-list (apply function args))))))))))
(memoize is useless if there are no duplicates)

How to access "two" in (("one" . "two")) in elisp

I'm very new to elisp and I'm trying to adapt some existing code.
While looping over a table (generated by the orgmode function org-clock-get-table-data) I try the following:
((equal column "Project") (insert (cdr row)))
which yeilds the following in the Messages buffer:
cond: Wrong type argument: char-or-string-p, (#("Verify CalTime accruals for vacation/sick" 0 41
(fontified t org-category #("Admin" 0 5 (fontified t org-category "Admin" org-category-position 32
line-prefix nil wrap-prefix nil ...)) org-category-position 32 line-prefix #("*" 0 1 (face org-
hide)) wrap-prefix #(" " 0 4 (face org-indent)) ...)) nil 30 (("wps" . "Administration")))
The value that I want to insert is "Administration" so I try this
((equal column "Project") (insert (nth 4 row)))
which yeilds the following in the minibuffer
Wrong type argument, char-or-string-p, (("wps" . "Administration"))
Can someone tell me how I can insert the string "Administration"?
EDIT
Thanks Wes and Drew:
(cdar row)
Doing the above yields the first element of the complex list that I saw in the Messages buffer earlier:
Verify CalTime accruals for vaction/sick
row seems to be a complex list of lists:
((equal column "Project") (insert (car row))); yeilds ^B
((equal column "Project") (insert (cdr row)))
yields:
cond: Wrong type argument: char-or-string-p, (#("Verify CalTime accruals for vacation/sick" 0 41
(fontified t org-category #("Admin" 0 5 (fontified t org-category "Admin" org-category-position 32
line-prefix nil wrap-prefix nil ...)) org-category-position 32 line-prefix #("*" 0 1 (face org-
hide)) wrap-prefix #(" " 0 4 (face org-indent)) ...)) nil 30 (("wps" . "Administration")))
I think each "#" in the output above represents a list item. The fact that (nth 4 row) gives the error output shown above supports this and suggests that something like this might work:
((equal column "Project") (insert (nth 2 (nth 4 row))))
;yeilds wrong type argument, char-or-string-p, nil
So there is probably some function that I need to use to decode that 4th list item....
That 4th element is the orgmode property that has been assigned to the clocktable entry on the row we are parsing. This list of properties is defined in my .emacs:
(setq org-global-properties
;; WPS = Web Platform Services. Time tracking for Google Sheet begun with CalTime Migration
'(("wps_ALL".
"Administration
ASG-Consulting
Chanc-Office-Website
")))
Instead of the assoc + cdr combination, you can also use assoc-default:
ELISP> (assoc-default "one" '(("one" . "two")))
=> "two"
Note that lists of the form (("wps" . "Administration") ("foo" . "bar")) are typically "alists", and so you may need to handle the situation where there is more than one item in your list.
Read: C-hig (elisp) Association Lists RET
and also: (elisp) Dotted Pair Notation
You may obtain a keyed item from an alist with (assoc) or (assq) depending on the form of equality needed for the test. Equivalent strings are not equal objects in elisp, so in this case you want assoc rather than assq.
That gives you the entire (KEY . VALUE) form as a result, and you obtain the cdr of that as usual; hence:
(let ((my-alist '(("wps" . "Administration") ("foo" . "bar"))))
(cdr (assoc "wps" my-alist)))
yields: "Administration"
Lists are complex to think about in elisp. Until you've done enough of them that you stop thinking about them. Ha ha. But read up on the functions like car (picks the first element in a list) and cdr (picks the rest of the rest) to get started. And then you can chain things by combining letters in short sequences at least. So the answer you want is:
(cdar row)

How to define symbols that will work like ( and ) by symbol macro?

I am trying define symbols a and b in following way
a + 1 1 b
2
I am trying to do this by using define-symbol-macro
(define-symbol-macro a '( )
(define-symbol-macro b ') )
but this way is not working.
What Lisp does with source code
Common Lisp is an incredibly flexible language, in part because its source code can be easily represented using the same data structures that are used in the language. The most common form of macro expansion transforms the these structures into other structures. These are the kind of macros that you can define with define-symbol-macro, define-compiler-macro, defmacro, and macrolet. Before any of those kind of macroexpansions can be performed, however, the system first needs to read the source from an input stream (typically a file, or an interactive prompt). That's the reader's responsibility. The reader also is capable of executing some special actions when it encounters certain characters, such ( and '. What you're trying to do probably needs to be happening down at the reader level, if you want to have, e.g., (read-from-string "a + 1 1 b") return the list (+ 1 1), which is what you want if you want (eval (read-from-string "a + 1 1 b")) to return 2. That said, you could also define a special custom language (like loop does) where a and b are treated specially.
Use set-macro-character, not define-symbol-macro
This isn't something that you would do using symbol-macros, but rather with macro characters. You can set macro characters using the aptly named set-macro-character. For instance, in the following, I set the macro character for % to be a function that reads a list, using read-delimited-list that should be terminated by ^. (Using the characters a and b here will prove very difficult, because you won't be able to write things like (set-macro-character ...) afterwards; it would be like writing (set-m(cro-ch(r(cter ...), which is not good.)
CL-USER> (set-macro-character #\% (lambda (stream ignore)
(declare (ignore ignore))
(read-delimited-list #\^ stream)))
T
CL-USER> % + 1 1 ^
2
The related set-syntax-from-char
There's a related function that almost does what you want here, set-syntax-from-char. You can use it to make one character behave like another. For instance, you can make % behave like (
CL-USER> (set-syntax-from-char #\% #\()
T
CL-USER> % + 1 1 )
2
However, since the macro character associated with ( isn't looking for a character that has the same syntax as ), but an actual ) character, you can't simply replace ) with ^ in the same way:
CL-USER> (set-syntax-from-char #\^ #\))
T
CL-USER> % + 1 1 ^
; Evaluation aborted on #<SB-INT:SIMPLE-READER-ERROR "unmatched close parenthesis" {1002C66031}>.
set-syntax-from-char is more useful when there's an existing character that, by itself does something that you want to imitate. For instance, if you wanted to make ! an additional quotation character:
CL-USER> (set-syntax-from-char #\! #\')
T
CL-USER> (list !a !(1 2 3))
(A (1 2 3))
or make % be a comment character, like it is in LaTeX:
CL-USER> (set-syntax-from-char #\% #\;)
T
CL-USER> (list 1 2 % 3 4
5 6)
(1 2 5 6)
But consider why you're doing this at allā€¦
Now, even though you can do all of this, it seems like something that would be utterly surprising to anyone who ran into it. (Perhaps you're entering an obfuscated coding competition? ;)) For the reasons shown above, doing this with commonly used characters such as a and b will also make it very difficult to write any more source code. It's probably a better bet to define an entirely new readtable that does what you want, or even write a new parser. even though (Common) Lisp lets you redefine the language, there are still things that it probably makes sense to leaveĀ alone.
A symbol-macro is a symbol that stands for another form. Seems like you want to look at reader macros.
http://clhs.lisp.se/Body/f_set__1.htm
http://dorophone.blogspot.no/2008/03/common-lisp-reader-macros-simple.html
I would second Rainer's comment though, what are you trying to make?
Ok so I love your comment on the reason for this and now I know this is for 'Just because it's lisp' then I am totally on board!
Ok so you are right about lisp being great to use to make new languages because we only have to 'compile' to valid lisp code and it will run. So while we cant use the normal compiler to do the transformation of the symbols 'a and 'b to brackets we can write this ourselves.
Ok so lets get started!
(defun symbol-name-equal (a b)
(and (symbolp a) (symbolp b) (equal (symbol-name a) (symbol-name b))))
(defun find-matching-weird (start-pos open-symbol close-symbol code)
(unless (symbol-name-equal open-symbol (nth start-pos code))
(error "start-pos does not point to a weird open-symbol"))
(let ((nest-index 0))
(loop :for item :in (nthcdr start-pos code)
:for i :from start-pos :do
(cond ((symbol-name-equal item open-symbol) (incf nest-index 1))
((symbol-name-equal item close-symbol) (incf nest-index -1)))
(when (eql nest-index 0)
(return i))
:finally (return nil))))
(defun weird-forms (open-symbol close-symbol body)
(cond ((null body) nil)
((listp body)
(let ((open-pos (position open-symbol body :test #'symbol-name-equal)))
(if open-pos
(let ((close-pos (find-matching-weird open-pos open-symbol close-symbol body)))
(if close-pos
(weird-forms open-symbol close-symbol
`(,#(subseq body 0 open-pos)
(,#(subseq body (1+ open-pos) close-pos))
,#(subseq body (1+ close-pos))))
(error "unmatched weird brackets")))
(if (find close-symbol body :test #'symbol-name-equal)
(error "unmatched weird brackets")
(loop for item in body collect
(weird-forms open-symbol close-symbol item))))))
(t body)))
(defmacro with-weird-forms ((open-symbol close-symbol) &body body)
`(progn
,#(weird-forms open-symbol close-symbol body)))
So there are a few parts to this.
First we have (symbol-name-equal), this is a helper function because we are now using symbols and symbols belong to packages. symbol-name-equal gives us a way of checking if the symbols have the same name ignoring what package they reside in.
Second we have (find-matching-weird). This is a function that takes a list and and index to an opening weird bracket and returns the index to the closing weird bracket. This makes sure we get the correct bracket even with nesting
Next we have (weird-forms). This is the juicy bit and what it does is to recursively walk through the list passed as the 'body' argument and do the following:
If body is an empty list just return it
if body is a list then
find the positions of our open and close symbols.
if only one of them is found then we have unmatched brackets.
if we find both symbols then make a new list with the bit between the start and end positions inside a nested list.
we then call weird forms on this result in case there are more weird-symbol-forms inside.
there are no weird symbols then just loop over the items in the list and call weird-form on them to keep the search going.
OK so that function transforms a list. For example try:
(weird-forms 'a 'b '(1 2 3 a 4 5 b 6 7))
But we want this to be proper lisp code that executes so we need to use a simple macro.
(with-weird-forms) is a macro that takes calls the weird-forms function and puts the result into our source code to be compiled by lisp. So if we have this:
(with-weird-forms (a b)
(+ 1 2 3 a - a + 1 2 3 b 10 5 b 11 23))
Then it macroexpands into:
(PROGN (+ 1 2 3 (- (+ 1 2 3) 10 5) 11 23))
Which is totally valid lisp code, so it will run!
CL-USER> (with-weird-forms (a b)
(+ 1 2 3 a - a + 1 2 3 b 10 5 b 11 23))
31
Finally if you have settled on the 'a' and 'b' brackets you could write another little macro:
(defmacro ab-lang (&rest code)
`(with-weird-forms (a b) ,#code))
Now try this:
(ab-lang a let* a a d 1 b a e a * d 5 b b b a format t "this stupid test gives: ~a" e b b)
Cheers mate, this was great fun to write. Sorry for dismissing the problem earlier on.
This kind of coding is very important as ultimately this is a tiny compiler for our weird language where symbols can be punctuation. Compilers are awesome and no language makes it as effortless to write them as lisp does.
Peace!

Should I call add-to-list in Emacs Lisp a destructive function?

add-to-list is often used to add an element to a list if the element is not in the list.
(let* ((aa (list 1 2 3))
(bb aa))
(add-to-list 'aa 0)
(list :aa aa :bb bb))
=> (:aa (0 1 2 3) :bb (1 2 3))
Should one call add-to-front a destructive function because it changes the meaning of name aa? Or should it be called non-destructive because the list that aa used to point to is intact?
(let* ((cc (list 1 2 3))
(dd cc))
(add-to-list 'cc 0 t)
(list :cc cc :dd dd))
=> (:cc (1 2 3 0) :dd (1 2 3))
For Emacs newbies wondering why bb and dd equals (1 2 3), feel free to open a separate stackoverflow question for that and leave a link with "add comment" button. For Emacs newbies wondering why some fellow newbies would wonder that, replace (add-to-list 'aa 0) with (setcar aa 111) and see.
For Lispers who don't use Emacs, here's a simplified definition of add-to-list
(defun simple-add-to-list (list-var element &optional append)
"Add ELEMENT to the value of LIST-VAR if it isn't there yet.
If ELEMENT is added, it is added at the beginning of the list,
unless the optional argument APPEND is non-nil, in which case
ELEMENT is added at the end.
The return value is the new value of LIST-VAR."
(let ((lst (symbol-value list-var)))
(if (member element lst)
lst
(set list-var
(if append
(append lst (list element))
(cons element lst))))))
If it's capable of modifying the list passed to it, then it's destructive.
If a function takes a list via a symbol, it should be automatically assumed to be destructive, no? Otherwise why not just take the list itself?

Common lisp push from function

I have the following common lisp functions: (aggregate line1 line2) and (queuer data result).
queuer should push into result either the values line1 and line2 if they have the 1st field different, or the aggregate of those 2 lines if they have the 1st field equal.
I do not know why it doesn't change my result list.
Note: I am initializing the result list with a (push (pop data) result) to have the first element there. The 2 lists are 1-depth nested lists (("1" "text") ("2" "text") (...)).
(defun aggregate (line1 line2)
(progn
(list
(nth 0 line1)
(nth 1 line1)
(nth 2 line1)
(concatenate 'string (nth 3 line1) ", " (nth 3 line2))
(concatenate 'string (nth 4 line1) ", " (nth 4 line2)))))
(push (pop x) y)
(defun queuer (data result)
(loop do
(let ((line1 (pop data))
(line2 (pop result)))
(if (equal (first line1) (first line2))
(progn
(push (aggregate line1 line2) result)
(print "=="))
(progn
(push line2 result)
(push line1 result)
(print "<>"))))
while data))
Thank you for any insights.
If you write functions in Lisp it is preferable to think 'functionally'. A function takes values and returns values. A typical rule would be to avoid side effects. So your function should return a result value, not 'modify' a variable value.
Instead of:
(defparameter *result* '())
(defun foo (a)
(push a *result*))
use:
(defparameter *result* '())
(defun foo (a result)
(push a result)
result)
(setf *result* (foo a *result*))
Note also that aggregate does not need the progn.
Slightly advanced (don't do that):
If you have a global list:
(defparameter *foo* '())
You can't push onto it, as we have seen, like this:
(defun foo (l)
(push 1 l))
If you call foo the variable *foo* is unchanged. Reason: Lisp does not pass a variable reference, it passes the value of the variable.
But how can we pass a reference? Well, pass a reference: a cons cell would do it (or a structure, a vector, a CLOS object, ...):
CL-USER 38 > (defparameter *foo* (list '()))
*FOO*
CL-USER 39 > (defun foo (ref)
(push 1 (first ref)))
FOO
CL-USER 40 > (foo *foo*)
(1)
CL-USER 41 > (foo *foo*)
(1 1)
Now, if we look at *foo*, it is changed. But we haven't really changed the variable. We have changed the first entry of the list.
CL-USER 42 > *foo*
((1 1))
But, don't do it. Program in a functional style.
You cannot modify the contents of a variable with a function that only takes the variable's value.
Take the following simple example:
(defun futile-push (thing list)
(push thing list))
(let ((foo (list 1)))
(futile-push 2 foo))
What happens?
Foo is evaluated to the list it points to.
2 evaluates to 2.
These two arguments are passed to the function.
Inside the function invocation:
Thing is now bound to 2.
List is now bound to the list (1).
Note that the list does not know that it is also referenced by the variable
foo outside the function.
foo
|
v
---------
list -> | 1 |NIL|
---------
Push modifies the variable list in such a way that it is now bound to
the list (2 1).
Note that this does not affect foo outside. Foo still points to
the same thing as before.
foo
|
v
--------- ---------
list -> | 2 | ----> | 1 |NIL|
--------- ---------
Futile-push returns the return value of the push form, which happens
to be the new value of list.
That return value is never used or bound, so it vanishes.
foo
|
v
---------
| 1 |NIL|
---------
The most straightforward way to do what you want is to return the new
value and then set the variable outside:
(let ((foo (list 1)))
(setf foo (not-so-futile-push 2 foo)))
If you need to do that at more than one place, it might be worthwhile
to write a macro for that which expands to the setf form. Note that
push is itself a macro for exactly these reasons.
When you call push in queuer, this changes the value of the binding "result", not the cons cell that result is pointing to.
(push x list)
is essentially equivalent to:
(setq list (cons x list))
As long as your queuer function is a function, it couldn't really be any other way. If you call it with the argument "my-queue", then that argument (a symbol) is evaluated when you call the function and the result of the evaluation -- a cons cell -- is passed to the function. There is no way to modify that cons cell to indicate that another cons cell should be "prepended" to it -- cons cells don't keep track of the things that point to them.
There are (at least) three possible solutions:
Write your code so that queuer returns the new queue, instead of expecting the argument to be modified (or "mutated").
Wrap the queue inside a mutable layer of indirection. You could for instance hold the queue in the car or the cdr of a cons cell. You would then be able to mutate (car result) or (cdr result) in your queuer function, for instance with push.
Convert queuer to be a macro instead of a function. You can then write code to mutate its argument that will essentially be 'inserted' in your code wherever you use the queuer macro.
I would personally recommend the first solution. Where you would then, if you had your mutating queuer, want to write:
(queuer-mutating data my-queue)
You would instead write something like:
(setf my-queue (queuer-not-mutating data my-queue))
When you initialize data variable using (push (pop data) result), it moves items from data to result instead of copying:
CL-USER> (setq data '(("1" "text1") ("2" "text2") ("3" "text3")))
(("1" "text1") ("2" "text2") ("3" "text3"))
CL-USER> (setq result nil)
NIL
CL-USER> (push (pop data) result)
;Compiler warnings :
; In an anonymous lambda form: Undeclared free variable DATA (3 references)
(("1" "text1"))
CL-USER> (print data)
(("2" "text2") ("3" "text3"))
(("2" "text2") ("3" "text3"))
CL-USER> (print result)
(("1" "text1"))
(("1" "text1"))
What you might want to use instead is (copy-list list) function:
CL-USER> (setq copy2 (copy-list data))
(("2" "text2") ("3" "text3"))