LINUX.ORG.RU

Реализация векторов

 ,


0

2

Вектора не копируются в замыкания, насколько я понимаю, точней копируются, но по ссылкам. Они нарушают локальность.

(define chng (lambda(x) (vector-set! x 0 "foo")))
(define v '#(1 2 3))
(chng v)
(write v)
(newline)

;Для сравнения:

(define chng (lambda(x) (set! x 100)))
(define a 1)
(define l '(1 2 3))
(chng a)
(chng l)
(write a)
(newline)
(write l)

out:
#("foo" 2 3)
1
(1 2 3)

Почему так было сделано? Есть на это причины?

ЗЫ к слову, массивы в JS сделаны точно также.



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

Вектора не копируются в замыкания, насколько я понимаю, точней копируются, но по ссылкам.

В замыкания вообще всё копируется по ссылкам. Вектора не исключение.

Для списков сделай (define chng (lambda(x) (set-car! x 100))) и увидишь, что там тоже ссылка.

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

Че-то я не догоняю. В этом примере:

(define chng (lambda(x) (set! x 100)))
(chng a)
Если у нас в замыкании находится переменная а, а не ее значение - 1, то что же мешает set'у поменять ее значение вне замыкания?

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

Если у нас в замыкании находится переменная а, а не ее значение - 1

Тут не замыкание, а передача значения. Также как в (chng v) передаётся не переменная, а значение #(1 2 3)

(define chng
  (let ((x 1))
    (lambda() (set! x (+ x 1)) x)))

Вот здесь в замыкании переменная x.

> (chng)
2
> (chng)
3

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

И вообще в лиспах переменная в функцию всегда передаётся по значению.

monk ★★★★★
()

точней копируются, но по ссылкам

Што? Вектор _копируется_ _по ссылке_?

anonymous
()

SICP:

Lecture 5A - Assignment, State, and Side-effects

Lecture 5B - Computational Objects

- что, как, почему и зачем. И хватит уже тупняк разводить.

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

Тут не замыкание

В таком случае, как это понимать?

(define a 1)
(define chng (lambda(x) (set! x 100)))

(chng a)
(let ((x a)) (set! x 100))
((lambda(x) (set! x 100))a)
Все 3 последние выражения, по-идее, эквивалентны. Тогда последние 2 — это тоже не замыкания? То-есть let у нас не создает замыкания? Не всегда?

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

То-есть let у нас не создает замыкания? Не всегда?

(let ((var1 exp1) ...) body ...)

раскрывается в

((lambda (var1 ...) body ...) exp1 ...)

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

(define (make-counter init)
  ; в этом скоупе определена переменная init
  (lambda ()
    (set! init (+ init 1))
    init))

; а тут уже не определена
(define c1 (make-counter 0))
; c1 замкнута на свой скоуп, где определена переменная init
(c1)
; => 1
(c1)
; => 2
...

В твоем случае никакого дополнительного скоупа не создается, x — просто формальный параметр процедуры. Как в Си, Паскале, да и вообще практически в любом другом языке.

korvin_ ★★★★★
()
Последнее исправление: korvin_ (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.