2024状态 Clojure调查!中分享您的想法。

欢迎!请查看关于页面以获取有关此工作的更多信息。

+8票数
语法和读取器
编辑

问题

既然我必须在Clojure代码中这里那里包含一些JavaScript、XML和HTML,就必须转义引号,这可能相当令人烦恼且容易出错。当进行脚本处理和运行shell命令时,你可能会遇到棘手的转义情况。

解决方案

添加一个字符串字面量,可以适应包含任何类型的字符串,而无需转义。

建议

文本块

一些其他语言提供了一种名为文本块的特性,其中您可以使用三个或更多的引号编写字符串,此时所有字符都允许使用

(println """
         This " is allowed,
         and no need to escape it.
         """

文本块通常还带有其他功能,例如,第一个和最后一个换行符不是字符串的一部分。并且源代码中三重引号的位置界定引号中的行开始。因此,上述代码打印

This " is allowed,
and no need to escape it.

而不是

         This " is allowed,
         and no need to escape it.

虽然文本块在视觉上很整洁,因为它们在源代码中有很好的对齐。但它们依赖于空白,而Clojure到目前为止是一个不依赖于空白的语言,这意味着空白没有意义。我认为最好保持这种状态。因此,以下是接下来的两个建议。

原始字符串

有时没有“块”功能的文本块被称为原始字符串字面量

(println """This " is allowed,
and no need to escape it.
Also support multi-line, but
not the "block" style of text blocks.""")

因此

(println """
         This " is allowed,
         and no need to escape it.
         """

打印

         This " is allowed,
         and no need to escape it.

与文本块不同。

如果您需要三重引号,只需将分隔符改为四重引号即可

""""This """ is now allowed as well.""""

原始字符串的问题在于,如果您使用双引号作为分隔符

""This is a raw " string!""

但想在开头或结尾处使用单引号

"""{{hello}}"""

我想让字符串变成"{{hello}}",而不是{{hello}},但原始字符串无法区分这两者,因为它现在认为这是一个三重引号的分隔符。

一个解决方案是允许在开始处或结尾处使用转义引号

""\"{{hello}}\"""

但不放在中间

""\"{{he\llo}}\"""

这个字符串是:"{{he\llo}}"

因此,转义字符\可以出现在除引号开头(如果后面紧跟一个引号)以外的任何位置,结尾处如果紧跟一个引号也可以。

我还是找不到这个理想。规则太多,仍然存在需要转义的情况。

未转义的字符串(我最喜欢的)

这里的想法是允许任何字符串作为分隔符。因此,对于我们要嵌套在Clojure代码中的任何可能的字符串,我们总能找到一个不是包含它的字符串来用作分隔符。

假设加入了#text读取器宏,它期望以下形式是一个常规字符串,用于告诉它读取以下形式的分隔符。

(println #text "|" |"{{hello}}"|)

将会打印

"{{hello}}"

#text的第一个参数告诉它以下原始字符串应该用的分隔符。这样,你绝对不必在原始字符串内使用转义序列。对于任何给定的字符串,你都可以找到不包含它的分隔字符串来正确处理它。

我关于这种方法的一个疯狂的想法,仅在此处抛砖引玉,是如果你使用足够随机的字符串作为分隔符,这可能是一种奇特的注入形式保护方式。

(println #text "xIBgdSl4TCCOIdqdMu9G" xIBgdSl4TCCOIdqdMu9G
Can't nobody guess the delimiter to escape the string context :p
xIBgdSl4TCCOIdqdMu9G)

谢谢

3 答案

+1

这已经被要求过,也被拒绝过几次,我认为这里没有新论点。

嗯,我首先尝试搜索过。找不到任何东西。我受到即将到来的Java JEPs关于它的启发:https://openjdk.java.net/jeps/355https://openjdk.java.net/jeps/326
如果您搜索“原始字符串”、“字符串字面量”、“here dol”、“多行注释”等,在Clojure和Clojure-dev谷歌邮件列表中有很多讨论。

旧设计页面: https://archive.clojure.org/design-wiki/display/design/Alternate%2Bstring%2Bquote%2Bsyntaxes.html

我认为我应该将“拒绝”改写为“缺乏兴趣”;我认为Rich通常认为这类事情有很多细微的复杂性(尤其是对于工具),但收益相对较低。
by
不使用三引号方法的一个论点是,这已经是合法的Clojure代码。

用户=> (println """
这已经是有效的Clojure代码
""")
 
这已经是有效的Clojure代码
 
nil
用户=>

这不意味着您想要的,但今天它是有效的,尽管我怀疑没有真正的代码这样做)
by
好吧,我承认我只搜索了Google,没有特别搜索邮件列表 :p。

我没有想到文档字符串是一个用例,但这同样是一个很好的用例。

关于这可能会带来的工具复杂性的观点是很好的。解析heredoc或类似的内容可能更困难。

此外,如果你看一下Ruby、Perl和Python,你会发现似乎没有人能就如何正确做这件事达成一致,而且三者最终都支持多种方式。

说到不值得为工具付出努力。实际上,工具也可以解决这个问题。不是为了文档字符串用例,而是为了我的片段用例。我知道在IntelliJ中有一个模式,它会为你打开另一个缓冲区,你可以随意输入内容,它会自动将你输入字符串中的内容Java转义。也许我也会为Emacs开发类似的功能。
by
@sean 良好的提醒。无论是什么解决方案,我个人倾向于使用读取器标签。所以 #s """ """ 或者类似的东西。这将解决这个问题。
댓글쓴이
Java 15도 이 기능을 도입했습니다({- 컴파일러 전용 기능이므로 Clojure 구현에 관련이 없지만 -}, 하지만 아마도 해결 공간이 조금 더 커졌을 것입니다).

"원시 문자열"(raw strings)을 의미하며, 열리더 규약어를 함께 사용하면 현재 누구도 신경 쓰지 않는 문제가 많은 많은 것을 할 수 있습니다.
+1
댓글쓴이

현재 상태의 긍정적인 점을 보면, XML과 HTML을 텍스트로 처리하는 것이 언제나 Clojure사용자에게 큰诗经을 가져왔습니다. 잘못된 출력, 주입, 치밀한 변환, 올바른 정확성을 평가하기 어려운 코드 등이 그 예입니다.

Clojure는 데이터(어떻게 string이 될까요?)에 근거한 전통 덕분에 신뢰성 있는 소리를 듣고 있습니다. "Hiccup"과 "clojure.xml" 전통은 HTML과 XML 처리에 매우 효과적이고(대부분의 경험에 따르면) 실행 시간에 저렴하게 증명되었음을 알 수 있습니다. 코드에 블로브를 심어서는 안 될 것이라는 thing은 기쁜 effect를 가져왔습니다. 여기에 블로브가 있다면, possible opportunity에서 Enlive 등을 사용하여 파싱하고 데이터 구조로 처리할 수 있습니다.

자바스크립트는 조금 떨어질지 모른다. 이해하기 쉽게 시작해보세요? ClojureScript을编码하면, 동일한 라우팅(p)에서 cljs 파일과 동일한 경로를 통해 메모리를 가져올 수 있는 단축규약을 사용할 수 있습니다.

요약하면, Clojure는 코드에 HTML과 XML 레터얼을 내장하고 조정하는 것을 피하는 것이 좋다고 생각합니다. 나중에 누락된 기능으로 보일지 모르지만, 이렇게 하지 않은 것은 Clojure 코드의 신뢰성에 큰 이익을 끌어다줍니다.

댓글쓴이
Потрясающая точка зрения. И для HTML и XML я согласен. Вдохновение у меня появилось при肾脏補充渲染 и необходимости включения JavaScript в мой Hiccup.

Действительно, я wonder whether CLJS можно использовать таким образом, но думаю, что можно. Если это было так, это было бы действительно вопрос.
+1

再次展示

你好,

我认为也应支持将此功能添加到clojure中。在我看来,支持类似样式组件https://styled-components.npmjs.net.cn/是一个很好的用法案例。

const Button = styled.a`
  /* This renders the buttons above... Edit me! */
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  background: transparent;
  color: white;
  border: 2px solid white;

  /* The GitHub button is a primary button
   * edit this to target it specifically! */
  ${props => props.primary && css`
    background: white;
    color: palevioletred;
  `}
`

上述代码的主要优点是大多数情况下是纯CSS,不需要转换为Clojure。

在Clojure中添加原始字符串/区块文本是否有问题?是的。
我们来讨论一下这个问题,看看我们能走到哪一步。

是否有办法以类似于现在Java JEP的开发方式来实验Clojure的特性——拥有预览版本以供探索和改进,直到最终确定并添加到核心中?https://openjdk.java.net/jeps/326

我对Clojure比较新,不太熟悉这个语言及其所有的历史和传统。但我喜欢挑战传统,因为世界在变化。使我们的做事方式变得有意义的理由现在可能不再成立。

Clojure没有类似Java JEP的过程。如果Rich Hickey对某个特性不感兴趣,则他不会将其作为Clojure官方版本的一部分。

世界上任何人都可以创建自己的本地源代码更改并使用它,如果他们愿意。我听说有些组织运行修补过的Clojure版本以供自用。

向您的本地Clojure副本添加此类功能将相对简单。但这并不能帮助在分布式Clojure程序中使用该功能,因为没有使用Clojure官方版本的人能够编译和运行使用新功能源代码。
我也希望Clojure中有文本块。
我的用例是嵌入其他编程语言,例如Python。

“文本块”是这方面的一个要求,如果不是引号问题也太烦人了。
...