On Jan 31, 2013, at 8:03 PM, Chas Emerick wrote:

> 
> On Jan 30, 2013, at 5:59 PM, Michał Marczyk wrote:
> 
>> On 30 January 2013 23:32, Chas Emerick <[email protected]> wrote:
>>> On Jan 30, 2013, at 12:23 PM, Michael Fogus wrote:
>>> 
>>>>> RuntimeException EvalReader not allowed when *read-eval* is false.
>>>> 
>>>> The problem is that the second eval gets (<the actual + function> 1 2
>>>> 3) which invokes the right pathway triggering the exception.  You can
>>>> trigger the same exception by:
>>>> 
>>>> (binding [*read-eval* false] (eval (list + 1 2 3)))
>>> 
>>> Re-reading this, I'm clearly not grokking something here.  Maybe I'm having 
>>> a slow afternoon; send help. :-P
>>> 
>>> This obviously ends up running through EvalReader — but why?  How is 
>>> LispReader ever involved at all?
>> 
>> I believe the story goes like so:
>> 
>> The eval call here compiles a list of a function object and three
>> numbers. The function object gets compiled to code which effectively
>> calls readString on "#=(clojure.core$_PLUS_. )". (It so happens that
>> print-dup knows how to handle functions; if it didn't, an exception
>> would be thrown during compilation with the message "Can't embed
>> object in code, maybe print-dup not defined: ...".) When the compiled
>> code is executed, readString gets called to reconstruct the function,
>> and since *read-eval* is false, this fails.
> 
> Whoo, sneaky.  If only fns carried (most of) the metadata that their 
> originating vars were defined with, print-dup would be able to emit a 
> fully-qualified symbol instead of that bonkers ctor call...I think.
> 
> This explains why my plan for a nuclear option for "fixing" *read-eval*'s 
> default doesn't work when outside of a bare `java -cp ... clojure.main` REPL:
> 
>       https://gist.github.com/4674181
> 
> Much of the initialization of the nREPL / Leiningen / Reply toolchain 
> involves evaluating code that's been prn'ed, and there may very well be a 
> couple of nested `eval` usages lurking in there similar to what Fogus raised.
> 
> So, getting *read-eval* to a safe default is going to require more than just 
> setting its default to false; all usages of #= in 
> https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_print.clj 
> need to be eliminated.  Will be peeking at that next...

It looks like print-dup is actually significantly relied upon by the compiler 
when emitting constants (e.g. keyword and symbol literals, namespaces, vars, 
etc) for generated classes.  (There might be other usages that I haven't 
uncovered yet, but I don't *think* so.)  I think that that print-dup usage will 
need to be replaced with corresponding asm method emits if we are to default 
*read-eval* to false without introducing eval-related limitations that will 
appear to nearly all users to be arbitrary and capricious.

Per usual, I'm in over my head around compiler issues, but we'll see what next 
week brings.  I suspect others that have done more compiler hacking than I 
would have an easier time of it...

Cheers,

- Chas

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to