From: Dave Fayram
Subject: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <38ff3d6c.0403261516.1464d7fc@posting.google.com>
Hello folks, this is my first message here. I'm a relatively new lisp
user, and I've been enjoying my time with it. I like it so much, I'm
doing a just-for-fun project with it, but my reach is exceeding my
grasp a little here.

I am writing what is essentially a kind of text-based BBS. I let
people connect, handle their input, and have it call functions. It
starts by being a chatroom, but there are multiple modes that you can
place yourself into (which can stack).

One thing I'd like to do is let people actually write their own
features. I am already on the cusp of having a small meta-language
just for handling input and creating output quickly. But, since
everything runs in one lisp instance, I am a little worried. How can I
make sure that if they make a mistake, they don't trash the whole
system for everyone?

Is this possible? I mean, unwind-protect obviously, but I'd also like
to be more aggressive and make sure someone doesn't
common-lisp-user:quit the darn thing. My first thought is to put them
in a custom package, and make sure that package only uses a certain
set of packages that are relavant to writing and registering
functions. I worry about infinite loops and stuff like that though.

Is there any way I can guard against this? Is there a program in
existance that lets people extend the system from within the system,
as I am suggesting?

Or is my idea totally bad and bogus, and I should just not let them do
it? :)

From: ·······@noshpam.lbl.government
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <4pkr7vfvyrt.fsf@thar.lbl.gov>
·········@lensmen.net (Dave Fayram) writes:

> Is this possible? I mean, unwind-protect obviously, but I'd also like
> to be more aggressive and make sure someone doesn't
> common-lisp-user:quit the darn thing. My first thought is to put them
> in a custom package, and make sure that package only uses a certain
> set of packages that are relavant to writing and registering
> functions. I worry about infinite loops and stuff like that though.

1. If you find a general way to detect infinite loops in your
   end-user's code, please let us know. I'm sure you'll be a shoe-in
   for the Turing Award. :-)

2. If writing the SICP interpreter in CL isn't what you're looking
   for, try providing that to your end users through a separate thread
   or process. That way, it won't hose the invoking thread/process,
   and you can have it auto-load a library file of function & syntax
   definitions, which can mask all of the harmful stuff that your
   users would be otherwise able to access.

HTH,

~Tomer

-- 
()
From: Pascal Costanza
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <c43ru2$rv3$1@newsreader2.netcologne.de>
·······@noshpam.lbl.government wrote:

> ·········@lensmen.net (Dave Fayram) writes:
> 
>>Is this possible? I mean, unwind-protect obviously, but I'd also like
>>to be more aggressive and make sure someone doesn't
>>common-lisp-user:quit the darn thing. My first thought is to put them
>>in a custom package, and make sure that package only uses a certain
>>set of packages that are relavant to writing and registering
>>functions. I worry about infinite loops and stuff like that though.
> 
> 1. If you find a general way to detect infinite loops in your
>    end-user's code, please let us know. I'm sure you'll be a shoe-in
>    for the Turing Award. :-)

There are ways to avoid inifinite loops when you restrict the language 
that users are allowed to use. The straightforward way, of course, is to 
disallow any iteration/recursion constructs.

When you need recursion/iteration, you can make use of the notion of 
well-founded recursion. A well-founded recursion is a function for which 
you can prove that some value monotonically increases/decreases in some 
aspect, and there exists a limit for that value in the direction of 
increase/decrease. For example,

(defun mapcar (fun list)
   (if (null list) nil
       (cons (funcall fun (car list))
             (mapcar fun (cdr list)))))

...is a well-founded recursion, given that fun is also a well-founded 
recursion: The length of list decreases by 1 in each pass, and its 
length is at least 0. Many useful functions can be written that way.

See http://www.cs.utexas.edu/users/moore/acl2/ for a system built on top 
of Common Lisp that is built on that notion.


Pascal

-- 
1st European Lisp and Scheme Workshop
June 13 - Oslo, Norway - co-located with ECOOP 2004
http://www.cs.uni-bonn.de/~costanza/lisp-ecoop/
From: Cameron MacKinnon
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <dLadnaL60Y4haPndRVn-hg@golden.net>
Dave Fayram wrote:
> One thing I'd like to do is let people actually write their own
> features. I am already on the cusp of having a small meta-language
> just for handling input and creating output quickly. But, since
> everything runs in one lisp instance, I am a little worried. How can I
> make sure that if they make a mistake, they don't trash the whole
> system for everyone?
> 
> Is this possible? I mean, unwind-protect obviously, but I'd also like
> to be more aggressive and make sure someone doesn't
> common-lisp-user:quit the darn thing.

