Looping over strings gives wrong type argument error in Emacs Lisp

189 views Asked by At

I am trying to loop over a list of strings with dolist, and join element with a prefix string, using string-join from subr-x to create new string.

(dolist (p '("a" "b" "c"))
   (string-join '(p ".rnc")))

I am getting the error Wrong type argument: sequencep, p. The following code however works.

(dolist (p '("a" "b" "c"))
   (print p))

So this seems to be a problem of string-join or equivalently mapconcat within a loop. Any suggestions? Thanks!

2

There are 2 answers

0
phils On BEST ANSWER
'(p ".rnc")

It's very important to understand that '... which means (quote ...) is not a shorthand for making lists.

It's a form which causes lisp to return, unevaluated, the object that was created by the lisp reader.

In this instance the lisp reader returns a list containing the symbol p and a string ".rnc" -- and the symbol p is indeed not a sequence (hence your error).

Use (list p ".rnc") to create a list using the evaluated value of p as a variable.


p.s. Be sure to go over the distinct read and eval phases of lisp execution. Once you understand the distinction, quote will make much more sense.

1
Steve Vinoski On

string-join takes a sequence of strings and joins them together with the separator, so even if the arguments were correct, it's not going to do what you want if you pass it just a single string and a separator, since in that case it just returns the string because there's nothing to join. Also, dolist will by default return nil, and it makes collecting your results more difficult than necessary.

Use mapcar instead, since it will return a list of results, and use concat to add the suffix:

(mapcar (lambda (s) (concat s ".rnc")) '("a" "b" "c"))

Evaluating this results in:

("a.rnc" "b.rnc" "c.rnc")