Rebol 中 #[datatype] 构造函数的用途是什么

Shi*_*eng 4 rebol rebol3

我刚刚在 Rebol 中遇到了这个语法来构造一些值:

>> #[email! "me@host.com"]
== me@host.com
Run Code Online (Sandbox Code Playgroud)

这似乎相当于

>> to email! "me@host.com"
== me@host.com
Run Code Online (Sandbox Code Playgroud)

和这个

>> #[string! "hello"]
== "hello"
Run Code Online (Sandbox Code Playgroud)

虽然出现这些错误:

>> #[integer! 1]
** Syntax Error: Invalid construct -- #[
** Near: (line 1) #[integer! 1]
>> #[decimal! 1]
** Syntax Error: Invalid construct -- #[
** Near: (line 1) #[decimal! 1]
>> #[string! 1] 
== [string! 1]
Run Code Online (Sandbox Code Playgroud)

我想知道这是做什么用的?它带来什么好处?

ear*_*arl 6

这种语法结构称为“构造语法”(另请参阅CureCode issues #1955)。它存在的理由是允许使用文字形式来表示无法直接表示的值。

\n\n

有两类主要情况需要构造语法。

\n\n
    \n
  1. 值(构造语法除外)没有单独的词汇形式,而是仅通过求值构造。
  2. \n
  3. 具有常规文字形式的值,但其中特定值是“特殊”的,因为该值不再可以直接写入。
  4. \n
\n\n

(1) 直接值表示的构造语法

\n\n

此类的一个突出示例是 object!。Rebol 对象通常使用诸如make object! [a: 42]. 这不是结果对象值的直接文字表示,而是在评估时(在 DO 方言中)创建预期对象值的代码。构造语法允许直接表示值:#[object! [a: 42]]。

\n\n

其他典型的例子是#[none!]and 有点不规则(结构语法方面)#[true]and #[false](注意缺少!)。了解eg#[none!]和之间的差异none将导致对 Rebol 语义的更深入理解(因此留给读者作为练习)。

\n\n

(2) 作为“逃逸机制”的构造语法

\n\n

这种情况的典型示例是反向 URL,例如您从 获取的值reverse http://stackoverflow.com。如果结果值被序列化为纯 URL!,序列化形式在语法上将不再有效:

\n\n
>> /moc.wolfrevokcats//:ptth\n** Script error: // does not allow unset! for its value2 argument\n
Run Code Online (Sandbox Code Playgroud)\n\n

构造语法为这种情况提供了转义机制:

\n\n
>> #[url! "/moc.wolfrevokcats//:ptth"] = reverse http://stackoverflow.com/\n== true\n
Run Code Online (Sandbox Code Playgroud)\n\n

这个特殊的例子也指出了一个有问题的情况:

\n\n
>> reverse http://stackoverflow.com/\n== /moc.wolfrevokcats//:ptth\n
Run Code Online (Sandbox Code Playgroud)\n\n

可以说,这个输出(由mold机生成)是错误的:显示的结果不是相应值的有效词汇表示。

\n\n

有一些错误跟踪此类问题的特定实例(例如CureCode issues #2010URL 的针对更通用解决方案的一项建议是在 MOLD 的某些变体中内置往返检查:每当加载非构造语法 MOLD 的结果导致值与原始值不同时,该 MOLD变体将退回到序列化到构造语法。

\n