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.