1

I have a question about how to use interactive to allow the user to identify a desired list element to output.

Let's say I have a variable x assigned to a list structured like this:

(setq x '((y ("y1")
             ("y2")
             ("y3"))
          (z ("z1")
             ("z2")
             ("z3"))))

If I want to retrieve the text "(y1)" from this structure and show it to the user, I know that I can do so by using:

(message (format "%s" (nth 1 (assoc 'y x))))

The problem comes when I try to do the same thing interactively. Let's say I want to write a function that asks the user for the variable name and the desired list (y or z), then retrieves the first associated element:

(defun find-first-associated-value (varname listname)
  (interactive
   "sWhich variable? :
sWhich list? :")
  (message (format "%s" (nth 1 (assoc listname varname)))))

If I try to call this function and fill in the right values, I get the error Wrong type argument: listp, "y".

I can tell the reason this isn't working is that I'm passing strings (varname and listname) to assoc, which expects a KEY and then VALUE. The problem is that I can't figure out how to convert the user-inputted strings collected by interactive to those forms so that they can be understood by assoc. How can I fix this? I'd be very grateful for any help, and I apologize if the question is poorly worded--I'm new to programming in Lisp.

3
  • The problem is that the user inputs the string "y", but your list is using the symbol y. You could try to convert the user inputted string with its symbol via make-symbol. – Dan May 21 '20 at 13:34
  • 1
    @Dan I expect you meant intern ? – phils May 21 '20 at 13:47
  • 1
    elisp tag doesn't apply here. Please, read elisp tag – Muihlinn May 21 '20 at 15:26
1

You can use (interactive "S") to obtain a symbol instead of a string.

Regarding your general question, (intern STRING) returns the canonical symbol with the given name.

(eq 'foo (intern "foo"))
=> t

For more information, see C-hig (elisp)Creating Symbols

4
  • emacs.stackexchange.com/q/39351/454 might be helpful as well. – phils May 21 '20 at 14:06
  • Although this isn't the case, using make-symbol (uninterned symbols) helps to avoid name collision. It's implicit in the previous comment link and Dan's original comment but only briefly mentioned in the docs (AFAIK). – Muihlinn May 21 '20 at 15:53
  • Thank you so much for this - it's great to know about format (and make-symbol). I've tried to incorporate your recommendations into my code, but I must have misunderstood something, because I'm still getting the same error - whether I use "S" instead of "s" in interactive or (nth 1 (assoc (intern listname) varname))), it comes out as Wrong type argument: listp. I'm going to keep reading and experimenting and see if I can ask a pertinent question. – olivierestsage May 21 '20 at 16:56
  • I think you need to intern varname as well. – Fran Burstall May 21 '20 at 19:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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