gpt4 book ai didi

r - R 中的修改时复制语义到底是什么?规范来源在哪里?

转载 作者:行者123 更新时间:2023-12-03 05:23:04 27 4
gpt4 key购买 nike

每隔一段时间,我就会遇到 R 具有修改时复制语义的概念,例如 Hadley's devtools wiki .

Most R objects have copy-on-modify semantics, so modifying a function argument does not change the original value

我可以将该术语追溯到 R-Help 邮件列表。例如,Peter Dalgaard 在 July 2003 中写道:

R is a functional language, with lazy evaluation and weak dynamic typing (a variable can change type at will: a <- 1 ; a <- "a" is allowed). Semantically, everything is copy-on-modify although some optimization tricks are used in the implementation to avoid the worst inefficiencies.

类似地,Peter Dalgaard 在 Jan 2004 中写道:

R has copy-on-modify semantics (in principle and sometimes in practice) so once part of an object changes, you may have to look in new places for anything that contained it, including possibly the object itself.

更进一步,在 Feb 2000 中罗斯·伊哈卡说道:

We put quite a bit of work into making this happen. I would describe the semantics as "copy on modify (if necessary)". Copying is done only when objects are modified. The (if necessary) part means that if we can prove that the modification cannot change any non-local variables then we just go ahead and modify without copying.

说明书上没有

无论我如何努力搜索,我都无法在 R manuals 中找到对“修改时复制”的引用。 ,都不在 R Language Definition 中也不在 R Internals

问题

我的问题分为两部分:

  1. 这在哪里有正式记录?
  2. 修改时复制如何工作?

例如,谈论“按引用传递”是否合适,因为 promise 被传递给函数?

最佳答案

按值调用

R Language Definition这么说(在 4.3.3 Argument Evaluation 部分)

The semantics of invoking a function in R argument are call-by-value. In general, supplied arguments behave as if they are local variables initialized with the value supplied and the name of the corresponding formal argument. Changing the value of a supplied argument within a function will not affect the value of the variable in the calling frame. [Emphasis added]

虽然这没有描述修改时复制的工作机制,但它确实提到更改传递给函数的对象不会影响调用框架中的原始对象。

其他信息,特别是关于修改时复制方面的信息,请在 R Internals manual 中的 SEXP 描述中给出。 ,部分1.1.2 Rest of Header 。具体来说,它指出[强调]

The named field is set and accessed by the SET_NAMED and NAMED macros, and take values 0, 1 and 2. R has a 'call by value' illusion, so an assignment like

b <- a

appears to make a copy of a and refer to it as b. However, if neither a nor b are subsequently altered there is no need to copy. What really happens is that a new symbol b is bound to the same value as a and the named field on the value object is set (in this case to 2). When an object is about to be altered, the named field is consulted. A value of 2 means that the object must be duplicated before being changed. (Note that this does not say that it is necessary to duplicate, only that it should be duplicated whether necessary or not.) A value of 0 means that it is known that no other SEXP shares data with this object, and so it may safely be altered. A value of 1 is used for situations like

dim(a) <- c(7, 2)

where in principle two copies of a exist for the duration of the computation as (in principle)

a <- `dim<-`(a, c(7, 2))

but for no longer, and so some primitive functions can be optimized to avoid a copy in this case.

虽然这没有描述对象作为参数传递给函数的情况,但我们可以推断出相同的过程在运行,特别是考虑到前面引用的 R 语言定义中的信息。

功能评估中的 promise

我认为将promise传递给函数的说法不太正确。参数被传递给函数,实际使用的表达式被存储为 Promise(加上指向调用环境的指针)。只有当参数被求值时,存储在 Promise 中的表达式才会在指针指示的环境中被检索和求值,这个过程称为强制

因此,我认为在这方面谈论“按引用传递”是不正确的。 R 具有按值调用语义,但会尝试避免复制,除非对传递给参数的值进行求值和修改。

NAMED 机制是一种优化(正如 @hadley 在评论中指出的那样),它允许 R 跟踪修改后是否需要进行复制。正如 Peter Dalgaard 所讨论的那样,NAMED 机制的具体运作方式涉及一些微妙之处(在 R Devel thread @mnel 在他们对问题的评论中引用)

关于r - R 中的修改时复制语义到底是什么?规范来源在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15759117/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com