I'm inexperienced enough that my suggestions should be carefully 
scrutinized, so maybe someone else can comment on the following:

Use a code walker, which will recursively scrutinize the source 
s-expressions of your users' programs. Check every symbol in the car 
position of each sexpr against a list of allowed (or, alternatively, 
denied) functions. If the code passes muster, execute it, else tell the 
user what was forbidden.

You need a code walker instead of just a simplistic tree traversal 
bacause the code walker understands special forms and expands macros.

The paper I've been using to understand code walkers is Richard C. 
Waters' "Macroexpand-all: An Example of a Simple Lisp Code Walker"[1]
I can't recommend it as a complete introduction, as it deals with an 
early version of CL (CLtL1), and I can't quite get the code working; it 
contains things which CMUCL doesn't seem to understand, like:

	#,#'(lambda ...

But I think my idea is sound; you just need to find a simple code walker 
that works with your lisp, and make a simple modification in it to 
perform your required tests, as outlined above.

And *I* need pointers to better, more modern online resources about code 
walkers. Anyone? Please?

The above doesn't prevent hapless or malicious users from using too much 
CPU, but it stops pretty much all the other harmful stuff I can think 
of, except perhaps a user sending WAY too much code, giving your lisp 
image some nasty and painful bloating. But that's another, simpler fix.

[1] http://www.merl.com/papers/TR93-17/

-- 
Cameron MacKinnon
Toronto, Canada
From: Pascal Bourguignon
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <871xnfw1ei.fsf@thalassa.informatimago.com>
·········@lensmen.net (Dave Fayram) writes:

> Hello folks, this is my first message here. I'm a relatively new lisp
> user, and I've been enjoying my time with it. I like it so much, I'm
> doing a just-for-fun project with it, but my reach is exceeding my
> grasp a little here.
> 
> I am writing what is essentially a kind of text-based BBS. I let
> people connect, handle their input, and have it call functions. It
> starts by being a chatroom, but there are multiple modes that you can
> place yourself into (which can stack).
> 
> One thing I'd like to do is let people actually write their own
> features. I am already on the cusp of having a small meta-language
> just for handling input and creating output quickly. But, since
> everything runs in one lisp instance, I am a little worried. How can I
> make sure that if they make a mistake, they don't trash the whole
> system for everyone?
> 
> Is this possible? I mean, unwind-protect obviously, but I'd also like
> to be more aggressive and make sure someone doesn't
> common-lisp-user:quit the darn thing. My first thought is to put them
> in a custom package, and make sure that package only uses a certain
> set of packages that are relavant to writing and registering
> functions. I worry about infinite loops and stuff like that though.
> 
> Is there any way I can guard against this? Is there a program in
> existance that lets people extend the system from within the system,
> as I am suggesting?
> 
> Or is my idea totally bad and bogus, and I should just not let them do
> it? :)

Assuming you want to do it the most secure way, just implement your
own interpreter. Then you'll be able to control all actions. (For
example to avoid infinite loops, you can check time used or count
statement executed).

Check sicp for a good example of how to write a lisp interpreter in lisp.
http://mitpress.mit.edu/sicp/

-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: John Fraser
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <4di9c.3741$Td3.3254@nwrddc02.gnilink.net>
Pascal Bourguignon wrote:
> 
> Assuming you want to do it the most secure way, just implement your
> own interpreter. Then you'll be able to control all actions. (For
> example to avoid infinite loops, you can check time used or count
> statement executed).
> 
> Check sicp for a good example of how to write a lisp interpreter in lisp.
> http://mitpress.mit.edu/sicp/
> 

I agree, this would be the safest way.  You have complete control over 
an interpreter within your program.  You can ensure that it only has 
access to what you want it to have access to and you limit the number of 
  steps in its execution.

There are probably both minimal Scheme and CL interpreters written to 
run in CL.  Choosing of of these and extending it (or reducing it) would 
be easier than writing your own.  But, it would also be less fun.

Cheers,

John
From: Kenny Tilton
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <1O59c.7800$DV6.2582@twister.nyc.rr.com>
Dave Fayram wrote:

