【问题标题】:make-symbol added unwanted formatting to generated symbolsmake-symbol 为生成的符号添加了不需要的格式
【发布时间】:2014-02-21 23:09:12
【问题描述】:

我正在尝试编写一个函数primeify,它接受一个符号并返回附加了“-prime”的符号。我想要的输出是:

[1] > (primeify 'y)
Y-PRIME

(或y-prime,此案不是这里的重点,尽管稍后可能会变得相关)。

这是我当前的(错误的)实现:

(defun primeify (sym)
     (make-symbol (concatenate 'string (string sym) "-prime")))

但是,make-symbol 通过使用其他格式将其弄乱,从而破坏了输出。我的输出是:

[1]> (primeify 'y)
#:|Y-prime|

有什么方法可以避免make-symbol 完成的额外处理,或者我可以使用其他函数来完成此操作吗?这甚至可以在 lisp 中完成吗?

【问题讨论】:

  • 你需要先将字符串大写
  • @VsevolodDyomkin 那删除了条(||),但是有什么办法可以删除#:
  • 如果你想要当前包中的符号,你需要使用intern,而不是使用make-symbol获得的uninterned symbol
  • 最重要的是,不是 make-symbol 在符号名称中添加任何内容,而是 Lisp 打印机 does these things 在打印符号时。例如,如果你切换到一个不导入符号的包,你会看到<package-name>:<symbol-name>(或者如果它没有被导出,则带有::)。 || 和 `` 在名称包含空格或小写/混合大小写字符时使用。

标签: lisp package common-lisp symbols


【解决方案1】:

你的符号:

#:|Y-prime|

这是一个非实习符号。它没有包装。正因为如此,#: 在符号前面。

也是大小写混合的符号名。因此,它用竖线转义。请记住,默认情况下,符号名称在内部以大写形式存储。

(defun primeify (sym)
  (let ((name (concatenate 'string
                           (string sym)
                           "-PRIME")))
    (if (symbol-package sym)
        (intern name (symbol-package sym))
      (make-symbol name))))

上述函数为新符号提供与原始符号相同的包(如果有)。

CL-USER 3 > (primeify 'foo)
FOO-PRIME
NIL

CL-USER 4 > (primeify '#:foo)
#:FOO-PRIME

【讨论】:

  • 为了在不同的设置下获得最一致的行为,我会使用(string '#:-prime)(symbol-name '#:-prime) 而不是"-PRIME"。实际上,这可能发生在阅读时,所以#.(symbol-name '#:-prime) 会很好。当然,这些设置总是会在运行时更改,因此没有万能的解决方案。
猜你喜欢
  • 2014-02-19
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 2020-07-05
  • 2012-10-12
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
相关资源
最近更新 更多