Al construir algunas funciones, puedo cometer algunos errores. Cuando esto sucede, hago clic en EJECUTAR y tengo que volver a ingresar todas las definiciones anteriores y el nuevo intento.

¿Hay alguna forma de "anular la definición" del (define (func args ...) body) anterior y seguir adelante?

2
No One in Particular 28 may. 2012 a las 22:47

1 respuesta

La mejor respuesta

En primer lugar, el comportamiento es por diseño. Las variables no se pueden mutar fuera de un módulo. Esto le da al optimizador la oportunidad de, entre otros cosas, varias cosas en línea. Consulte http://docs.racket-lang.org/guide/module-set. html para una explicación detallada.

Si necesita modificar algo dentro de un módulo, la forma estándar de hacerlo es usar un parámetro.

Aquí hay un truco rápido (y me refiero a un truco) que abusa de los parámetros para hacer posibles las redefiniciones.

Para declarar que una función es redefinible, use redefineable. En este ejemplo, una función foo se declara redefinible.

#lang racket

(define-for-syntax (make-current-name stx id)
  (datum->syntax 
   stx (string->symbol
        (format "current-~a" (syntax-e id)))))

(define-syntax (redefine stx)
  (syntax-case stx ()
    [(_ (name arg ...) body ...)
     (with-syntax ([current-name (make-current-name stx #'name)])
       #'(current-name (lambda (arg ...) body ...)))]))

(define-syntax (redefineable stx)
  (syntax-case stx ()
    [(_ name)
     (with-syntax ([current-name (make-current-name stx #'name)])
       #'(begin
           (define current-name (make-parameter (λ x (error 'undefined))))
           (define (name . xs)
             (apply (current-name) xs))))]))

(redefineable foo)

(redefine (foo x) (+ x 1))

Ahora ejecute el programa, y ​​en las ventanas de interacción, ahora podemos hacer lo siguiente:

Welcome to DrRacket, version 5.3.0.6--2012-05-11(9401a53/a) [3m].
Language: racket.
> (foo 41)
42
> (redefine (foo x y) (* x y))
> (foo 2 3)
6
4
soegaard 28 may. 2012 a las 23:51
Muy dulce. Entiendo su advertencia y no haría cosas como esta en un entorno de producción, pero quería ahorrarme algo de acción del mouse y copiar y pegar.
 – 
No One in Particular
28 may. 2012 a las 23:57