> Hello folks, this is my first message here. I'm a relatively new lisp
> user, and I've been enjoying my time with it. I like it so much, I'm
> doing a just-for-fun project with it, but my reach is exceeding my
> grasp a little here.
> 
> I am writing what is essentially a kind of text-based BBS. I let
> people connect, handle their input, and have it call functions. It
> starts by being a chatroom, but there are multiple modes that you can
> place yourself into (which can stack).
> 
> One thing I'd like to do is let people actually write their own
> features. I am already on the cusp of having a small meta-language
> just for handling input and creating output quickly. But, since
> everything runs in one lisp instance,...

Now that you have gotten some feedback laying out somewhat painful 
solutions, you might want to consider just fixing this, the Real 
Problem. You have not mentioned your environment, but you probably have 
socket support, and sorting those out to spread the action out over 
multiple processes eliminates a whole wadge of problems in one go.

Compared to writing your own interpreter /and/ designing the intepreted 
language /and/ documenting it... I'd learn sockets and how to connect 
users with their own lisp images.

kt
From: Dave Fayram
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <38ff3d6c.0403270045.4a06769b@posting.google.com>
> Now that you have gotten some feedback laying out somewhat painful 
> solutions, you might want to consider just fixing this, the Real 
> Problem. You have not mentioned your environment, but you probably have 
> socket support, 

As this is a distributed realtime communications system, yes, I do
have sockets. I'm using OpenMCL.

> and sorting those out to spread the action out over 
> multiple processes eliminates a whole wadge of problems in one go.

I said, it's essentially a very generic network service. However, it
connects multiple people in real time. I might eliminate the rather
awkward "Please don't loop me infinitely" problem, but then I have to
provide some kind of central service for them all to connect to to
distribute realtime messages, or use brutally inefficient IPC. Or,
maybe, I could used shared memory chunks.

The only reasonable idea among that lisp is to make Lisp instances
connect to a master server.

> Compared to writing your own interpreter /and/ designing the intepreted 
> language /and/ documenting it... 
> I'd learn sockets and how to connect 
> users with their own lisp images.
> 

I wish that were feasible. 

Honestly, I'm kind of surprised. You'd think this kind of idea would
be really useful. I know that "safe" execution of code was a really
useful feature in Ruby. I mean, using Lisp to extend a Lisp program
seems like a really natural idea. I'm not even so worried about
infinite looping because multi-threading will at least ameliorate that
problem. It's more that I don't want them redefining critical symbols
(like asg-process-event-loop, which reads from the socket) or
anything.

If there isn't a nice standard analog to Ruby's $SAFE, I'll probably
just not allow user scripting directly in Lisp.
From: John Fraser
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <M6i9c.3675$Td3.2784@nwrddc02.gnilink.net>
You could just write a taint-checked-eval.  Limit the Lisp they can use, 
provide a safe looping construct (via a macro of some sort), and taint 
check it before running it.  You can create a nice little sandbox for 
your users this way.

Perl also has a safe mode that is written in Perl.  Although separating 
Perl code from Perl internals is somewhat difficult, the principle 
works. The same can be said of Lisp.

Cheers,

John
From: Peter Seibel
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <m3isgqkfs7.fsf@javamonkey.com>
·········@lensmen.net (Dave Fayram) writes:

> Hello folks, this is my first message here. I'm a relatively new lisp
> user, and I've been enjoying my time with it. I like it so much, I'm
> doing a just-for-fun project with it, but my reach is exceeding my
> grasp a little here.
>
> I am writing what is essentially a kind of text-based BBS. I let
> people connect, handle their input, and have it call functions. It
> starts by being a chatroom, but there are multiple modes that you can
> place yourself into (which can stack).
>
> One thing I'd like to do is let people actually write their own
> features. I am already on the cusp of having a small meta-language
> just for handling input and creating output quickly. But, since
> everything runs in one lisp instance, I am a little worried. How can I
> make sure that if they make a mistake, they don't trash the whole
> system for everyone?
>
> Is this possible? I mean, unwind-protect obviously, but I'd also
> like to be more aggressive and make sure someone doesn't
> common-lisp-user:quit the darn thing. My first thought is to put
> them in a custom package, and make sure that package only uses a
> certain set of packages that are relavant to writing and registering
> functions. I worry about infinite loops and stuff like that though.

