Как я могу передать переменную ссылкой в схеме?
Пример функциональности я хочу:
(define foo
(lambda (&x)
(set! x 5)))
(define y 2)
(foo y)
(display y) ;outputs: 5
Кроме того, есть ли способ возвратиться ссылкой?
См. http://community.schemewiki.org/?scheme-faq-language вопрос "Есть ли способ эмулировать call-by-reference?".
В целом, я думаю, что это противоречит функциональной природе схемы, поэтому, вероятно, есть лучший способ структурировать программу, чтобы сделать ее более похожей на схему.
лямбда!
(define (foo getx setx)
(setx (+ (getx) 5)))
(define y 2)
(display y)(newline)
(foo
(lambda () y)
(lambda (val) (set! y val)))
(display y)(newline)
Яри прав, передача по ссылке несколько несхема, по крайней мере, с переменными. Однако желаемое поведение используется и часто поощряется, все время более схематично, с использованием замыканий. Страницы 181 и 182 (книги Google) в проверенной схеме лучше, чем я, объясняют ее.
Вот ссылка на макрос, позволяющий использовать синтаксис, подобный c, для «передачи по ссылке». Сайт Олега - это золотая жила для интересных чтений, поэтому обязательно отметьте его, если вы еще этого не сделали.
Вероятно, вы слишком часто используете C, PHP или что-то еще. В схеме вы не хотите делать такие вещи, как pass-by-*. Сначала поймите, что означает область видимости и как ведут себя различные реализации (в частности, попытайтесь понять, в чем разница между LISP и Scheme).
По своей сути чисто функциональный язык программирования не имеет побочных эффектов. Следовательно, это означает, что pass-by-ref не является функциональной концепцией.
Как сказал Яри, обычно вы хотите избежать передачи по ссылке в Scheme, поскольку это предполагает, что вы злоупотребляете побочными эффектами.
Однако, если вы хотите, вы можете заключить все, что хотите передать по ссылке, в cons
box.
(cons 5 (void))
создаст блок, содержащий 5. Если вы передадите это поле процедуре, которая изменит 5 на 6, ваше исходное поле также будет содержать 6. Конечно, вы должны помнить о cons
и car
, когда это необходимо.
В Chez Scheme (и, возможно, в других реализациях) есть процедура под названием box
(и ее спутники box?
и unbox
) специально для этой чепухи с коробкой/разгрузкой: http://www.scheme.com/csug8/objects.html#./objects:s43