LINUX.ORG.RU
Ответ на: комментарий от true_admin

Ну так не пиши чуши про «переменные» и пиши «объекты», когда ты подразумеваешь объекты.

В случае использования ссылки именно на объект поведение в python'е было бы в стиле ML'ей, а не схемы. То есть захват по значению.

aedeph_ ★★
()
Ответ на: комментарий от true_admin

Зачем - никогда не интересовался, просто запомнил, что переменные, к которым доступаются из разных кадров, хранятся в cell и вроде это артефакт реализации CPython. Если интересно - http://tech.blog.aknin.name/2010/06/05/pythons-innards-naming/

tailgunner ★★★★★
()
Ответ на: комментарий от aedeph_

В случае использования ссылки именно на объект поведение в python'е было бы в стиле ML'ей

...для иммутабельных объектов.

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

В общем стиле.

Standard ML of New Jersey v110.75 [built: Sun Dec 29 21:15:03 2013]
- val r = ref 0;
val r = ref 0 : int ref
- val f = fn x => x + !r;
val f = fn : int -> int
- f(1);
val it = 1 : int
- r := 10;
val it = () : unit
- f(1);
val it = 11 : int
aedeph_ ★★
()
Ответ на: комментарий от aedeph_

Кажется, я понял как это работает. Тьюплы-то иммутабельные. Когда ты «перезаписываешь» переменную надо пересоздавать тьюпл, или же обновить указатель у cell.

А мой вопрос был простой: почему бы вместо тьюпла не сделать какой-нить обычный сишный массив для хранения указателей на «внешние переменные». Тогда не нужны были бы эти cell objects. Предвижу вопрос на тему «а как получить доступ к этому массиву из питона». Сделать питоновскую обёртку. Чем не вариант?

cast tailgunner

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

Кажется, ты ничего не понял.

Куда будут указывать «указатели на ``внешние переменные``»?

aedeph_ ★★
()
Ответ на: комментарий от true_admin

Я не претендую на глубокое знание CPython, но вот мое понимание вопроса: когда один и тот же объект должен быть доступен из N стековых кадров, во все N помещаются cell со ссылками на один и тот же объект. Cell необходимы, потому что в стековом кадре могут хранится только Python-объекты. Cell необходимы не всегда, потому что объект, доступный только в одном кадре, можно положить прямо в этот кадр (без cell).

Но всё это нафиг не нужно для понимания лямбд %)

tailgunner ★★★★★
()
Ответ на: комментарий от aedeph_

дереференс переменной из определённого скоупа.

И чем это Тем, что ссылается не на объект.

отличается от ссылки на объект?

Еще раз: если верить документации, в Cell хранится ссылка на объект. Ты утверждаешь, что там хранится не ссылка. Тебе не кажется, что ты противоречишь документации?

Ты код-то запусти, не ломайся уж так сильно.

Да я запустил. Но выдача не проясняет твою мысль.

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

Если объект - это то, куда ссылается текущая переменная из замыкающего контекста, то следующий assignment должен перезаписать новый объект внутрь cell object'а.

По мне так жесть какая-то полная.

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

Если объект - это то, куда ссылается текущая переменная из замыкающего контекста

Замыкающего или объемлющего?

следующий assignment должен перезаписать новый объект внутрь cell object'а.

Я тоже примерно так понимаю.

По мне так жесть какая-то полная.

А по мне, довольно логично. Объект должен быть доступен из нескольких мест, в каждом месте хранится ссылка на него.

tailgunner ★★★★★
()
Ответ на: комментарий от aedeph_

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

arturpub ★★
()
Ответ на: комментарий от aedeph_

Почему жесть? Все контексты, включая родительский, держатся за один и тот же слот, это и обеспечивает распространение изменения. Когда обычной переменной что-то присваиваешь, тоже какой-то объект цепляется за локацию в стеке, а старый отцепляется и возможно разрушается. Тут только способ локации сменился с индекса в массиве на спецобьект, который вместе с фреймом не помрет.

arturpub ★★
()
Последнее исправление: arturpub (всего исправлений: 1)
Ответ на: комментарий от true_admin

Разные контексты имеют разные пересечения захватов, поэтому нельзя расшарить этот массив между всеми, вернее можно, но зачем. Как минимум лайфтаймы сломаются, ты же не знаешь какие индексы уже все.

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

Это самое правдоподобное объяснение, спасибо.

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