[racket] changing source code with application still running

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Wed Oct 10 10:07:53 EDT 2012

Jay's answer is in principle correct but you can get close to what Graham did with a simple bit of planning. 

Instead of a web application, let's start with an interactive application: 

(define MY-PI 3)

(define (area-of-circle r)
  (* MY-PI r r))

(define (repl)
  (with-handlers ((exn? (lambda (x) "ready for repairs")))
    (displayln '(enter a number please: ))
    (let ([r (read)])
      (displayln `(the area of a circle with radius ,r is ,(area-of-circle r))))


It defines MY-PI according to the laws in Indiana, an area function, and then the 'server', an interactive repl. Here is how you fire up this application: 

[:Assignments/6/Foo] matthias% racket -i -f run_my_application.rkt

The -i key says you want an interactive version of Racket and the -f key tells racket to load the specified file. You could package this up as a shell script called run_my_application of course. Your customers walk up to the computer, enter numbers, and get results: 

[:Assignments/6/Foo] matthias% racket -i -f run_my_application.rkt
Welcome to Racket v5.3.0.24.
(enter a number please:)
(the area of a circle with radius 3 is 27)
(enter a number please:)

Now this guy is clever, probably someone from Illinois, and he notices that the area of this circle is way off. He calls you in, and you hit control-c to raise an exception, which kills the user's repl but puts you back into the Racket repl: 

  C-c C-c(ready for repairs)

Now you are back at the Racket prompt, and you can change things, e.g., you can set! MY-PI to something sensible (alternatively, fix the run_my_application file and load it): 

> (set! MY-PI 3.14)
> (repl)
(enter a number please:)
(the area of a circle with radius 3 is 28.259999999999998)
(enter a number please:)

After the fix you re-start the repl, and the user can continue -- et voilà a better result shows up. 

In addition, you could inspect the state of the program while you are at the Racket repl and see what the various variables hold now. You can inspect boxes and fields of objects and so on. 

In a web setting, you would run the server at the repl, enter the namespace of the user's program (login in as the user), fix the servlet, re-load the servlet, and the user would see on the spot. 

On Oct 10, 2012, at 9:25 AM, Daniel Bastos wrote:

> Here's a quote from Paul Graham --- quoting from
> http://bc.tech.coop/blog/040223.html.
> "When one of the customer support people came to me with a report of a
> bug in the editor, I would load the code into the Lisp interpreter and
> log into the users' account. If I was able to reproduce the bug I'd
> get an actual break loop, telling me exactly what was going wrong.
> Often I could fix the code and release a fix right away. And when I
> say right away, I mean while the user was still on the phone. "
> I have been trying to understand *how* this is done. I'd hope that
> this is also possible in Racket. But let me ask about the following
> specific situation.
> Say I have some application running. I told the shell
>     ./run_my_application &
> Now, while using it, I notice a bug somewhere. How do I change the
> code and see its new effect without shutting down and rerunning the
> application?
> Thank you.
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users

Posted on the users mailing list.