--
You received this message because you are subscribed to the Google Groups "Clojure Dev" group.
To view this discussion on the web visit https://groups.google.com/d/msg/clojure-dev/-/gU2FEfz1y20J.
To post to this group, send email to cloju...@googlegroups.com.
To unsubscribe from this group, send email to clojure-dev...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/clojure-dev?hl=en.
I want to mention that :children is pretty inconvenient if you intend to do any AST transformations.
--
On Fri, Apr 27, 2012 at 11:32 AM, David Nolen <dnolen...@gmail.com> wrote:On Thu, Apr 26, 2012 at 4:25 PM, Aaron Cohen <aa...@assonance.org> wrote:
I want to mention that :children is pretty inconvenient if you intend to do any AST transformations.What kinds of transformations are you finding useful?In CinC, I chose to do all the logic that the java clojure compiler currently intertwines with emitting code in a separate pass over the AST.
--
You received this message because you are subscribed to the Google Groups "Clojure Dev" group.
To view this discussion on the web visit https://groups.google.com/d/msg/clojure-dev/-/mtNZTAtet6kJ.
I'd like to see a better explanation of the problem.
--
You received this message because you are subscribed to the Google Groups "Clojure Dev" group.
To view this discussion on the web visit https://groups.google.com/d/msg/clojure-dev/-/7EOsvZiWeM0J.
An alternative to the multimethod approach that might retain the "data" aspect instead of creating an API would be to change :children to only contain the names of the keys of the child elements, rather than a copy of the values. This avoids the "going out of sync problem", since that means :children is an indirect reference to the actual child nodes. I actually think this is more work for the consumer than the multimethod approach, but it'd be possible to write a general "children" function in terms of the :children element.For example:{:op :if :test test-expr :then then-expr :else else-expr :children [:test :then :else]}--Aaron
On Monday, April 30, 2012 1:49:36 PM UTC+3, Rich Hickey wrote:I'd like to see a better explanation of the problem.
If I understand correctly, only exprssion objects (i.e., maps containing :op, :env, :form etc) should be in the :children vector. Is this correct? At least the analyze docstring suggests it:"... If expr has any (immediately) nested exprs, must have :children [exprs...] entry. ..."If the above assumption is correct then what was in the :children vectors was somewhat inconsistent[1]:* contents of :env is one of the "children" for the :dot expression object #CLJS-205* :fn has no :children key #CLJS-205* The :children for :let has an extra set of brackets #CLJS-195* Children for :try* contains a {:name mname} entry. In addition the children contains the blocks of :try :catch :finally, and not the expressions themselves* :recur has no :childrenThe reason for the multimethod approach is laid out in the second paragraph of CLJS-214[2]. If that is not the correct approach then we should revert those changes. I'm more interested in getting the points above corrected.Jonas
What's the point of keeping an element that the primary project doesn't use, and the library users can't use?
--
You received this message because you are subscribed to the Google Groups "Clojure Dev" group.
I'm not sure I understand either. It duplicates parts of the tree and in my experiences working with it, it just confuses things. I would want to work with the tree much more in the way that the compiler itself does and that's through knowledge of how each node is constructed. It seems like the multi-method is a great way of capturing that.
Cheers,
Chris.
--
You received this message because you are subscribed to the Google Groups "Clojure Dev" group.
I think it's possible to come up with a solution that works for everyone.What about my idea about putting the child keys in :children rather than duplicating the values?
On Mon, Apr 30, 2012 at 9:52 AM, David Nolen <dnolen...@gmail.com> wrote:
> Just because you're ignoring it doesn't mean other tools will.Is anyone currently using :children? Keeping it around just in case
some might, or guessing about how other tools might want to use that
information doesn't seem right.
I'm sorry, I disagree. You're fighting to defend an ugly misfeature in my opinion.How does it make sense to have the data that all users are going to need, but present it in a form that some subset of users will be: 1) forced to ignore, and then 2) duplicate that same information in a form that works for them.Whatever floats your boat though I guess.--Aaron
--
--
You received this message because you are subscribed to the Google Groups "Clojure Dev" group.
I don't know what you mean by using pattern matching or unification without an example. I don't think either are core features of the clojure language, so I don't know why we're catering to them. However, if we can make them work I'd be happy to think about how.--Aaron
Is it impossible for core.logic to say (children node) rather than (:children node)?--Aaron
--
Hmm how about this compromise- an add-children multimethod?(add-children ast)People who don't plan on transforming the AST can just interact with data - and those who plan on transforming the AST have a standard way to keep nodes up to date.
Going on Rich's feedback I think pursuing the :children as keys approach is best. Clearly just having the keys there isn't sufficient. But I think this approach addresses problems a) *and* b), we get a more human-readable AST as a result.So what should :children look if it becomes an index of sorts?
Disadvantages:???
On Wed, May 2, 2012 at 2:20 PM, David Nolen <dnolen...@gmail.com> wrote:On Wed, May 2, 2012 at 2:10 PM, Aaron Cohen <aa...@assonance.org> wrote:What about forms like let where :children is a bit complex?:children (into (vec (map :init bes))(conj (vec statements) ret))I think that should become: {:op :let :children {:init [inits] :statements [statements] :ret ret}
On Wed, May 2, 2012 at 2:29 PM, Aaron Cohen <aa...@assonance.org> wrote:On Wed, May 2, 2012 at 2:20 PM, David Nolen <dnolen...@gmail.com> wrote:On Wed, May 2, 2012 at 2:10 PM, Aaron Cohen <aa...@assonance.org> wrote:What about forms like let where :children is a bit complex?:children (into (vec (map :init bes))(conj (vec statements) ret))I think that should become: {:op :let :children {:init [inits] :statements [statements] :ret ret}So if a :children value entry is a vector it's something you need to iterate over?
What about :ret? So you'll always need to look at :children if you want to know :ret?
So it should actually look like:{:op :let :children {:inits [{:op :binding :name x :init init-expr} {:op :binding :name y :init init-expr}] :statements [statements] :ret ret}}
2) Supporting generic code walkers. Code walking has traditionally been a difficult and brittle thing, as everyone encodes the primitives. Thus, adding a new primitive becomes impossible. Plus, that encoded knowledge itself is quite complex and duplicated between code walkers. Given that the AST data is a mix of things that would need to be walked and other details, there needs to be a mechanism to distinguish them.
2) Supporting generic code walkers. Code walking has traditionally been a difficult and brittle thing, as everyone encodes the primitives. Thus, adding a new primitive becomes impossible. Plus, that encoded knowledge itself is quite complex and duplicated between code walkers. Given that the AST data is a mix of things that would need to be walked and other details, there needs to be a mechanism to distinguish them.
Wouldn't any new primitive potentially invalidate any assumptions made by any code walker? New primitives could subtly violate some invariant that a code walker expected. It's not as if having a generic way to walk the AST would suddenly insulate any code walker that naively cared about a subset of primitives.
:children as a vector of keys seems promising.