How do I undefine in Dr Racket?

racket

Solution

First of all, the behaviour is by design. Variables can not be mutated outside a module. This gives the optimizer a chance to, among other things, inline various things. See http://docs.racket-lang.org/guide/module-set.html for a detailed explanation.

If you need to modify something inside a module, the standard way of doing it, is to use a parameter.

Here is a quick hack (and I mean hack) that abuses parameters to make redefinitions possible.

To declare a function to be redefineable use `redefineable`. In this example a function `foo` is declared to be redefineable.

#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))

Now run the program, and in the interaction windows, we can now do as follow:

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

Problem

When building up some functions, I can make some mistakes. When this happens, I click RUN and have to re-enter all of the previous definitions and the new attempt. Is there some way to "undefine" the previous `(define (func args ...) body)` and just keep going?

Original source