help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: eval myths - Re: How to tame compiler?


From: tomas
Subject: Re: eval myths - Re: How to tame compiler?
Date: Sat, 1 May 2021 10:13:04 +0200
User-agent: Mutt/1.5.21 (2010-09-15)

On Fri, Apr 30, 2021 at 11:23:03PM +0300, Jean Louis wrote:
> * Jorge P. de Morais Neto <jorge+list@disroot.org> [2021-04-30 17:29]:
> > Hi all!
> > 
> > Em [2021-04-22 qui 10:46:59-0400], Stefan Monnier escreveu:
> > 
> > >> Is there a way to avoid these warnings?
> > >
> > > Yes: don't abuse `eval` ;-)
> > 
> > Jean Louis, could you provide a little more detail on what are you using
> > ~eval~ for? [...]

> Good read:
> https://en.wikipedia.org/wiki/Eval#Security_risks
> 
> My eval-ing is equally dangerous as Org Babel evaling. If I write some
> destructive commands, well, it will be destructive.

Framing this from the security point of view to then deconstruct
that frame leads up a blind alley. Actually, it's a kind of
strawman [1] :-)

Not that the security aspect isn't important. Actually, it has the
potential to illustrate the underlying problem, but it is /not/
the underlying problem.

What, for me, was elucidating was to try to think about what environment
eval is supposed to "see". Imagine, in a lexical context,

  (let ((x 5))
    (eval '(+ x 2)))

[QUESTION TO THE EXPERTS]
  Why is this code

    (let ((x 5))
      (eval '(+ x 2) t))

  complaining "eval: Symbol’s value as variable is void: x"
  when I `C-x e' it in my scratch buffer?
  Yes, `lexical-binding' is t in the buffer
[END OF QUESTION]

Is eval supposed to "see" x? Now, if you have a compiler which does
constant folding [0] ("ah, x, in this context /can/ only be 5, so we
substitute its value in all expressions...").

Look up the documentation of `eval' in the Emacs Lisp manual for the
path elisp has chosen.

As soon as eval is involved, that is a bad plan. What if deep there
in the eval, there is a (setq x 99)? Which isn't known at compile
time, because... eval?

So whenever there's an eval, the compiler has to drop nearly all its
instruments. And this is bad :-)

This is not really easy to grasp, but you'll always hear people who
have done that tour (Stefan has!) to somewhat discourage the use
of eval. Yes, it's there, is a tool, use it -- but it'll take you
some time and a couple of scars until you fully master it.

Usually, the problem you want to solve isn't nearly general enough
to warrant the full eval.

Put in other words: before you use eval, try to give an account
of the full evaluation environment passed to it: `x' is bound to
5 (see above), `current-buffer' to some funny function, there is
a function `strokes-describe-stroke' (did you know that one? I
didn't)... and so on.

There's that phrase "eval is evil" (I saw it first mentioned by
Christian Queinnec in his book [2a], [2b]). You can use it conveniently
in your search engine to see folks out there arguing the exact
way you do and the answers given (most of the time it's javascript
these days, because it's the language you get paid for currently,
but the underlying problem is similar).

Note that I have very little clue on all those things. Stefan
has. If he says "think before eval", I'd strongly recommend doing
some reading and experimenting. The journey could end up being
panoramic :-)

Cheers

[0] https://en.wikipedia.org/wiki/Constant_folding
[1] The kind I'd call "involuntary strawman". Security often
   has to play involuntary strawman.
[2a] https://christian.queinnec.org/
[2b] https://christian.queinnec.org/WWW/LiSP.html

-- t

Attachment: signature.asc
Description: Digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]