Instead of trying to lock down all of Common Lisp, it might be more
straightforward to build up exactly what they need. Use READ to read
s-expressions from them but don't EVAL them--translate them from your
own mini language to real Lisp and EVAL that. That way you have total
control over what code they can actually write. (I.e. if there's no
symbol that you translate to COMMON-LISP-USER:QUIT, then there's no
way for them to call it.) If you're language is rich enough, you'll
still have the problem that there's no way to know, for instance,
whether their program will ever quit. But you can even do some tricks
there. For instance suppose you supply a DO loop like construct they
might write:

  (defun foo ()
    (do () () (burn-cpu)))

But you might translate that to:

  (defun foo ()
    (do ((iterations 0 (1+ iterations)))
      ((> iterations *max-iters*)
       (when (> iterations *max-iters*)
         (error "Bang you're dead: too many iterations.")))
      (burn-cpu)))


-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: John Fraser
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <Fqi9c.3907$Td3.714@nwrddc02.gnilink.net>
Peter Seibel wrote:

> there. For instance suppose you supply a DO loop like construct they
> might write:
> 
>   (defun foo ()
>     (do () () (burn-cpu)))
> 
> But you might translate that to:
> 
>   (defun foo ()
>     (do ((iterations 0 (1+ iterations)))
>       ((> iterations *max-iters*)
>        (when (> iterations *max-iters*)
>          (error "Bang you're dead: too many iterations.")))
>       (burn-cpu)))
> 

I suggested something similar (in concept anyway) just a few seconds 
ago, but I should have waited until I read the whole thread.  Good example.

> -Peter
> 

Secure programming is the rage in the industry right now, with very few 
languages supporting it very well.  This thread raises an interesting 
question.  Has this ever been studied or has a secure library ever been 
written for CL?  Sure, buffers can't be overflowed in CL, but It seems 
that there would be a whole new suite of problems.

Cheers,

John
From: Ivan Boldyrev
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <n2mkj1x9vu.ln2@ibhome.cgitftp.uiggm.nsc.ru>
On 8696 day of my life John Fraser wrote:
>  Sure, buffers can't be overflowed in CL...

I am unsure: AREF description in CLHS mentions no exceptional
situations or anything about indexes out of range.

-- 
Ivan Boldyrev

              "Assembly of Japanese bicycle require great peace of mind."
From: Pascal Bourguignon
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <87k714151k.fsf@thalassa.informatimago.com>
Ivan Boldyrev <···············@cgitftp.uiggm.nsc.ru> writes:

> On 8696 day of my life John Fraser wrote:
> >  Sure, buffers can't be overflowed in CL...
> 
> I am unsure: AREF description in CLHS mentions no exceptional
> situations or anything about indexes out of range.

Yes, it's  quite implicit for a specification (much too implicit IMO).


 aref array &rest subscripts => element
 subscripts---a list of valid array indices for the array.
                        ^^^^^^^^^^^^^^^^^^^

valid array index n. (of an array) a fixnum suitable for use as one of
possibly several indices needed to name an element of the array
according to a multi-dimensional Cartesian coordinate system. Such a
fixnum must be greater than or equal to zero, and must be less than
the corresponding dimension[1] of the array. (Unless otherwise
explicitly specified, the phrase ``a list of valid array indices''
further implies that the length of the list must be the same as the
rank of the array.) ``For a 2 by 3 array, valid array indices for the
first dimension are 0 and 1, and valid array indices for the second
dimension are 0, 1 and 2.''


True, it doesn't say whether using  invalid array indices leads to
"implementation dependant" results or raise an exception or whatever...

There's even this compilation option along with declarations that
allow the compilers to generate fast but wrong code...



If you want to program in a language formally specified, I guess you
won't have much choice and only ADA will fit.  Perhaps we should plan
to use VDL or Z for Common-Lisp-2010?

-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Ivan Boldyrev
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <b02lj1x9o.ln2@ibhome.cgitftp.uiggm.nsc.ru>
On 8698 day of my life Pascal Bourguignon wrote:
> True, it doesn't say whether using  invalid array indices leads to
> "implementation dependant" results or raise an exception or whatever...
>
> There's even this compilation option along with declarations that
> allow the compilers to generate fast but wrong code...

It is not wrong for portable program ;)

> If you want to program in a language formally specified, I guess you
> won't have much choice and only ADA will fit.  Perhaps we should
> plan to use VDL or Z for Common-Lisp-2010?

I can fix problem just with pair of functions: my-aref and (setf
my-aref) :)

-- 
Ivan Boldyrev

       Assembly of a Japanese bicycle requires greatest peace of spirit.
