Arc Forumnew | comments | leaders | submitlogin
5 points by waterhouse 5500 days ago | link | parent

Due to the way eval works, it doesn't touch lexical variables. So:

  arc> (let i 2 (+ i 1))
  3
  arc> (let i 2 (eval '(+ i 1)))
  Error: "reference to undefined identifier: _i"
This isn't specific to Arc, by the way. In Racket and in Common Lisp, it doesn't work:

  > (let ((i 2)) ;Racket
      (eval 'i))
  . . reference to undefined identifier: i
Thus, your version of when will not work the same way as the macro version when you try to do this, for example:

  arc> (time:for i 1 1000 (mywhen '(is i 666) '(prn "Oh no!")))
  Error: "reference to undefined identifier: _i"
Other than that little kink with lexical variables, though, using eval does do pretty much the same thing as using a macro.

One more thing: eval is also much less efficient if you intend to use it repeatedly. By definition, eval performs full syntax analysis every time you use it. In the below example, its argument is a constant, so a smart compiler could theoretically optimize it to run like normal code, but in general its argument would not be constant.

  arc> (= i 0)
  0
  arc> (time:repeat 1000 (++ i))
  time: 2 msec.
  nil
  arc> (time:repeat 1000 (eval '(++ i)))
  time: 145 msec.
  nil
So, I recommend against using eval if you can avoid it. One use case is where you wait for the user to type in an expression, and you evaluate it and print the result.


1 point by ulix 5499 days ago | link

Thank you for the answer, very interesting. Here's some more things I found:

1) actually the "reference to undefined identifier" error can be avoided un-quoting the variables at calling time, as in: (let i 2 (eval­ `(+ ,i 1))) (time:for i 1 1000 (mywh­en `(is ,i 666) '(prn­ "Oh no!")))

2) the last expression is computed in 176 msec, whereas the regular macro 'when' is computed in 2 msec (much faster as you forecasted).

3) these examples don't work in online interpreter Arc Web REPL (http://dabuttonfactory.com:8080/), but they work in TryArc (http://tryarc.org/)

Thanks

-----