Subject: Re: Several REPL attached to a single image
From: rpw3@rpw3.org (Rob Warnock)
Date: Wed, 21 Nov 2007 04:53:53 -0600
Newsgroups: comp.lang.lisp
Message-ID: <s92dnQNzVojck9nanZ2dnUVZ_t2inZ2d@speakeasy.net>
<rixed@apc.happyleptic.org> wrote:
+---------------
| I would like to have a lisp running somewhere and "connect"
| to it with several REPL. I've looked various (free) lisp implementations
| without finding anything close, so I don't know if it's feasable.
...
| (Note: if this rely on some particular implementation magic, Im using
| clisp or gcl or ecl, which are not the biggest, but because of that I
| managed to port them on my ARM "server", while neither sbcl, cmucl nor
| openmcl are portable)
+---------------

I'm sorry CMUCL isn't acceptable to you, since it comes with a built-in
function that does exactly what you want:

    cmu> (describe 'mp::start-lisp-connection-listener)
    START-LISP-CONNECTION-LISTENER is an internal symbol in the MULTIPROCESSING package.
    Function: #<Function MULTIPROCESSING::START-LISP-CONNECTION-LISTENER {10331281}>
    Function arguments:
      (&key (port 1025) (password (random (expt 2 24))))
    Function documentation:
      Create a Lisp connection listener, listening on a TCP port for new
      connections and starting a new top-level loop for each. If a password
      is not given then one will be generated and reported.  A search is
      performed for the first free port starting at the given port which
      defaults to 1025.
    Its defined argument types are:
      (&KEY (:PORT (UNSIGNED-BYTE 16)) (:PASSWORD T))
    Its result type is:
      T
    On Wednesday, 11/16/05 05:14:48 pm PST it was compiled from:
    target:code/multi-proc.lisp
      Created: Tuesday, 7/5/05 06:12:50 am PDT
      Comment: $Header: /project/cmucl/cvsroot/src/code/multi-proc.lisp,v 1.43 2005/07/05 13:12:50 rtoy Exp $
    cmu> 

You use it like this:

    cmu> (mp::start-lisp-connection-listener)

    #<Process Anonymous {4894FE5D}>
    cmu> 
    ;;; Started lisp connection listener on port 1025 with password 6600875

Then from anywhere in the world, you just Telnet to there, type the
password, and you're in a REPL, e.g.:

    $ telnet my-host-name 1025
    Trying [my-IP-address]...
    Connected to my-host-name.
    Escape character is '^]'.
    Enter password: 6600875       <== I typed the password

    cmu> (mp:all-processes)

    (#<Process Lisp session from [client-host-name] {48952B75}>
     #<Process Lisp connection listener on port 1025 {4894FE5D}>
     #<Process Initial {48008005}>)
    cmu> 

Note: The password is any readable CL *object*, so you can certainly
make *much* stronger password than a weak random 24-bit number
[a much longer string or symbol, for instance].

Note#2: Things are arranged so that if you call (QUIT) from one
of the remote REPL sessions, you kill *only* that session, not
the whole CMUCL image.

In any case, you might look for something similar in one of the
implementations you find acceptable, or if nothing exists already,
you could implement the above function signature yourself from
whatever network socket and thread primitives your implementation
does provide.

In case it helps, the source for CMUCL's START-LISP-CONNECTION-LISTENER
is ~90 lines of code, down near the bottom of this file:

    http://common-lisp.net/cgi-bin/viewcvs.cgi/*checkout*/src/code/multi-proc.lisp?root=cmucl

You'll also need a sample top-level REPL to call; the one CMUCL's
START-LISP-CONNECTION-LISTENER uses is called TOP-LEVEL, is ~30 lines
of code, and is in the same file just a little bit farther up.


-Rob

p.s. CMUCL *is* "portable" -- it runs on multiple platforms [albeit
fewer than in times past], and it had to be "ported" for that to happen.
But I agree that you need to be a fairly-competent compiler writer to
port CMUCL to a new architecture. It's certainly not as easy as just
recompiling a C program.

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607