Thread overview
Template recursion error on table struct
Mar 25, 2016
data pulverizer
Mar 25, 2016
data pulverizer
Mar 26, 2016
Ali Çehreli
Mar 26, 2016
data pulverizer
Mar 26, 2016
data pulverizer
Mar 26, 2016
Ali Çehreli
Mar 26, 2016
data pulverizer
March 25, 2016
I am attempting to create a table struct with generic column types using templates. The subTable() member function subsets the table, however I am getting a template recursion error. I know where the problem is from, I don't know how to resolve it. I am modelling it after the matrix example in Ali Çehreli book: http://ddili.org/ders/d.en/templates_more.html

import std.stdio;

template ColumnTable(T...){
	struct ColumnTable{
	private:
		typeof(T) data;
		string[] names;
		struct Range{
			size_t begin;
			size_t end;
		}
        // This function is the source of the issue
	auto subTable(Range rowRange, Range columnRange)(){
		auto new_data = data[columnRange.begin .. columnRange.end];
		auto output = ColumnTable!(new_data)(new_data); // This is the problem
		string[] new_names = names[columnRange.begin .. columnRange.end];
		output.setNames(new_names);
		return output;
	}
	public:
		this(T...)(T args){
			data = args;
			foreach(i, arg; T){
				names ~= args[i].stringof;
			}
		}
		void setNames(string[] names){
			this.names = names;
		}
		void test(){
			writeln(subTable!(Range(0, 2), Range(0, 2))());
		}
	}
}


void main(){
	string[] names = ["tariq", "sharma", "peter", "rakel"];
	double[] salary = [44.5, 32.2, 40.1, 28.1];
	int[] age = [24, 20, 22, 25, 19];
	writeln(ColumnTable!(names, salary, age)(names, salary, age));
}

March 25, 2016
p.s. I realise that the ColumnTable call is a little ponderous but I tidy it up in a convenience wrapper function:

auto CreateDataTable(Args...)(){
	string[] names;
	foreach(i, arg; Args){
		names ~= Args[i].stringof;
	}
	auto df = ColumnTable!(Args)(Args);
	df.setNames(names);
	return df;
}


// auto myTable = CreateDataTable!(names, salary, age)();
March 25, 2016
WARNING: Do not try to compile this code. Your computer may be unresponsive for a while. :)

On 03/25/2016 02:54 PM, data pulverizer wrote:
> I am attempting to create a table struct with generic column types using
> templates.

However, the template arguments are not types; rather, aliases.

