Hi Mike!

Am Samstag, 7. Mai 2016 19:00:11 UTC+2 schrieb Mike Rodriguez:
>
> ...
> I can see how the docs @ http://clojure.org/reference/evaluation could 
> mislead someone to thinking that it is perfectly fine and acceptable to 
> embed any objects into a call to `eval`, but I really don't think that is 
> what the docs are discussing in this case.  Calling `eval` is a way to dig 
> into the evaluator of Clojure to use it "ad hoc" yourself at a different 
> time than "normal".
>
indeed, the docs say that function objects should evaluate to themselves. 

>
> So at this point, you've circumvented Clojure's standard evaluation and 
> you are attempting to take matters into your own hand.  When you do that, 
> there starts to become a lot of subtle issue, like the one of whether or 
> not you can get away with embedding already evaluated objects into a new 
> evaluation.  Since, in your example, you functions are already evaluated to 
> their function objects, you are effectively "double evaluating" them.  When 
> you do that, expect issue.
>
> This is a subtle and confusing topic because there are indeed times when 
> you can get away with embedding objects into the code you are calling eval 
> on.  However, I'd argue that is not the normal case and you shouldn't rely 
> on that because it doesn't take much change to break it and no longer be 
> able to do it.  For example, functions that have closures, I believe, can 
> never successfully be embedded into a call to eval.
>
> The real point here is in understanding evaluation semantics.  The reader 
> reads characters/text into data structures.  However these data structure 
> are not unbounded.  They are the data structures that are used to describe 
> the syntax of the Clojure language, e.g. [], {}, (), :keywords, symbols, 
> "strings", 123, etc.
> If you try to print a function object, you'll see it has no clear 
> representation as a valid data structures in the Clojure syntax subset of 
> data structures.  
> It'll be something like: <clojure.lang.AFnblah@123>
>
I think, I understand, but nevertheless I cannot understand why
{:f `(~(let [v (fn [] 1)
                   f (fn [x] (v))] f))} 
evaluates as expected, but
(eval {:f `(~(let [v (fn [] 1)
                   f (fn [x] (v))] f))})
does not. That looks like a bug, for me.

>
> This is your warning sign that it is going to be trouble to call eval on 
> it.  Eval is intended to evaluate _code_ represented as data.  This 
> function object is not in a form amendable for interpretation as code.
>
> If you do not try to control evaluation yourself, when evaluating 
> functions typically looks like this (fn [x] (inc x)).  That is not a 
> function object to the evaluator.  It is a list, with 3 elements.  The 
> first is a symbol, the next is a vector, the last is another list, and we 
> can describe its subforms similarly.
>
> Clojure does provide a facility to give a meaningful reader/data syntax 
> representation to arbitrary objects to allow evaluation later for things 
> like serialization.  This is via the 
> clojure.core/print-dup family of functionality.  Functions themselves in 
> Clojure do not out-of-the-box come with a useful implementation of 
> print-dup, but it is a multimethod and can be dynamically extended to new 
> types of data.
>
> I think you should try to solve your problem in a simpler way than going 
> to this level of depth and/or trying to call eval yourself on 
> already-pre-evaluated forms, but for the sake of learning, you may be 
> interested in seeing how to make a macro for creating functions that do 
> have a print-dup implementation that would allow them to be printed as 
> readable, then "evaluatable" code data structures later on.  
> https://github.com/sorenmacbeth/serializable-fn is an example of this.  I 
> have used it for inspiration before where I did want to be able to 
> serialize pre-eval'ed functions, but I had some tweaks to it of my own. 
>  The basic idea holds.  However, I only have needed to go to this level of 
> complexity when I was trying to serialize this data so that I could store 
> it away and use it in another separate process later, which I think is 
> where it can become useful.
>
I will take a look at your hint. 

>
>
> Hopefully you find this useful.
>
thank you, Mike

Johannes 

>
>
>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
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 clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to