【问题标题】:Why are there two assignment operators, `<-` and `->` in R?为什么 R 中有两个赋值运算符,`<-` 和 `->`?
【发布时间】:2019-01-03 22:54:52
【问题描述】:

我知道如何使用&lt;--&gt;,还有are several writeups 关于equals 赋值和箭头赋值之间的区别,但我不知道什么时候更喜欢@987654331 @以上&lt;-

似乎社区已经合并使用&lt;- 进行分配。

Google 的 R style-guide 和 Hadley Wickam 的 tidyverse R style-guide 都没有在作业部分提到 -&gt;

我很好奇导致 S/S-PLUS 开发人员输入右箭头分配运算符 -&gt; 的设计考虑因素。与&lt;-= 相比,在哪些设置中使用-&gt; 会被认为更具可读性(或更易于键入)?

我不熟悉任何其他允许右分配语义的语言。哪些语言在这方面启发了 R?

我正在寻找引用书籍/早期设计文档/用户手册/存档邮件列表或其他参考资料的答案,以确定 S 作者/设计师在使用前向箭头赋值运算符时的意图。

【问题讨论】:

  • 很遗憾,我之前的评论消失了,但我认为这是相关的:您链接的“好文章”不准确且具有误导性。可以在 Reddit 上找到对差异的正确解释:reddit.com/r/Rlanguage/comments/47c3z7/… — 如果有人对此评论有疑问,请告诉我为什么,而不仅仅是标记它.
  • 在这么短的时间内在这个线程中获得了这么多点,这是在哪里发布的?
  • @Moody_Mudskipper,最初在此处发布,未从子站点移至 SO。我敢打赌,很多人想知道为什么 R/S 如此古怪。我自己找不到任何参考资料,但谢天谢地,本的回答引用了 S. 的主要作者钱伯斯。
  • 我虽然是从博客或reddit之类的链接,但我只是好奇

标签: r language-design s


【解决方案1】:

来自新 S 语言(Becker、Chambers 和 Wilks 1988 年)中练习的答案,来自 Google 图书:

当您键入一个长表达式只是为了记住最后保存结果是个好主意时,右箭头允许您执行分配而无需重新键入行。

这表明 S 用户直接在控制台中工作,没有大多数现代 REPL/interactive 环境中可用的行编辑功能...


一些考古学:我在 Google 图书的基础资料中四处寻找。三本相关书籍:

  • 棕皮书:S:数据分析和图形的交互式环境 R. A. Becker,J. M. Chambers(CRC 出版社,1984 年)
  • 扩展 S 系统,Becker 和 Chambers(Taylor 和 Francis,1985 年)
  • 蓝皮书:新的 S 语言 Becker、Chambers 和 Wilks(Wadsworth 和 Brooks/Cole 1988 年,但 2018 年再版!!由 CRC Press)

    1. The Brown Book 在正文中没有提到-&gt;

但在附录中有:

  1. 扩展 S 系统在正文中提到了-&gt;

这本书我搜索不了太多,所以-&gt;可能还会在附录中的某个地方提到。

  1. 蓝皮书指的是右箭头,但实际上似乎有一个错字:

我将带下划线的红色段落解释为支持第一行有下划线的错字,应该是-&gt;而不是←...

这是上面提到的练习答案的截图:

如果您想要一本 1985 年的书,您可以以 34.41 美元或 1070.99 美元的价格购买(但免运费!)...

【讨论】:

  • 感谢您的回答。这种设计对于无法编辑行的交互式控制台非常有意义。当然,在发布这个问题之前,我什至没有考虑过 S 是在 70 年代开发的以及可用的当代硬件和软件。顺便说一句,我想知道谁会为Becker: Extending The S System 的副本支付 1,070.99 美元
  • 我还想知道使用&lt;- 的选择是否受到需要-&gt; 的影响。对于在没有向上箭头来浏览历史和允许编辑的控制台上工作的人来说,前进箭头解决了一个真正的问题。
  • 我听说/相信其他地方有记载,当时贝尔实验室使用的键盘有一个专用的左箭头键...
  • 信息丰富(+1)。您(或 Google 图书)有一个小错误,在应该是“Chambers”时使用了两次“Chamber”
【解决方案2】:

我认为这只是个人喜好问题。

