LINUX.ORG.RU

Вопрос по call by value

 


1

2

а правильно ли я понимаю, что вот тут

https://ru.wikipedia.org/wiki/Стратегия_вычисления#.D0.92.D1.8B.D0.B7.D0.BE.D...

написана чушь?

Там утверждается, что *как правило* каждый раз происходит копирование

обычно посредством копирования этого значения в новую область памяти). При этом, если язык разрешает функциям присваивать значения своим параметрам, то изменения будут касаться лишь этих локальных копий, но видимые в месте вызова функции значения останутся неизменными по возвращении.

Версия для любителей плеваться на рупедию

Call-by-value evaluation is the most common evaluation strategy, used in languages as different as C and Scheme. In call-by-value, the argument expression is evaluated, and the resulting value is bound to the corresponding variable in the function (frequently by copying the value into a new memory region).

разберем на примере scheme, который приведен там в качестве примера, пошагово

(define (tst x) (write x) (set! x b) (write x))

(define a 1)
(define b 2)

(tst a)
;out: 12

1 (tst a) — вычисляем a; связываем значение a (1) с идентификатором x

2.(write x) — вычисляем x; выводим вычисленное значение x (1)

3. (set! x b) — вычисляем b; связываем значение (2) c идентификатором x.

4 Повторяем шаг 2

Какое копирование они тут увидели? ЕМНИП, копирования по-дефолту вообще никогда не происходит

Все то же самое и в других языках, с которыми я знаком.

Там действительно чушь написана, или я что-то не так понял? Какой вообще смысл может быть в копировании, в данном случае? Оно ведь ничего не даст, кроме оверхед по памяти, и дополнительной путаницы в коде.



Последнее исправление: ambiguousnick (всего исправлений: 1)

связываем значение a (1) с идентификатором x

т.е. копируем значение 1 в новый слот и связываем его с x.

guile> (define (tst x) (write x) (set! x b) (write x))
guile> (define a 1)                                   
guile> (define b 2)
guile> (tst a)
12
guile> a
1
guile> b
2

Т.е. изменение x не влияют на a - x содержит копию значения a.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)

тебе объяснили как «связывание» работает «под капотом». что не так?

anonymous
()

Лизни уже розетку от электроплиты, чмо нулевое.

anonymous
()
Ответ на: комментарий от no-such-file

т.е. копируем значение 1 в новый слот и связываем его с x.

что значит копируем? у тебя что идентификатор, что 1 в единственном экземпляре в программе находятся. Это линкование а не копирование.

ambiguousnick
() автор топика
Ответ на: комментарий от no-such-file

Т.е. изменение x не влияют на a - x содержит копию значения a.

Конечно не влияют, ведь мы не тронаем связку а -> 1. Копирование тут не при чем.

ambiguousnick
() автор топика
Ответ на: комментарий от anonymous

тебе объяснили как «связывание» работает «под капотом». что не так?

Не так то, что не может оно так работать. Есть подозрение, что пишущий соврал:)

ambiguousnick
() автор топика
Ответ на: комментарий от ambiguousnick

ведь мы не тронаем связку а -> 1

Без копирования:

a --+-> 1
x --|
И какая нахрен разница, что мы трогаем, если значение слота изменится при записи через x? После выполнения функции будет a=2.

Копирование:

a -> 1
x -> 1 (копия, создаваемая при входе в функцию)

no-such-file ★★★★★
()
Ответ на: комментарий от ambiguousnick

Зависит от языка. В схемке значение копируется. Возможно используется CoW, но это уже детали.

guile> (define a 1)
guile> (define b a)
guile> (set! b 2)
guile> a
1
guile> b
2

no-such-file ★★★★★
()
Ответ на: комментарий от ambiguousnick

это тоже *копирование*.

Всё копирование, кроме алиасинга, когда 2 переменные указывают на один слот и можно значение изменять через любую из них. Так работает жабка, например, или ссылки в крестах.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от ambiguousnick

что ты подразумеваешь под понятием «копирование»?

Создается новый слот, значение из старого слота копируется в новый.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Всё копирование, кроме алиасинга, когда 2 переменные указывают на один слот

Но в этом примере так оно и есть, у тебя 2 переменные указывают н одно и то же значение.

ambiguousnick
() автор топика
Ответ на: комментарий от no-such-file

Создается новый слот, значение из старого слота копируется в новый.

Ну. А в жанном случае, у тебя создается новый слот, который указывает на уже существующее значение. Не подходит твое определение под примеры, которые ты показал.

ambiguousnick
() автор топика
Ответ на: комментарий от ambiguousnick

который указывает на уже существующее значение

Слот никуда не указывает, он _содержит_ значение. Переменная указывает на слот.

