Идиоматический способ длинных многострочных констант (или переменных) в коде Лиспа

Каков идиоматический способ вставки длинных многострочных переменных или констант в код Common Lisp? Есть ли что-то вроде HEREDOC в оболочке unix или некоторых других языках, чтобы исключить отступы пробелов внутри строковых литералов?

Например:

(defconstant +help-message+ 
             "Blah blah blah blah blah
              blah blah blah blah blah
              some more more text here")
; ^^^^^^^^^^^ this spaces will appear - not good

И писать так как-то некрасиво:

(defconstant +help-message+ 
             "Blah blah blah blah blah
blah blah blah blah blah
some more more text here")

Как мы должны это написать. Если есть какой-то способ, когда вам не нужно экранировать кавычки, это будет еще лучше.


person coredump    schedule 09.10.2014    source источник


Ответы (3)


Не знаю насчет идиоматики, но format может сделать это за вас. (естественно. format может все.)

См. раздел Hyperspec 22.3.9.3, перевод строки с тильды. Неокрашенный, он удаляет как новую строку, так и последующие пробелы. Если вы хотите сохранить новую строку, используйте модификатор @:

(defconstant +help-message+
   (format nil "Blah blah blah blah blah~@
                blah blah blah blah blah~@
                some more more text here"))

CL-USER> +help-message+
"Blah blah blah blah blah
blah blah blah blah blah
some more more text here"
person Peder Klingenberg    schedule 09.10.2014
comment
Спасибо, это выглядит разумно. - person coredump; 09.10.2014
comment
@coredump А в случае постоянной строки вы можете использовать #. (как в ответе Райнера). - person Joshua Taylor; 09.10.2014

Такого нет.

Отступ обычно:

(defconstant +help-message+ 
  "Blah blah blah blah blah
blah blah blah blah blah
some more more text here")

Возможно, используйте макрос для чтения или оценку времени чтения. Эскиз:

(defun remove-3-chars (string)
  (with-output-to-string (o)
    (with-input-from-string (s string)
      (write-line (read-line s nil nil) o)
      (loop for line = (read-line s nil nil)
            while line
            do (write-line (subseq line 3) o)))))

(defconstant +help-message+
  #.(remove-3-chars
  "Blah blah blah blah blah
   blah blah blah blah blah
   some more more text here"))

CL-USER 18 > +help-message+
"Blah blah blah blah blah
blah blah blah blah blah
some more more text here
"

Потребуется больше полировки ... Вы можете использовать «струнную обрезку» или что-то подобное.

person Rainer Joswig    schedule 09.10.2014
comment
Год я думал о том, чтобы сделать подобный макрос, но он сломает все, если кто-то редактирует код в другом редакторе с другими настройками отступов. - person coredump; 09.10.2014

Я иногда использую эту форму:

(concatenate 'string "Blah blah blah"
                     "Blah blah blah"
                     "Blah blah blah"
                     "Blah blah blah")
person Elias Mårtenson    schedule 10.10.2014
comment
Это даст вам: Бла-бла-бла-бла-бла-бла-бла-бла-бла-бла-бла, без новых строк. - person coredump; 10.10.2014