虽然 -&gt; 早于 magrittr 管道,但最近的一个用例是 -&gt; 可用于在此类管道中保持从左到右的流动:

library(magrittr)
input %>% fun1 %>% fun2 -> result

另一方面,鉴于&lt;- 的使用频率最高,即使在这种情况下,您也可能希望使用&lt;-

&lt;- 的参数是它以设置的值开始行,这有点像语句的目的,特别是如果结果变量命名良好,而右侧是机制和因此,细节服从于结果——人们喜欢从概述开始,然后才进入细节。下面我们定义参数k。它是 3,或者它是由一个常量定义的,还是一个复杂的表达式,这似乎与语句的目的无关。

k <- 3

就我个人而言,我从不使用-&gt;

【讨论】:

  • &lt;- 的一个非常小的缺点是它的内部实现有点奇怪:str(quote(a-&gt;b)) 给出了language b &lt;- a,即解析器实际上在解析时翻转了表达式...跨度>
  • 另一点是&lt;- 可以更轻松地跟踪对象名称。如果您正在编写以-&gt; 结尾的表达式进行赋值,则您的对象名称将水平分散,而始终使用&lt;- 意味着每个对象名称都可以被可预测地定位。
  • 值得注意的是Tidyverse style guide 表示在使用管道时不要使用-&gt;
  • @Mako212 当场。事实上,它对代码质量有害。让你的副作用(=赋值)可见,不要在行尾隐藏它们。
【解决方案3】:

我无法推测 R 允许从左到右赋值的原因。 大多数编程语言(实际上几乎所有)只执行从右到左的赋值,这确实是事实。

也就是说,R 并非完全独立。

我不熟悉任何其他允许右分配语义的语言。

我能想到至少三种其他(家族)语言允许它:

  • 汇编语言经常执行从左到右的赋值;例如,有影响力的 AT&T 语法是这样写赋值的:

    movl $1, %eax
    

    这会将值 1 分配给 EAX 寄存器。 (另一方面,英特尔的 x86 语法执行从右到左的赋值。)

  • TI-BASIC 的 STO(“存储”)操作是这样写的:

    1→A
    
  • COBOL 使用多种形式的从左到右赋值:

    MOVE 1 TO x
    ADD 2 TO x
    

    等等

然而,我怀疑这些语言中是否有任何一种是 R 赋值语法的灵感来源。相比之下,APL 编程语言使用箭头赋值,人们普遍认为 S(因此间接地是 R)从 that 中获得灵感;但 APL 只执行从右到左的赋值 (var ← value)。

【讨论】:

  • 也是 POP-2。 POP-2 使用显式堆栈;所以这将是合法的:str.len; f(n+1); 'A' -&gt;Z -&gt;Y -&gt;X 将 str.len 分配给 X,假设 f() 返回单个结果。更常见的是,一个函数会返回多个结果,就像在 Lua 中一样。
【解决方案4】:

R 旨在具有一种用于表达数学的相当自然的语法。有趣的是,-&gt; 实际上是在矩阵上描述一些elementary row operations 的常用符号。例如,s*R_i -&gt; R_i 将用于表示将第 i 行替换为 s 次第 i 行的操作。 2*A[1,] -&gt; A[1,] 之类的东西是完全有效的 R。我不知道这些考虑是否与设计决策有关,但它确实表明它是数学语言的合理选择。

【讨论】:

  • 这很有趣,但 R 实际上并没有让我觉得 R 是一种试图使矩阵运算语法自然的语言。与 Matlab 相比,R 的矩阵语法是正向卷积的。
  • @KonradRudolph 我同意它的语法没有针对矩阵进行优化 (%*% ??),但 R 仍然是一种易于数学家使用的数学编程语言。 S 和 R 最初的 3 位主要开发者(Chambers、Ihaka 和 Gentleman)都拥有数学或统计学博士学位。对于接受过此类培训的人,在线性代数中既定使用箭头将使&lt;--&gt; 成为分配的自然选择。我的背景也是数学,当我第一次看到它时,我喜欢 &lt;-。尽管我不使用-&gt;,但它总是让我觉得很舒服。
猜你喜欢
  • 2015-12-25
  • 2010-12-17
  • 2014-03-23
  • 2013-11-26
  • 2018-04-20
  • 2015-12-14
相关资源
最近更新 更多