反引号符号列表以句号结尾

时间:2019-10-20 05:46:13

标签: common-lisp symbols

我很好奇是否有一种方法可以在逗号插入值后面加上句点来结束用反引号引起的符号列表。

这是示例代码:

(defparameter *things* '(book pencil shoe))
(defun inspect-item (item things)
    (if (member item things)
        `(you pick up the ,item and yeet it out the window.)
        `(only realize the truth... there is no ,item.)))

此操作将在(print (inspect-item 'book *things*))之后,并产生符号列表(YOU PICK UP THE BOOK AND YEET IT OUT THE WINDOW.)。在这种情况下,我假设句点是符号WINDOW.的一部分(已使用最后一个函数确认)。

但是,(print (inspect-item 'spoon *things*))声称变量ITEM.没有值(因为它认为名称为item.)将失败illegal end of dotted list。在项目和句点之间留一个空格会产生错误BOOK.,我认为这是因为假设我正在使用点列表语法。

有什么办法让它产生我想要的符号结尾(Json 1: Key Value identifier 1111 Y 1 2222 N 1 3333 Y 2 4444 N 1 JSON2: ID name address zip mobile 1111 SRI Guntur 522438 999999 2222 Ravi Medikonduru 522238 888888 5555 kavitha Goa 789889 777777 4444 power SAP 827736 666666 Result: ID name address zip mobile Value 1111 SRI Guntur 522438 999999 Y 2222 Ravi Medikonduru 522238 888888 N 4444 power SAP 827736 666666 N )?

3 个答案:

答案 0 :(得分:4)

解决方案的可能要求

您需要在旧符号的基础上创建一个新符号:

  • 同名,后接.
  • 可能在同一包装中

句号

请注意,您可以使用转义符号|.|\.来写一个以句点作为名称的符号。

CL-USER 17 > (let ((item 'foobar))
               `(only realize the truth... there is no ,item \.))
(ONLY REALIZE THE TRUTH... THERE IS NO FOOBAR \.)

princ打印时没有转义字符:

CL-USER 18 > (princ '(ONLY REALIZE THE TRUTH... THERE IS NO FOOBAR \.))
(ONLY REALIZE THE TRUTH... THERE IS NO FOOBAR .)       ; <- printed output
(ONLY REALIZE THE TRUTH... THERE IS NO FOOBAR \.)      ; <- REPL value

解决方案

CL-USER 19 > (defun add-suffix (symbol suffix)
               (intern (concatenate 'string
                                    (symbol-name symbol)
                                    (symbol-name suffix))
                       (symbol-package symbol)))
ADD-SUFFIX

CL-USER 20 > (let ((item 'tree))
               `(we went to the ,(add-suffix item '|.|)))
(WE WENT TO THE TREE.)

使用format的灵活性而不是使用concatenate也很有用。

CL-USER 22 > (defun add-suffix (symbol suffix)
               (intern (format nil "~a~a" symbol suffix)
                       (symbol-package symbol)))
ADD-SUFFIX

答案 1 :(得分:3)

我认为真正的问题在于尝试生成文本,就像生成符号列表一样。这些是完全不同的东西。这样做的唯一原因可能是某种锻炼。有很多介绍性的文字可以做这种事情。

相反,我建议实际产生文本。 e。字符串。您可以使用format函数,该函数在插入变量时非常灵活:

(defparameter *things* '("book" "pencil" "shoe"))

(defun inspect-item (item things)
  (if (member item things :test #'string-equal)
      (format nil
              "You pick up the ~a and yeet it out the window."
              item)
      (format nil
              "Only realize the truth… there is no ~a."
              item)))

答案 2 :(得分:1)

我部分同意Svante的观点,即将符号列表转换为文本通常是错误的事情。另一方面,解析器&c之类的东西经常想用符号而不是字符串来思考,因为符号具有不错的属性,例如(eq a b)以您希望的方式工作。

话虽这么说,这是另一种方法:创建单词列表,然后具有将它们变成代表句子的字符串的功能,并添加适当的标点和大写字母。

(defparameter *things* '(book pencil shoe))

(defun inspect-item (item things)
  (sentencify (if (member item things)
                  `(you pick up the ,item and yeet it out the window)
                `(only realize the truth... there is no ,item))))

(defun sentencify (slist &key (question nil))
  (format nil "~{~A~^ ~}~A"
          (loop for first = t then nil
                for w in slist
                for ws = (typecase w
                           (symbol (symbol-name w))
                           (string w)
                           (t w))
                collect (typecase ws
                          (string (if first
                                      (string-capitalize ws)
                                    (string-downcase ws)))
                          (t ws)))
          (if question "?" ".")))

现在:

> (inspect-item 'book *things*)
"You pick up the book and yeet it out the window."

> (inspect-item 'bok *things*)
"Only realize the truth... there is no bok."

> (inspect-item '(x . y) *things*)
"Only realize the truth... there is no (x . y).