no-such-file ★★★★★
()
Ответ на: комментарий от ambiguousnick

2 переменные указывают н одно и то же значение

Они указывают на разные слоты, но слоты имеют одинаковое значение, т.к. значение было скопировано.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Да, но есть разница между


slot1: <slot-name> - <the-value>
slot2: <slot-name> - <the-value>

где оба имени ссылаются на одно и то же значение

и

slot1: <slot-name> - <the-value>
slot2: <slot-name> - <copy-the-value>

где имена ссылаются на разные значения.

[/copy]

В первом случае никаких копий нет, у тебя только одно the-value. Какое это отношение имеет к копированию? У тебя оба идентификатора ссылаются на одно и то же. То что это разные слоты, никто не спорит, но копирование то тут причем?
ambiguousnick
() автор топика

анонiмус, ты?

anonymous
()
Ответ на: комментарий от no-such-file

Они указывают на разные слоты, но слоты имеют одинаковое значение, т.к. значение было скопировано.

они не указывают на разные слоты, они сами являются именами слотов. Это просто сахар, на JS это можно записать

global.a=1
global.b=global.a
тут, без сахара, видно, что a и b являются *именами в составе* слотов.

ambiguousnick
() автор топика
Ответ на: комментарий от no-such-file

а у меня два одинаковых значения в двух разных слотах.

Да. Это то же самое, что и я говорю. Там нет никаких копий. создание слота и линковка знчения никакого отношения к копированию не имеет.

ambiguousnick
() автор топика
Ответ на: комментарий от no-such-file

Я имею в виду, что это семантически эквивалентно, просто в схеме это подковерная возня, а в JS можно записать явно.

ambiguousnick
() автор топика
Ответ на: комментарий от ambiguousnick

в JS можно записать явно

Конкретно в этом примере копирование кстати есть, но вообще в js как и в жабке объекты не копируются, а в схемке копируются.

no-such-file ★★★★★
()
Ответ на: комментарий от ambiguousnick

Пардон, лоханулся, в схемке тоже объекты не копируются, awww.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)

Я не понял, о чем тред. Все объясняют автору в чем разница между value и reference и почему в его языке a=1, b=a, b++, a==1.

ichi404
()
Ответ на: комментарий от ichi404

Второй тред о новом нике анонiмус-а, что не понятно-то?

Begemoth ★★★★★
()

А можешь на схеме круг нарисовать?

ovk48 ★★★
()

у тебя есть биндинг a, который ссылается на ячейку, в которой лежит 1. И есть биндинг b, который ссылается на ячейку с 2.

         +---+
[a] ---> | 1 |
         +---+

         +---+
[b] ---> | 2 |
         +---+

Далее, ты вызываешь функцию, которой передаешь a в качестве аргумента.

Если передача будет по ссылке, то будем иметь такую картину:

         +---+
[a] ---> | 1 |
         +---+
           ^
           |
[x] -------+

Если по значению, то такую:

         +---+
[a] ---> | 1 |
         +---+

         +---+
[x] ---> | 1 |
         +---+

Вот тут и происходит копирование. Вместо того, чтобы ссылаться на существующую ячейку, мы создаем еще одну точно такую же и копируем туда значение ячейки. Соответственно, set! перепишет значение в той ячейке, на которую указывает x, т.е. изменится копия, а оригинал не будет затронут. Потому ячейка, на которую указывает a изменяться не будет.

anonymous
()
Ответ на: комментарий от anonymous

Проблема в том, что случай

         +---+
[a] ---> | 1 |
         +---+

         +---+
[x] ---> | 1 |
         +---+

Изменяем ячейку, на которую указывает [x]

         +---+
[a] ---> | 1 |
         +---+

         +---+
[x] ---> | 2 |
         +---+
Никак не отличим от ситуации:
         +---+
[a] ---> | 1 |
         +---+
           ^
           |
[x] -------+

Изменяем биндинг [x] так, чтобы он указывал на новое значение:

         +---+
[a] ---> | 1 |
         +---+

         +---+
[x] ---> | 2 |
         +---+

И именно это имеет в виду ТС, как мне кажется.

anonymous
()
Ответ на: комментарий от ambiguousnick

у тебя что идентификатор, что 1 в единственном экземпляре в программе находятся.

нед, единица в двух экземплярах. Одна в а, другая - в х.

anonymous
()

Т Ы О П Я Т Ь В Ы Х О Д И Ш Ь Н А С В Я З Ь

Ы

О

П

Я

Т

Ь

В

Ы

Х

О

Д

И

Ш

Ь

Н

А

С

В

Я

З

Ь

anonymous
()
Ответ на: комментарий от anonymous

Но это ведь просто реализация. Концептуально разницы нет.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.