- Implementation note - - Bad variable name !! - - In a number of places we have 'query', the argument == list of TreeQL operations, but we also have 'query' the instance variable, referring to the parent object. This easily confuses anyone trying to understand the implementation. => Use a different name for the instance variable referring to the parent object. - Implementation note We should add more comments to see which methods are helpers, and which implement the TreeQL operators. We should also reorder the methods based on that. The internal methods (like apply, mapself) should have names with first char upper case. Also better name for 'apply' is 'treeapply', or 'treeop_apply'. 'bool' is 'treefiler_apply' or something ... - Should we save a node set before a query, and restore if an error occurs ? = query is like transaction = = new node set happens only if successful = - should we have push/pop operations to save/restore node sets while the query executes ? - this would essentially start to add a stack manipulation language to the TreeQL (push, pop, dup, swap, rot, ...) - does it make sense to 'precompile' queries into a tree ops, for faster execution (saving, using precompiled queries ?) - Tree ops - tcllib tree has an 'ancestors' operation. IMHO it should be used. NOTE: When we reimpl. tree in snit we can use 'info methods' to check for existence of 'ancestors', and fall back to the local iteration via 'parent' if it is not present. - list of left siblings can be had easier (we have an 'index' op!) - descendants can be had from tree. (and|or|not)q use helpers an|or|not given their definition they can be regular operators as well. > > ** Operator 'string' is not a mutator. > > It is a string acessor. Does not change the tree, leaves > > results in the node set => Definitely accessor. > > Quite right. Ok, will move it in my docs. operator reverse > > ** Ideas, way out ... > > > > -- Keep not a node set, but a stack of sets, add > > operations: > > push, pop, dup, swap, rot > > Nice idea. It's already sort of implicitly there, though, in the > andq/orq/notq stuff. Right. I noticed that for SQ a subquery we have the equivalence (andq SQ) <=> (subquery SQ and) if we also assume that there is some internal storage both 'subquery' and 'and' know and use for the temp node set. Extending this storage to a stack is conceptually easy and clean. Etc. for the other operators. > OTOH, rather than duplicating stack functionality, a nice API to mix the > struct::stack and other objects might be better. I've left the ability > to set and query the nodeset, so this isn't foreclosed. Oh, you mean a special object keeping the actual node and implementing the access. Again defaults to self, but could be a specific rapper to stack ? Hm. (I had not thought of using the struct::stack, but its use is sort of obvious. (I guess I tend to forget stack and queue objects, because they can be implemented so lightweight with Tcl lists when and whereever they are needed)). > > I am not sure if adding this type of stack operators > > will up the expressivity of the TreeQL very much. It > > becomes a bit more forth-like. > > I'd suggest it would be good to provide a bunch of parent QL types for > that. Now that I truly understand the parent stuff, yes, this can be layered on top of the basic query. And should be, so people can choose what they need and how much baggage is required. Yes, definitely use layering here to keep stuff simple and modular. > > -- Precompile queries to Tcl code doing all ops directly > > in proper sequence ? > > (If we allow a q-object to save such queries, and > > execute on demand. Maybe store in files ?) > > I *really* like that idea. It does become forth-like :) The main loop of the query interpreter is already similar to a inner-loop, inner-interp of a forth system. For this we have to tell to not interpret the operator, but to run a compile method for the operator, which adds Tcl code to a script, and this can be saved and used later. ... Depending on the complexitiy of the created code the script may depend on the infrastructure of a query object, or be completely independent, i.e. require only access to a tree object. If the latter then it becomes a 'hardwired query object', maybe a new snit class ? Note, this type of compiler can also be added through the 'parent query' stuff. ... Heh, this could make things even more easy. Have the user play with queries, then attach a parent query to your object, run the queries again to get compiled, save ... The only not so modular thing is that the compiler has to know how the operators are ipmlemented, and this may not gel with an extended query having stack operation. ... Or can we use the snit method introspection here as well ? Get methods available, get method body, use that in the generated code ... But then methods have to be written carefully so that we can extract the actual operation from the code accessing node set and such. ... Or we split the current methods into true functionality and a interpreter shim. The compiler needs only the functionality, and uses his own mgmt code ... Oh the ideas ... Ok, stop now before completely flying off the deep end. I will put all this into a file IDEAS.txt of the module and place it under revision control, for future work. ** Proposal: Add a `node set operator` -> "reverse". set nodes [struct::list reverse $nodes] This makes the description of a number of operators, like "backward" easier. backward <==> 'prev subtree reverse' ** Ideas, way out ... -- Keep not a node set, but a stack of sets, add operations: push, pop, dup, swap, rot I am not sure if adding this type of stack operators will up the expressivity of the TreeQL very much. It becomes a bit more forth-like. -- Precompile queries to Tcl code doing all ops directly in proper sequence ? (If we allow a q-object to save such queries, and execute on demand. Maybe store in files ?)