Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eval can only see locals #1041

Closed
gilch opened this issue Apr 12, 2016 · 4 comments · Fixed by #2010
Closed

eval can only see locals #1041

gilch opened this issue Apr 12, 2016 · 4 comments · Fixed by #2010

Comments

@gilch
Copy link
Member

gilch commented Apr 12, 2016

Eval works on symbols for modules:

=> (import operator)
import operator
=> (eval 'operator)
from hy.importer import hy_eval
from hy import HySymbol
hy_eval(HySymbol('operator'), locals(), '__console__')
<module 'operator' from 'C:\\Python34\\Scripts\\env-hy\\lib\\operator.py'>

Functions can return modules:

=> ((fn [] operator))
def _hy_anon_fn_1():
    return operator
_hy_anon_fn_1()
<module 'operator' from 'C:\\Python34\\Scripts\\env-hy\\lib\\operator.py'>

Functions can return the result of an eval:

=> ((fn [] (eval 'first)))
from hy.importer import hy_eval
from hy import HySymbol

def _hy_anon_fn_1():
    return hy_eval(HySymbol('first'), locals(), '__console__')
_hy_anon_fn_1()
<function first at 0x000000000369DC80>

But not if it's a module!

=> ((fn [] (eval 'operator)))
from hy.importer import hy_eval
from hy import HySymbol

def _hy_anon_fn_1():
    return hy_eval(HySymbol('operator'), locals(), '__console__')
_hy_anon_fn_1()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 1, in _hy_anon_fn_1
  File "c:\users\me\code\repos\hy\hy\importer.py", line 134, in hy_eval
    return eval(ast_compile(expr, "<eval>", "eval"), namespace)
  File "<eval>", line 1, in <module>
NameError: name 'operator' is not defined

I am surprised by this. Are you?

@gilch
Copy link
Member Author

gilch commented Apr 12, 2016

It's not just modules. I found a simpler illustration:

=> (def spam 42)
spam = 42
=> (eval 'spam)
from hy.importer import hy_eval
from hy import HySymbol
hy_eval(HySymbol('spam'), locals(), '__console__')
42
=> ((fn [] (eval 'spam)))
from hy.importer import hy_eval
from hy import HySymbol

def _hy_anon_fn_1():
    return hy_eval(HySymbol('spam'), locals(), '__console__')
_hy_anon_fn_1()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 1, in _hy_anon_fn_1
  File "c:\users\me\code\repos\hy\hy\importer.py", line 134, in hy_eval
    return eval(ast_compile(expr, "<eval>", "eval"), namespace)
  File "<eval>", line 1, in <module>
NameError: name 'spam' is not defined
=> ((fn [] (eval 'spam (globals))))
from hy.importer import hy_eval
from hy import HySymbol

def _hy_anon_fn_1():
    return hy_eval(HySymbol('spam'), globals(), '__console__')
_hy_anon_fn_1()
42

The equivalent Clojure works:

user=> (def spam 42)
#'user/spam
user=> (eval 'spam)
42
user=> ((fn [] (eval 'spam)))
42
user=>

Common Lisp too:

* (defvar spam 42)

SPAM
* ((lambda () (eval 'spam)))

42
*

Even Racket Scheme (if anyone cares about Racket):

> (define spam 42)
> ((lambda () (eval 'spam)))
42
> 

@refi64
Copy link
Contributor

refi64 commented Apr 12, 2016

Have a fix in the works; just writing the tests.

@gilch gilch mentioned this issue Apr 12, 2016
@Kodiologist Kodiologist changed the title eval glitch in fn for modules eval can only see locals Apr 2, 2017
@allison-casey
Copy link
Contributor

I don't know how yet, but this looks to be fixed.

@Kodiologist
Copy link
Member

Don't feel like you have to find the change that fixed it. The important thing is just ensuring it's fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants