2010-07-16 17 views
8

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

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 una manera de volver por referencia?

+0

esquema es paso por valor – newacct

Respuesta

10

Ver http://community.schemewiki.org/?scheme-faq-language pregunta "¿Hay alguna manera de emular la llamada por referencia?".

En general, creo que lucha contra la naturaleza funcional del esquema, así que probablemente haya una mejor manera de estructurar el programa para hacerlo más similar a un esquema.

+0

Cool, gracias. Es bueno saberlo, pero parece que probablemente debería encontrar una forma mejor de hacer lo que estoy tratando de hacer :) – Cam

+6

Esa es una buena referencia al emular un argumento de "referencia" utilizando recuadros, y tenga en cuenta que el resultado de usar 'box',' unbox' y 'set-box!' está muy cerca de usar un puntero explícito en C. Además, es raro usar tal cosa, pero * puede * ser útil en algunas ocasiones - Scheme fomenta la programación funcional y desalienta la mutación, pero no tiene una objeción fundamental para hacerlo. (Pero en la mayoría de los casos es probable que el código de novato haga esto para reconsiderarlo). –

3

Como dijo Jari, generalmente quiere evitar pasar por referencia en Scheme ya que sugiere que está abusando de los efectos secundarios.

Si lo desea, puede incluir todo lo que desee pasar por referencia en un cuadro cons.

(cons 5 (void)) 

producirá una caja que contiene 5. Si pasa esta caja a un procedimiento que cambia el 5 a un 6, la caja original también contendrá un 6. Por supuesto, usted tiene que recordar a cons y car cuando sea apropiado.

Chez Esquema (y posiblemente otras implementaciones) tiene un procedimiento llamado box (y sus compañeros box? y unbox) específicamente para este boxeo/disparate unboxing: http://www.scheme.com/csug8/objects.html#./objects:s43

0

Es probable que tenga utilizar demasiada cantidad de C, PHP o lo que sea . En el esquema, no desea hacer cosas como pasar por *. Comprenda primero qué significa el alcance y cómo se comporta la implementación diferente (en particular, trate de descubrir cuál es la diferencia entre LISP y Scheme).

En esencia, un lenguaje de programación puramente funcional no tiene efectos secundarios. En consecuencia, significa que pasar-por-ref no es un concepto funcional.

2

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) 
+0

esto parece diferente de lo que la pregunta (por ejemplo, 'foo' toma dos argumentos, no uno) – gcbenison

2

Jari es correcto es algo unscheme-como para pasar por referencia, al menos con variables. Sin embargo, el comportamiento que desea se usa, y con frecuencia se fomenta, todo el tiempo de una forma más parecida utilizando cierres. Pages 181 and 182 (google books) en el esquema experimentado hacer un mejor trabajo que puedo explicarlo.

Aquí hay una referencia que proporciona una macro que le permite usar una sintaxis tipo c para 'pasar por referencia'. El sitio de Olegs es una mina de oro para lecturas interesantes, así que asegúrese de reservarlo si aún no lo ha hecho.

http://okmij.org/ftp/Scheme/pointer-as-closure.txt

1

Puede afectar a un contexto exterior desde dentro de una función definida en ese contexto exterior, que le da el efecto de 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 (definir x (casilla 5)), (unbox x), etc. como se menciona en un subcomentario de Eli, que es lo mismo que la solución contras sugerida por erjiang.

Cuestiones relacionadas