0

I have a loop with a condition, based on which I decide whether I should append something to existing string or not. In Python, it should look like (this is dummy code, just to show the idea):

result_str = ''
for item in range(5):
  if item % 2 == 0:
    result_str += str(item)

print(result_str)

Output: 024

So the question is: how can I perform addition assignment on strings (+=) in lisp?

1

1 Answer 1

9

String concatenation relies on the more general CONCATENATE function:

(concatenate 'string "a" "b")
=> "ab"

Since it considered verbose by some, you can find libraries that implement shorter versions:

(ql:quickload :rutils)
(import 'rutils:strcat)

And then:

(strcat "a" "b")

In order to assign and grow a string, you need to use SETF with an existing variable.

(let ((string ""))
  (dotimes (i 5)
    (when (evenp i)
      (setf string (strcat string (princ-to-string i)))))
  string)

A more idiomatic way in Lisp is to avoid string concatenation, but print in a stream which writes into a buffer.

(with-output-to-string (stream)
  ;; now, stream is bound to an output stream 
  ;; that writes into a string. The whole form 
  ;; returns that string.
  (loop
     for i from 0 below 5 by 2
     do (princ i stream)))
 => "024"

Here above, stream is just the symbol used for naming the stream, you could use any other one, including *standard-output*, the special variable that represents current output stream. Doing so would make the enclosed code redirect its standard output to the string stream.

An alternative way to build the intermediate list is the following, where iota is a small utility in the alexandria library:

(delete-if #'oddp (alexandria:iota 5))
=> (0 2 4)

In order to produce a string, you can also use FORMAT, which has a directive that can iterate over lists:

(format nil "~{~a~}" '(0 2 4))
=> "024"

The nil stream destination represents a string destination, meaning (format nil ...) returns a string. Each directive starts with a tilde character (~), ~{ and ~} enclose an iteration directive; inside that block, ~a prints the value "aesthetically" (not readably).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.