
Common Lisp Runtime Redefinition (2002) - brudgers
http://tiborsimko.org/common-lisp-runtime-redefinition.html
======
flavio81
What is even more amazing is to start a web server from the Lisp command line
(the "REPL"), and then change the definition of a function. The app will use
the new function without stopping and/or restarting. And this includes the
intermediate step of compiling the whole function!!

You can also update the definition of a class and then force all instances of
this class to use the updated definiton... all of this while the program keeps
running.

I always tell my friends to try some Common Lisp. The runtime environment is
rather amazing. The exception handling system ("condition" system) is also
another thing that is impressive on CL. It is so far beyond what Java (or C++)
brings to the table, that it isn't even funny to compare them.

~~~
stevekemp
I have the same discussion every few months, using FORTH as an example. I
guess there are a lot of environments where you can use this style of dynamic
updates - TCL, FORTH, Lisp, & etc.

~~~
blacksqr
Yes, with Tcl starting a server from an interactive interpreter and changing
function and class definitions on the fly is trivially simple.

I'm writing a Tcl web sever that uses Tcl's namespace features to change the
execution environment the client sees on a per-connection basis. Trivial.
Anybody else got that?

------
ScottBurson
Runtime definition (and redefinition) of functions was critical to the Lisp
Machine's usage model. Since the entire environment was a single Lisp session,
_everything_ happened at "runtime", including defining functions. Most
development, then, was done by interactively defining functions and trying
them out. It certainly was possible to compile a source file into a binary
file, and there were occasions when one had munged one's Lisp session to the
point that rebooting and reloading the binaries was required, though those
were relatively rare.

------
aidenn0
The combination of dynamicisim, speed, and general utility of the CL runtime
is unmatched anywhere except perhaps smalltalk.

With sbcl/slime, I can run a test, get instruction level profiling of the
disassembly, make a change and collect profiling data again without restarting
my program. The ability to go up and down the levels of abstraction all in the
same environment is unparalleled.

------
throwaway7645
Can you not redefine a method in Python's shell in the exact same method?

Edit: Ah...silly me, that isn't exactly runtime.

~~~
brudgers
Right. If I have the Python code to parallel the Common Lisp:

    
    
      import time                                                        
                                                                       
      def drill(n, f):                                                   
          for i in range(0, n):                                          
              f(i)                                                       
              time.sleep(1)                                              
                                                                       
      def gen(n):                                                        
          print(n)                                                       
                                                                       
      drill(10, gen)
    

I get:

    
    
      $> python3 interrupt.py
      0
      1
      2
      3
      ^CTraceback (most recent call last):
        File "interrupt.py", line 11, in <module>
          drill(10, gen)
        File "interrupt.py", line 6, in drill
          time.sleep(1)
      KeyboardInterrupt
      $>
    

The funny thing is though I've known it was possible to redefine running
Common Lisp code and I have seen the Continue option many times, it really
wasn't clear why it would be used and in part because it is mostly ignored in
descriptions of Common Lisp. I mean the behavior isn't described in the SBCL
User Manual. Nor is it really fleshed out in the Common Lisp HyperSpec
[http://www.lispworks.com/documentation/HyperSpec/Body/f_abor...](http://www.lispworks.com/documentation/HyperSpec/Body/f_abortc.htm)

~~~
tom_mellior
This isn't a very fair comparison as the Lisp code is shown running in the
REPL, not in some sort of release mode that, even in Lisp, would presumably
_not_ drop you into the REPL.

It's fairer to ask for interactive mode, in which you can redefine things and
restart your tests:

    
    
        $ python3 -i interrupt.py
        0
        1
        2
        ^CTraceback (most recent call last):
          File "interrupt.py", line 12, in <module>
            drill(10, gen)
          File "interrupt.py", line 7, in drill
            time.sleep(1)                                              
        KeyboardInterrupt
        >>> def gen(n):
        ...     print('{}!'.format(n))
        ... 
        >>> drill(10, gen)
        0!
        1!
        2!
        3!
        ^CTraceback (most recent call last):
          File "<stdin>", line 1, in <module>
          File "interrupt.py", line 7, in drill
            time.sleep(1)                                              
        KeyboardInterrupt
        >>>
    

What's magic about the Lisp version is not the "in debug mode, you get a REPL
and can redefine stuff" part. What's magic about the Lisp version is the "
_you can then continue the test where you left off_ " part. That's impossible
in Python because exceptions unwind the stack.

~~~
juki
Lisp doesn't really have separate release/debug modes[1]. When you want to
distribute a program as a binary, you dump the image and set a custom top-
level function to use instead of the default REPL. The program will still
contain the compiler/interpreter and can redefine everything just like during
development (altough the program might not use or expose those features to the
user). The REPL isn't in any way magical in Lisp; it's just the default option
for interacting with the Lisp.

[1]: You can ask the Lisp to drop all debug information as an optimization,
which makes development impractical, but still possible. Some implementation
might allow you to distribute a program without the compiler, but the standard
does not specify that.

~~~
lispm
Lisp doesn't have that in the language standards, but Lisp implementations
provide that. Lisp developers had the problem of shipping smaller
applications, shipping faster applications to end customers, targetting
systems where GC is problematic, or deploying on embedded systems.

Lisps with extensive image-based delivery support are for example Allegro CL
and LispWorks. Delivery here means also deep cuts into the software like
removing parts of the Lisp system (everything development relatied, unused
functionality, ...) and also removing parts of the program for the delivered
application. For example the running program might not need much of the
program's symbols. Functions would be called directly and not through symbols.

There are also compilers for application delivery (some are inhouse) which
generate self-contained C code. These then are compiled with the usual C
compiler and generate small static applications. An example would be mocl,
which can compile for Android, iOS and macOS platforms.