> template ColumnTable(T...){
>      struct ColumnTable{
>      private:
>          typeof(T) data;
>          string[] names;
>          struct Range{
>              size_t begin;
>              size_t end;
>          }
>          // This function is the source of the issue
>      auto subTable(Range rowRange, Range columnRange)(){
>          auto new_data = data[columnRange.begin .. columnRange.end];
>          auto output = ColumnTable!(new_data)(new_data); // This is the
> problem

new_data is a local variable. So, this instantiation of ColumnTable is with that symbol.

> void main(){
>      string[] names = ["tariq", "sharma", "peter", "rakel"];
>      double[] salary = [44.5, 32.2, 40.1, 28.1];
>      int[] age = [24, 20, 22, 25, 19];
>      writeln(ColumnTable!(names, salary, age)(names, salary, age));
> }

Likewise, that instantiation of ColumnTable is with the symbols 'names', 'salary', and 'age'. Is that what you want? Or do you want to instantiate with their types? Can you explain some more what you are trying to do.

Ali

March 26, 2016
On Saturday, 26 March 2016 at 06:28:42 UTC, Ali Çehreli wrote:
> WARNING: Do not try to compile this code. Your computer may be unresponsive for a while. :)
>
> On 03/25/2016 02:54 PM, data pulverizer wrote:
> > I am attempting to create a table struct with generic column
> types using
> > templates.
>
> However, the template arguments are not types; rather, aliases.
>
> > template ColumnTable(T...){
> >      struct ColumnTable{
> >      private:
> >          typeof(T) data;
> >          string[] names;
> >          struct Range{
> >              size_t begin;
> >              size_t end;
> >          }
> >          // This function is the source of the issue
> >      auto subTable(Range rowRange, Range columnRange)(){
> >          auto new_data = data[columnRange.begin ..
> columnRange.end];
> >          auto output = ColumnTable!(new_data)(new_data); //
> This is the
> > problem
>
> new_data is a local variable. So, this instantiation of ColumnTable is with that symbol.
>
> > void main(){
> >      string[] names = ["tariq", "sharma", "peter", "rakel"];
> >      double[] salary = [44.5, 32.2, 40.1, 28.1];
> >      int[] age = [24, 20, 22, 25, 19];
> >      writeln(ColumnTable!(names, salary, age)(names, salary,
> age));
> > }
>
> Likewise, that instantiation of ColumnTable is with the symbols 'names', 'salary', and 'age'. Is that what you want? Or do you want to instantiate with their types? Can you explain some more what you are trying to do.
>
> Ali

I am trying to build a table similar to R's dataframe but with unbounded data types. I am hoping that D's flexible template programming methods will allow table-like class or struct to be constructed with "naked" types i.e. unwrapped with variant. The ColumnTable object consists of vector columns that are bound together in a tuple - the data member and accessed in a similar way to your matrix example. The table will have column names and should be accessible by:

table[0..4, "colname"]
table[0..4, ["colname_1", "colname_2", "colname_3"]]
table[0..$, 0..4]

and should be able to be subsetted and inserted into by another table

table_1[0..4, 3..4] = table_2
table_1[0..4, ["colname_1", "colname_2"]] = table_2

and columns could be added or overwritten

table[0..$, 0] = someVector
table.columnBind(someVector)

column bind two table together ...

auto new_table = ColumnTable(table_1, table_2)
auto new_table = ColumnTable(table_1, someVector)

row bind two table having the same column characteristics

auto new_table = rbind(table_1, table_2)

Then perhaps do something similar for row-based tables.
March 26, 2016
On Saturday, 26 March 2016 at 06:28:42 UTC, Ali Çehreli wrote:
> Likewise, that instantiation of ColumnTable is with the symbols 'names', 'salary', and 'age'. Is that what you want? Or do you want to instantiate with their types? Can you explain some more what you are trying to do.
>
> Ali

I guess am trying to instantiate the class using symbols that should pass a tuple right to the data member. Does that mean that I need to use a mixin template instead of a template?
March 26, 2016
Please ignore my earlier response. :)

On 03/25/2016 02:54 PM, data pulverizer wrote:

> template ColumnTable(T...){
[...]
>          auto output = ColumnTable!(new_data)(new_data); // This is the
> problem

You want to slice the template arguments there. The following removes the infinite recursion:

        auto output = ColumnTable!(T[columnRange.begin .. columnRange.end])(new_data);

Ali

March 26, 2016
On Saturday, 26 March 2016 at 09:47:10 UTC, Ali Çehreli wrote:
> Please ignore my earlier response. :)
>
> On 03/25/2016 02:54 PM, data pulverizer wrote:
>
> > template ColumnTable(T...){
> [...]
> >          auto output = ColumnTable!(new_data)(new_data); //
> This is the
> > problem
>
> You want to slice the template arguments there. The following removes the infinite recursion:
>
>         auto output = ColumnTable!(T[columnRange.begin .. columnRange.end])(new_data);
>
> Ali

Thanks a lot! The subTable() method includes a loop to subset the rows which I forgot to include originally ...

auto subTable(Range rowRange, Range columnRange)(){
		auto new_data = data[columnRange.begin .. columnRange.end];
		foreach(i, col; new_data){
			new_data[i] = col[rowRange.begin .. rowRange.end];
		}
		auto output = ColumnTable!(T[columnRange.begin .. columnRange.end])(new_data);
		string[] new_names = names[columnRange.begin .. columnRange.end];
		output.setNames(new_names);
		return output;
	}