Ответ 1
Язык R обычно имеет семантику значений. Назначение x <- y
означает, что x
и y
будут независимыми копиями одного и того же объекта (обновления на y
и x
будут независимыми). Наивная реализация x <- y
всегда выделяет память для x
и полностью копирует y
в нее. Вместо этого GNU-R использует механизм копирования на запись, он откладывает копию до тех пор, пока не произойдет обновление, что экономит время памяти/времени выполнения, если это не произойдет. Пользователи R не должны знать об этой оптимизации, они полностью прозрачны (за исключением некоторых редких случаев, таких как ошибки из памяти). Этот механизм применяется к присваиванию, обозначенному как x <- y
и assign("x", y)
в равной степени.
Ленивая оценка является частью дизайна языка и видима для пользователей/программистов R. Выражения, переданные в качестве аргументов функции, например. в foo(ls())
переданное выражение ls()
оценивается лениво, только если и когда это необходимо для реализации вызываемой функции.
delayedAssign
- это низкоуровневая функция, видимая для пользователей/программистов R, но она действительно используется только для ленивой загрузки пакетов и не нужна в пользовательских программах. delayedAssign
позволяет указать выражение для вычисления значения переменной; вычисление будет происходить лениво, только если /, когда переменная читается в первый раз.
Итак, чтобы ответить на вопрос, назначение в R всегда "лениво" в том, что используется механизм копирования на запись. Вычисление правой части присваивания может быть также ленивым (с использованием delayedAssign
), но это не должно быть необходимо/использовано пользовательскими программами.
Я думаю, что для "переименования" переменных нет необходимости использовать delayedAssign
(потому что правая сторона не вычисляется). Это только усложняет ситуацию, и, скорее всего, из-за бухгалтерии delayedAssign
будет накладные расходы на производительность. Я бы просто использовал обычное задание, если мне пришлось переименовывать переменные.
Для ясности кода я также по возможности стараюсь избегать удаления переменных из среды и даже назначения из функции в глобальную среду, например. Я бы просто создал новый список и ввел в него новые привязки (переменные).
Упомянув механизм копирования на запись, с текущей реализацией в GNU-R, любое из описанных решений потенциально может вызвать копирование памяти, которое не было бы необходимо, если бы переменные не были переименованы. Невозможно избежать этого на уровне R.