From: Alan Crowe
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <86d66ypo0e.fsf@cawtech.freeserve.co.uk>
Dave Fayram worried:
> But, since everything runs in one lisp instance, I am a
> little worried. How can I make sure that if they make a
> mistake, they don't trash the whole system for everyone?

and

> Is this possible? I mean, unwind-protect obviously, but
> I'd also like to be more aggressive and make sure someone
> doesn't common-lisp-user:quit the darn thing.

There are two very different questions here, how do you
protect against users who are /not/ trying to crash the
systems and how do you protect against users who /are/ trying
to crash the system?

For example, you don't want a frustrated user typing (quit),
not realising that it shuts down the whole system. So
save a route to the function that implements quit in a
closure, and password protect it.

(let ((hiding-place (symbol-function 'quit)))
  (defun apocalypse(password)
    (if (equal password "rover")
      (funcall hiding-place))))

Then redefine quit

(defun quit ()"Operation not permitted")

(quit) => "Operation not permitted"
(apocalypse "dog") => NIL
(apocalypse "rover")
Lisp exits.

Can a malicious user disassemble apocalypse to recover the
password? Unfortunately not.

(disassemble 'apocalypse) =>
Error in function DISASSEM::COMPILE-FUNCTION-LAMBDA-EXPR:
   Cannot compile a lexical closure

Since I didn't compile apocalypse, breaking the password is
easier than that:

(function-lambda-expression #'apocalypse)
=>
(LAMBDA (PASSWORD)
  (BLOCK APOCALYPSE (IF (EQUAL PASSWORD "rover") (FUNCALL HIDING-PLACE))))
T
APOCALYPSE

Since I'm relatively new to Lisp my instinct is to stick to
the easier task of securing your project against user errors
and accidents. I think the condition system does what is
required.

(defun user-repl()
  (tagbody top
	   (handler-bind
	    ((error (lambda(condition)
		      (describe condition)
		      (format t "Since this is a single threaded multi-user system,
we cannot allow access to the debugger. Sorry.")
		      (go top))))
	    (format t "~&>>--> ")
	    (force-output)
	    (print (eval (read)))
	    (go top))))

* (user-repl)

>>--> (+ 5 7)

12 
>>--> (/ 3 0)

#<DIVISION-BY-ZERO {480518DD}> is a structure of type DIVISION-BY-ZERO.
FUNCTION-NAME: KERNEL::DIVISION-BY-ZERO-ERROR-HANDLER.
ACTUAL-INITARGS: (:FUNCTION-NAME KERNEL::INTEGER-/-INTEGER :OPERATION
                  KERNEL::DIVISION :OPERANDS ...).
ASSIGNED-SLOTS: NIL.Since this is a single threaded multi-user system,
we cannot allow access to the debugger. Sorry.
>>--> 

Err, my call to read doesn't time share among the users.
I hope the example is useful, even if the actual code isn't.

Alan Crowe
Edinburgh
Scotland
From: Pascal Bourguignon
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <87k716umbl.fsf@thalassa.informatimago.com>
Alan Crowe <····@cawtech.freeserve.co.uk> writes:
> So
> save a route to the function that implements quit in a
> closure, and password protect it.
> 
> (let ((hiding-place (symbol-function 'quit)))
>   (defun apocalypse(password)
>     (if (equal password "rover")
>       (funcall hiding-place))))
> 
> Then redefine quit
> 
> (defun quit ()"Operation not permitted")
> 
> (quit) => "Operation not permitted"
> (apocalypse "dog") => NIL
> (apocalypse "rover")
> Lisp exits.

I would rather use the package system to prevent access to
"super-user"  functions.


> Can a malicious user disassemble apocalypse to recover the
> password? Unfortunately not.

Indeed, as soon as primitives to access the compiled or interpreted
code are available that allow modifying it, you cannot prevent a
malicious program to change itself to gain access to the whole of
itself.  

That's why you need to use the package system, to prevent access to
the most powerfull primitives.  If there's no
function-lambda-expression and no disassemble function available, you
cannot get or change the password.


-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Ivan Boldyrev
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <s8lkj1x2mu.ln2@ibhome.cgitftp.uiggm.nsc.ru>
On 8697 day of my life Pascal Bourguignon wrote:
>> (quit) => "Operation not permitted"
>> (apocalypse "dog") => NIL
>> (apocalypse "rover")
>> Lisp exits.
>
> I would rather use the package system to prevent access to
> "super-user"  functions.
>
>> Can a malicious user disassemble apocalypse to recover the
>> password? Unfortunately not.
>
> Indeed, as soon as primitives to access the compiled or interpreted
> code are available that allow modifying it, you cannot prevent a
> malicious program to change itself to gain access to the whole of
> itself.  
>
> That's why you need to use the package system, to prevent access to
> the most powerfull primitives.  If there's no
> function-lambda-expression and no disassemble function available,
> you cannot get or change the password.

But this "protection" can be easely broken with ::, can't it?  Why I
can't type

(someobsurepackage::quit)

no matter what a value of CL:*PACKAGE* is?

-- 
Ivan Boldyrev

              "Assembly of Japanese bicycle require great peace of mind."
From: Alain Picard
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <87ptaw2hh1.fsf@memetrics.com>
Ivan Boldyrev <···············@cgitftp.uiggm.nsc.ru> writes:

> But this "protection" can be easely broken with ::, can't it?  Why I
> can't type
>
> (someobsurepackage::quit)
>

I think the idea is to have a codewalker inspect all
the forms before evaluation, making sure all forms in
the "operation" position are in the safe package.
From: Rainer Joswig
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <joswig-8E4F63.14170427032004@news.fu-berlin.de>
In article <····························@posting.google.com>,
 ·········@lensmen.net (Dave Fayram) wrote:

> Hello folks, this is my first message here. I'm a relatively new lisp
> user, and I've been enjoying my time with it. I like it so much, I'm
> doing a just-for-fun project with it, but my reach is exceeding my
> grasp a little here.
> 
> I am writing what is essentially a kind of text-based BBS. I let
> people connect, handle their input, and have it call functions. It
> starts by being a chatroom, but there are multiple modes that you can
> place yourself into (which can stack).
> 
> One thing I'd like to do is let people actually write their own
> features. I am already on the cusp of having a small meta-language
> just for handling input and creating output quickly. But, since
> everything runs in one lisp instance, I am a little worried. How can I
> make sure that if they make a mistake, they don't trash the whole
> system for everyone?
> 
> Is this possible? I mean, unwind-protect obviously, but I'd also like
> to be more aggressive and make sure someone doesn't
> common-lisp-user:quit the darn thing. My first thought is to put them
> in a custom package, and make sure that package only uses a certain
> set of packages that are relavant to writing and registering
> functions. I worry about infinite loops and stuff like that though.
> 
> Is there any way I can guard against this? Is there a program in
> existance that lets people extend the system from within the system,
> as I am suggesting?
> 
> Or is my idea totally bad and bogus, and I should just not let them do
> it? :)

PAIP has a bit about a Scheme implementation in Common Lisp.
It has been used in atleast one Common Lisp application
as a scripting tool.
From: Thomas F. Burdick
Subject: Re: Extension language, using lisp to extend lisp programs.
Date: 
Message-ID: <xcvwu5534bo.fsf@famine.OCF.Berkeley.EDU>
·········@lensmen.net (Dave Fayram) writes:

> One thing I'd like to do is let people actually write their own
> features. I am already on the cusp of having a small meta-language
> just for handling input and creating output quickly. But, since
> everything runs in one lisp instance, I am a little worried. How can I
> make sure that if they make a mistake, they don't trash the whole
> system for everyone?
> 
> Is this possible? I mean, unwind-protect obviously, but I'd also like
> to be more aggressive and make sure someone doesn't
> common-lisp-user:quit the darn thing. My first thought is to put them
> in a custom package, and make sure that package only uses a certain
> set of packages that are relavant to writing and registering
> functions. I worry about infinite loops and stuff like that though.

It was already suggested that you write an interpreter, and that's
exactly what I'd do here.  It's really not too hard.  There was a
thread recently that should be helpful:

  http://groups.google.com/groups?threadm=xcvad3ycvuw.fsf%40famine.OCF.Berkeley.EDU

You'll want to carefully consider the API you expose to your users,
and that'll be most of the effort.  Writing a simple Lisp interpreter
is way down in the noise of that.  Plus, you have the collected wisdom
of a generation of Lisp implementors in the CL spec.  When you have a
design question, just do what CL does.  Having Lisp interpreters as
extension languages before, I can vouch that it's pretty easy.  Most
of the pain for me was in designing a safe API to expose, and control
structures that would be usable for non-programmers (the users in these cases).

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'