For example, I have a list:

(setq foo '(1 2 3 4 5))

Then I need to get a pointer to its 3rd index element (which contains 4 in the example):

(setq p (SOME_FUNCTION foo 3))

The element with p address can be moved to another list so I can't just save its current foo's index.

And I need to be able to say later on:

(push 0 foo)
=> (0 1 2 3 4 5)
(setf p 444)

and list foo must be (0 1 2 3 444 5) afterwards.

Is this possible in Emacs lisp?

  • That is't so LISPy. Get a tutorial for LISP and work through it. Emacs LISP (as do many LISPs) has nth, so you'd get the 3rd element by (nth 2 foo) – vonbrand Feb 5 '13 at 12:14
  • @vonbrand I tried (setq p (nth 3 foo)) (setf p 444) but foo still contains (1 2 3 4 5). – Alexander Gromnitsky Feb 5 '13 at 12:18
  • Aside from the question, for beginners who are wondering why (setf p 444) cannot have any effect on the original list, the reason is that (setq p obj) simply make the variable p refer to the specified target object. (Also true in Python and many other dynamic languages) Also, numbers are immutable (again true in many other dynamic languages as well). This means that numbers are to be considered as objects whose state cannot change. Nevertheless, one can make a variable refer to a different number than before, or even to an object that is not a number. – Jisang Yoo Aug 2 '14 at 12:13
up vote 7 down vote accepted

In general, you can't store the "address" of an object. However, you can refer to a cons cell (a cons cell is what lists are made of). The cons cell could later be modified using setcar and setcdr.

For example:

(defvar my-cons-cell nil)

(defun my-save-cons-cell (cons-cell)
  (setq my-cons-cell cons-cell))

(defun my-set-car-in-saved-cons-cell (value)
  (setcar my-cons-cell value))

;; Test

(setq foo '(1 2 3 4 5))

(my-save-cons-cell (cdr (cdr (cdr foo))))

(push 0 foo)

(my-set-car-in-saved-cons-cell 444)

Here, foo has the value (0 1 2 3 444 5).

Note that this is really un-lisp like and breaks the functional programming paradigm...

You can do

(setq p (nth 3 foo))

and it stores in p the value stored at the index you want. You can also do

(setf (nth 3 foo) 444)

to store 444 at that place. But if you try to do something like

(setq pointer (nth 3 foo))
...
(setf pointer 444)

that won't work. In Emacs's trunk I have recently added gv-ref and gv-deref which would work just fine in such a case. They work pretty much like C's & and *:

(setq pointer (gv-ref (nth 3 foo)))
...
(setf (gv-deref pointer) 444)

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.