1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
- 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 ?)
|