From: David E. Young
Subject: Alternatives to EVAL
Date: 
Message-ID: <38E53B02.5FD4DA24@mindspring.com>
Greetings. I've read that if EVAL is used explicitly within a program,
it probably indicates poor design. We've a situation where we're getting
Lisp forms via a CORBA invocation and must somehow evaluate them within
the context of a particular package. As a rough prototype, we've
writting something like this:

  (defmacro eval-from-string (str)
      `(eval (read-from-string ,str))

However, since I certainly want to avoid poor constructs, and in the
interest of becoming a better Lisp developer, I'm soliciting
alternatives. I have Graham's books, but I'm currently at home and don't
have them handy. Thanks much.


--
David E. Young
Fujitsu Network Communications  "The fact that ... we still
(···@nc.fnc.fujitsu.com)         live well cannot ease the pain of
                                 feeling that we no longer live nobly."
                                  -- John Updike
"Programming should be fun,
 programs should be beautiful"
  -- P. Graham

From: David E. Young
Subject: Re: Alternatives to EVAL
Date: 
Message-ID: <38E53E58.B956828C@mindspring.com>
"David E. Young" wrote:

> Greetings. I've read that if EVAL is used explicitly within a program,
> it probably indicates poor design. We've a situation where we're getting
> Lisp forms via a CORBA invocation and must somehow evaluate them within
> the context of a particular package. As a rough prototype, we've
> writting something like this:
>
>   (defmacro eval-from-string (str)
>       `(eval (read-from-string ,str))
>

Following up my own post, I forgot to mention that typically, the form sent
across the wire (and handed to eval) will be a macro. Sorry for the
omission.


--
David E. Young
Fujitsu Network Communications  "The fact that ... we still
(···@nc.fnc.fujitsu.com)         live well cannot ease the pain of
                                 feeling that we no longer live nobly."
                                  -- John Updike
"Programming should be fun,
 programs should be beautiful"
  -- P. Graham
From: Mike McDonald
Subject: Re: Alternatives to EVAL
Date: 
Message-ID: <zMbF4.1353$h81.24564@typhoon.aracnet.com>
In article <·················@mindspring.com>,
	"David E. Young" <·······@mindspring.com> writes:
> Greetings. I've read that if EVAL is used explicitly within a program,
> it probably indicates poor design.

  It might be an indicator but it's not an obsolute either.

> We've a situation where we're getting
> Lisp forms via a CORBA invocation and must somehow evaluate them within
> the context of a particular package. As a rough prototype, we've
> writting something like this:
> 
>   (defmacro eval-from-string (str)
>       `(eval (read-from-string ,str))

  Calling EVAL when you want something evaluated is a perfectly rational and
justifiable thing to do. You may want to add error handling though, for both
the READ-FROM-STRING and the EVAL.

  Mike McDonald
  ·······@mikemac.com
From: Barry Margolin
Subject: Re: Alternatives to EVAL
Date: 
Message-ID: <zXcF4.88$YN6.2876@burlma1-snr2>
In article <·················@mindspring.com>,
David E. Young <·······@mindspring.com> wrote:
>Greetings. I've read that if EVAL is used explicitly within a program,
>it probably indicates poor design.

This mainly applies to cases where the program creates an expression and
then EVALs it.  It should probably use things like function objects and
function composition.

However, if it's receiving the expression from an external source, it's
normal.  For instance, the fact that the read-eval-print loop uses EVAL
doesn't indicate a misdesign of the read-eval-print loop -- that's
precisely what EVAL is for.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Christopher Browne
Subject: Re: Alternatives to EVAL
Date: 
Message-ID: <LhfF4.3537$9g4.174069@news5.giganews.com>
Centuries ago, Nostradamus foresaw a time when David E. Young would say:
>Greetings. I've read that if EVAL is used explicitly within a program,
>it probably indicates poor design. We've a situation where we're getting
>Lisp forms via a CORBA invocation and must somehow evaluate them within
>the context of a particular package. As a rough prototype, we've
>writting something like this:
>
>  (defmacro eval-from-string (str)
>      `(eval (read-from-string ,str))
>
>However, since I certainly want to avoid poor constructs, and in the
>interest of becoming a better Lisp developer, I'm soliciting
>alternatives. I have Graham's books, but I'm currently at home and don't
>have them handy. Thanks much.

Part of the secret is in knowing when to break the rules...

There is always some point at which forms need to be (eval)ed.

It tends to be preferred to do this at compile time, and thus avoid
the resultant security and runtime-speed issues.

If the forms are actually crossing over via CORBA, then you indeed do
need to have an eval, and while there could be some quibbling over
precisely *where* it should take place, it sure sounds like you've got
it in something *resembling* the right place.  

You might want to provide a "hook" to allow some processing on the
strings before they get (eval)led so that there's some validation of
correctness/safeness.  Rather resembling the common CGI step where
strings are pre-processed to prevent someone from transmitting "evil
things" and breaking security.
-- 
You know  how most packages say  "Open here". What is  the protocol if
the package says, "Open somewhere else"?
········@hex.net- <http://www.ntlug.org/~cbbrowne/lisp.html>
From: Tom Breton
Subject: Re: Alternatives to EVAL
Date: 
Message-ID: <m3k8ih4pcp.fsf@world.std.com>
"David E. Young" <·······@mindspring.com> writes:

> Greetings. I've read that if EVAL is used explicitly within a program,
> it probably indicates poor design. 

I wouldn't say that.  Using eval *gratuitously* indicates poor design,
because it adds an extra level of indirection without accomplishing
anything.  But where the extra indirection is helpful, by all means
use it.  Lisp is meant to do powerfully expressive things like that.
That's why eval is there.

>We've a situation where we're getting
> Lisp forms via a CORBA invocation and must somehow evaluate them within
> the context of a particular package. As a rough prototype, we've
> writting something like this:
> 
>   (defmacro eval-from-string (str)
>       `(eval (read-from-string ,str))


Ordinarily I'd ask why you are writing a string instead of directly
writing a sexp.  But since you tell me that's the only form you can
get the forms in, then ISTM your solution is fine.

I do wonder if you really want to use a macro rather than a function.
Macros are just Lisp acting as its own preprocessor.  *Are* these
forms actually something you're preprocessing?

> have them handy. Thanks much.

You're quite welcome.

-- 
Tom Breton, http://world.std.com/~tob
Not using "gh" since 1997. http://world.std.com/~tob/ugh-free.html
Rethink some Lisp features, http://world.std.com/~tob/rethink-lisp/index.html
From: David E. Young
Subject: Re: Alternatives to EVAL
Date: 
Message-ID: <38E68232.D83E36A5@mindspring.com>
Tom Breton wrote:

> "David E. Young" <·······@mindspring.com> writes:
>
> > Greetings. I've read that if EVAL is used explicitly within a program,
> > it probably indicates poor design.
>
>
> I do wonder if you really want to use a macro rather than a function.
> Macros are just Lisp acting as its own preprocessor.  *Are* these
> forms actually something you're preprocessing?
>

Hey Tom. The forms coming across the wire are indeed macro calls exported by a
third-party package. Right now, that's the way they must remain, so the
concensus here is that EVAL in this situation is an appropriate use. Thanks to
everyone who replied.

Regards,

--

David E. Young
Fujitsu Network Communications  "The fact that ... we still
(···@nc.fnc.fujitsu.com)         live well cannot ease the pain of
                                 feeling that we no longer live nobly."
                                  -- John Updike
"Programming should be fun,
 programs should be beautiful"
  -- P. Graham
From: Rob Warnock
Subject: Re: Alternatives to EVAL
Date: 
Message-ID: <8c6e54$qd44m$1@fido.engr.sgi.com>
David E. Young <·······@mindspring.com> wrote:
+---------------
| The forms coming across the wire are indeed macro calls exported by a
| third-party package. Right now, that's the way they must remain, so the
| concensus here is that EVAL in this situation is an appropriate use.
+---------------

Well, if *all* the forms coming across the wire are indeed "macro calls",
then for safety (*and* speed!) you might want to do you own "expansion" of
the "macros". That is, simply put a function to process each form into a
hash table indexed by the "macro" keyword [car of the form]. The per-form
functions can always call EVAL on certain sub-forms if they really, really
need to, but I'll bet that most (if not all) of the time the rest of each
form is just "data" to the per-form function.

If your application *can* fit into this model...

1. It's a lot cleaner than using EVAL, since you don't have to worry
   about confusions between "macro-expand time" and run-time;

2. It's a lot *faster* than using EVAL (you don't go through the entire
   interpreter);

3. It's a lot *safer* than using EVAL, since only pre-loaded handlers
   can be called (especially if you turn off *READ-EVAL*).


-Rob

-----
Rob Warnock, 41L-955		····@sgi.com
Applied Networking		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
1600 Amphitheatre Pkwy.		PP-ASEL-IA
Mountain View, CA  94043
From: Scott L. Burson
Subject: Re: Alternatives to EVAL
Date: 
Message-ID: <38EA2802.D3C85701@my-dejanews.com>
"David E. Young" wrote:
> 
> Hey Tom. The forms coming across the wire are indeed macro calls exported by a
> third-party package. Right now, that's the way they must remain, so the
> concensus here is that EVAL in this situation is an appropriate use.

Hmm, as a protocol design, this makes me a little nervous.

One thing you should definitely do, if you aren't already, is to specifically
bind *PACKAGE* across the READ-FROM-STRING call to a package that contains all
the symbols you need.  This will prevent your code from breaking if someone sets
the package to something weird.

(Digression: I learned my lesson on this the hard way.  Years ago, on a Lisp
Machine, I was hacking something for which I needed a package that did not
inherit any symbols from any other package.  When I set *PACKAGE* to this
package, I discovered that the LispM could no longer access its file server
(!).  After a considerable amount of poking around, I found the problem: the
Chaos NFILE protocol relied on the server sending file properties to the client
in the form of printed list structure, which contained, among other things, the
symbol NIL.  With *PACKAGE* bound to my weird package, the client's
READ-FROM-STRING got the wrong NIL, thus breaking the protocol.)

I would additionally suggest going a bit further and making a package that
contains *only* the symbols you will need to read.  This will limit what the
incoming forms can do when EVALed... which would make me a lot more comfortable
with this design.

-- Scott
From: Erik Naggum
Subject: Re: Alternatives to EVAL
Date: 
Message-ID: <3163862636948799@naggum.no>
* Scott L. Burson
| I would additionally suggest going a bit further and making a package
| that contains *only* the symbols you will need to read.  This will limit
| what the incoming forms can do when EVALed... which would make me a lot
| more comfortable with this design.

  it's even a little worse than you sketch out.  ideally, you should be
  able to force intern not to intern, i.e. to have read call find-symbol
  and barf on uninterned symbols.  ideally, you should be able to force the
  symbol-reader to barf on _any_ package specification other than those you
  have specified.  neither of these are possible in fully conforming code.

#:Erik
From: David E. Young
Subject: Re: Alternatives to EVAL
Date: 
Message-ID: <38EB6778.D93CBAA3@mindspring.com>
"Scott L. Burson" wrote:

> "David E. Young" wrote:
> >
> > Hey Tom. The forms coming across the wire are indeed macro calls exported by a
> > third-party package. Right now, that's the way they must remain, so the
> > concensus here is that EVAL in this situation is an appropriate use.
>
> Hmm, as a protocol design, this makes me a little nervous.
>
> One thing you should definitely do, if you aren't already, is to specifically
> bind *PACKAGE* across the READ-FROM-STRING call to a package that contains all
> the symbols you need.  This will prevent your code from breaking if someone sets
> the package to something weird.
>

Yes, this is precisely what I'm doing (after experiencing a problem similar to that
described in your LispM annecdote). Appreciate the thoughts.

Regards,

--
David E. Young
Fujitsu Network Communications  "The fact that ... we still
(···@nc.fnc.fujitsu.com)         live well cannot ease the pain of
                                 feeling that we no longer live nobly."
                                  -- John Updike
"Programming should be fun,
 programs should be beautiful"
  -- P. Graham
From: Erik Naggum
Subject: Re: Alternatives to EVAL
Date: 
Message-ID: <3163690457188144@naggum.no>
* "David E. Young" <·······@mindspring.com>
| I've read that if EVAL is used explicitly within a program, it probably
| indicates poor design.

  the probability is not 1.0, however.  using EVAL in servers or programs
  that accept input from users or agents of users for the express purpose
  of evaluation in the Lisp world is good design -- reinventing your own
  EVAL at this point is poor design.

#:Erik