''(Note: these notes apply to a new design for Ratcl, not the current v4 code)'' See [v6notes] for general notes on this design and the purpose of this page. *** Core operators *** Summary: * plus = row-wise concat, varargs * pair = columnwise concat, varargs * rowmap = map rows, 2nd arg is a 1-col view with int map * colmap = map columns, 2nd arg is a 1-col view with int map * step = generate an arithmetic progression (more general than v4's iota) *plus* Row-wise concatenation of all the views given as input. The structure of the input views must be compatible, but column names may differ. The meta-view of the result is the meta-view of the first input view. Without arguments, plus returns the 0-col / 0-row view, i.e. "0". *pair* Takes a variable number of views and returns a view with all columns of the input concatenated in the horizontal / column-wise direction. The pair operator is also available as the '..' infix operator in Lua. The pair vop uses "plus" over the meta-views to construct a result meta-view. The size of the resulting view is the size of the smallest input view. A notable property of pair is that the resulting view is not slower than the original: this does not add an extra layer of getter calls. Note: wrapping of row counts for views which are smaller than the rest would have been nice, but then 0-size view fail and more impartantly the above performance property would be lost. *rowmap* This was called "remap" in v4: return a view with the rows mentioned in the second arg. Given that lists are not directly supported as data type, that second arg must be a view with its first column containing integers (type "I") or no columns at all (in which case the view is treated as iota). When indexed beyond the end, row numbers "wrap". If the input view is empty, this is not possible and an error is generated instead. Some extra wrapper may be needed to support Tcl lists as 2nd arg. *colmap* Uses rowmap over the meta-views to construct the result meta-view. As with pair, a notable property of colmap is that the resulting view is not slower than the original: this does not add an extra layer of getter calls. *step* Takes 4 args: count, start, step, rate. Defaults: start=0, step=1, rate=1. Creates a 1-column view with an unnamed int column. This is a generalized version of v4's "iota" operator which can be used with pair and rowmap to implement vops such as iota, slice, times, spread, and reverse. The return column contains "count" integers in an arithmetic progression: i'th value = start + step * int(i/rate) *** Derived operators *** These operators are listed with their Lua implementation (untested for now). *size* The size operator can be defined as "the input view without its columns", since a 0-column-view is equivalent to the integer value of its row count. The size operator is also available as the '#' unary operator in Lua (in this case the result is always returned as a number, not a view). vopdef ('size', 'V', function (v) return v:colmap(0) end) *reverse* Return a view with rows in reverse order. vopdef ('reverse', 'V', function (v) return v:rowmap(v:step(#v-1,-1)) end) *first* Return the first n rows of a view. vopdef ('first', 'VI', function (v,n) if n>#v then n=#v end return v:rowmap(n) end) *last* Return the last n rows of a view. vopdef ('last', 'VI', function (v,n) if n>#v then n=#v end return v:rowmap(vops.step(n,#v-n)) end) *iota* Takes a count and a column name as input. Uses "step(count,0,1,1)" to generate a simple 0..count-1 progression of integers. vopdef ('iota', 'VS', function (v,name) return vops.view(0,name..':I'):plus(v.step()) end) *tag* Takes one input view and a column name. vopdef ('tag', 'VS', function (v,name) return v..v:iota(name) end) *slice* Takes a view and 3 int args: count, start, step (not sure about best arg order). Return a view with only specific rows singled out from the input view. If count exceeds the size of the input view, then it wraps around. Note: count > 0 and view empty is ill-defined and must generate an error. vopdef ('slice', 'VIII', function (v,count,start,step) return v:rowmap(vops.step(count,start,step)) end) *times* Returns its input n times (called "repeat" in v4, but that's a reserved word in Lua). vopdef ('times', 'VI', function (v,n) return v:rowmap(n*#v) end) *spread* Returns a view with each row repeated n times. vopdef ('spread', 'VI', function (v,n) return v:rowmap(vops.step(n*#v,0,1,n)) end) *product* Return the relational/cartesian cross-product of two views. vopdef ('product', 'VV', function (v,w) return v:spread(w)..w:times(v) end) *intbox* "Boxes" a (non-negative) integer as item in a 1-row/1-column view. This is mostly a gimmick for now - boxing/unboxing will become important with data-flow. vopdef ('intbox', 'I', function (i) return vops.step(1,i) end) *clone* Return a view with the same structure but no rows. vopdef ('clone' ,'V', function (v) return v:rowmap(0) end) *** More *** ''The above is just a start...''