Pregunta

¿Cómo puedo pasar una variable por referencia en el esquema?

Un ejemplo de la funcionalidad que quiero:

(define foo
  (lambda (&x)
    (set! x 5)))

(define y 2)

(foo y)

(display y) ;outputs: 5

Además, ¿hay alguna forma de devolverlo por referencia?

Otros consejos

Como dijo Jari, por lo general conviene evitar pasar por referencia en Scheme, ya que sugiere que estás abusando de los efectos secundarios.

Sin embargo, si lo desea, puede incluir cualquier cosa que desee pasar como referencia en un cons caja.

(cons 5 (void))

producirá una caja que contiene 5.Si pasas este cuadro a un procedimiento que cambia el 5 por un 6, tu cuadro original también contendrá un 6.Por supuesto, debes recordar cons y car cuando sea apropiado.

Chez Scheme (y posiblemente otras implementaciones) tiene un procedimiento llamado box (y sus compañeros box? y unbox) específicamente por esta tontería del boxeo/unboxing: http://www.scheme.com/csug8/objects.html#./objects:s43

Puede usar una macro:

scheme@(guile-user)> (define-macro (foo var)`(set! ,var 5))
scheme@(guile-user)> (define y 2)
scheme@(guile-user)> (foo y)
scheme@(guile-user)> (display y)(newline)
5

lambda!

(define (foo getx setx)
  (setx (+ (getx) 5)))

(define y 2)
(display y)(newline)

(foo
 (lambda () y)
 (lambda (val) (set! y val)))

(display y)(newline)

Jari tiene razón, es un poco de insasión, como pasar por referencia, al menos con variables.Sin embargo, el comportamiento que desea se usa, y a menudo se fomenta, todo el tiempo en un camino más similar al usar los cierres. páginas 181 y182 (Google Books) En el esquema sazonado hacen un mejor trabajo, entonces puedo explicarlo.

Aquí hay una referencia que le da una macro que le permite usar una sintaxis similar a C para 'pasar por referencia'.El sitio de Olegs es una mina de oro para lecturas interesantes, así que asegúrese de reservar la marca si aún no lo ha hecho.

http://okmij.org/ftp/scheme/pointer-as-cliendo.txt

Puede afectar un contexto externo desde dentro de una función definida en ese contexto exterior, lo que le brinda el efecto del pase por las variables de referencia, es decir, funciones con efectos secundarios.

(define (outer-function)
  (define referenced-var 0)
  (define (fun-affects-outer-context) (set! referenced-var 12) (void))
  ;...
  (fun-affects-outer-context)
  (display referenced-var)
)
(outer-function) ; displays 12

Esta solución limita el alcance de los efectos secundarios.

De lo contrario, hay (Define X (casilla 5)), (UNBOX X), etc., como se mencionó en un subcomment por ELI, que es el mismo que la solución CONS sugerida por ERJIANG.

Probablemente haya usado demasiado de C, PHP o lo que sea. En el esquema, no quiere hacer cosas como Pass-by- *. Entiendo primero qué significa alcance y cómo se comportan la implementación diferente (en particular, intente averiguar cuál es la diferencia entre Lisp y el Esquema).

Por esencia, un lenguaje de programación puramente funcional no tiene efecto secundario.En consecuencia, significa que el paso por refresco no es un concepto funcional.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top