Re: How to obtain Variant underlying type?

2022-07-11 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 11 July 2022 at 06:59:32 UTC, anonymouse wrote:

I did search for a better solution and came across...
https://tastyminerals.github.io/tasty-blog/dlang/2020/03/22/multidimensional_arrays_in_d.html


I like it!

It's been a good collaboration...

```d
import std.variant;

auto generate(T)(size_t x, size_t y) {
  T[][] result;
  ubyte[] arr = new ubyte[x * y * T.sizeof];
  size_t m = y * T.sizeof;

  foreach (i; 0 .. x) {
size_t n = i * m;
    result ~= cast(T[])arr[n .. n + m];
  }
  return result;
}

size_t[] shape(Variant v) {
  typeof(return) dims;

  while (cast(TypeInfo_Array) v.type !is null) {
    dims ~= v.length;
v = v[0];
  }

  if (!dims.length && v.length) {
    dims ~= v.length;
dims ~= 0;
  }
  return dims;
}

void main() {
  foreach(x; 1..100) {
    foreach(y; 1..100) {
      auto test = Variant(generate!int(x, y));
      assert(shape(test) == [x, y]);
    }
  }
}
```

SDB@79


Re: How to obtain Variant underlying type?

2022-07-11 Thread anonymouse via Digitalmars-d-learn

On Monday, 11 July 2022 at 05:41:40 UTC, jfondren wrote:


Oh, sorry. I didn't defend the code in any way because I 
assumed that the exceptional design would be seen as obviously 
bad (and that someone else would dig harder in order to find a 
better solution).


And you were right. I did search for a better solution and came 
across [1]. Although I was having some issues adapting it for my 
use case, Paul Backus' follow-up clarified the issue. This is 
what my naive brain led to before reading this response.


```d
size_t[] shape(Variant v)
{
typeof(return) dims;

while(cast(TypeInfo_Array) v.type !is null) {
dims ~= v.length;
v = v[0];
}

if(!dims.length && v.length) {
dims ~= v.length;
dims ~= 0;
}

return dims;
}
```

Didn't see the bugs that would occur when a scalar or empty array 
was passed because I hadn't tested for them.



if (!v.length) break;


Pure gold! Bugs are eliminated, and the code is shorter. Thank 
you.


--anonymouse

[1] 
https://tastyminerals.github.io/tasty-blog/dlang/2020/03/22/multidimensional_arrays_in_d.html


Re: How to obtain Variant underlying type?

2022-07-11 Thread anonymouse via Digitalmars-d-learn

On Sunday, 10 July 2022 at 19:14:34 UTC, Paul Backus wrote:


For reference, this is the more correct way:

```d
while (cast(TypeInfo_Array) v.type !is null) {
Variant elem = v[0];
// etc.
}
```

Hard to blame anyone for not coming up with that on their first 
try, especially since `TypeInfo_Array` is not even 
documented--you have to read the source of `object.d` to find 
out about it.


I honestly cannot say why but I was having a problem using this 
earlier. After several hours of frustration, I rebooted the 
computer, went for a run, came back, and tried again. It works!!! 
Thank you very much.


--anonymouse




Re: How to obtain Variant underlying type?

2022-07-10 Thread jfondren via Digitalmars-d-learn

On Monday, 11 July 2022 at 03:17:33 UTC, anonymouse wrote:

On Sunday, 10 July 2022 at 18:31:46 UTC, drug007 wrote:


I'd like to say that using of exception to break loop is 
really bad. Exception is exceptional thing but in the case 
above the exception is ordinary completion of the loop happens 
on regular basis. Don't do that.


Thanks for the advice. Lesson learned.

--anonymouse


Oh, sorry. I didn't defend the code in any way because I assumed 
that the exceptional design would be seen as obviously bad (and 
that someone else would dig harder in order to find a better 
solution).


The TypeInfo_Array fix breaks the last assertion of those unit 
tests, though. This works:


```d
import std.variant : Variant;

size_t[] shape(Variant v) {
size_t[] s;
while (cast(TypeInfo_Array) v.type !is null && v.length > 0) {
Variant elem = v[0];
s ~= v.length;
v = elem;
}
return s;
}
```

Although, that last assertion really is debatable. Languages like 
APL would read it as having a shape of [2, 0]:


```d
import std.variant : Variant;

size_t[] shape(Variant v) {
size_t[] s;
while (cast(TypeInfo_Array) v.type !is null) {
s ~= v.length;
if (!v.length) break;
v = v[0];
}
return s;
}

unittest {
assert([3, 1] == [[1], [2], [3]].Variant.shape);
assert([2, 1] == [[1], [2]].Variant.shape);
assert([2, 2] == [[1, 0], [2, 0]].Variant.shape);
assert([2] == [1, 2].Variant.shape);
assert([] == 2.Variant.shape);
assert([2, 0] == [[], []].Variant.shape);

// irregularity not checked
assert([2, 2] == [[1, 0], [2]].Variant.shape);
}
```


Re: How to obtain Variant underlying type?

2022-07-10 Thread anonymouse via Digitalmars-d-learn

On Sunday, 10 July 2022 at 18:31:46 UTC, drug007 wrote:


I'd like to say that using of exception to break loop is really 
bad. Exception is exceptional thing but in the case above the 
exception is ordinary completion of the loop happens on regular 
basis. Don't do that.


Thanks for the advice. Lesson learned.

--anonymouse


Re: How to obtain Variant underlying type?

2022-07-10 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 10 July 2022 at 18:31:46 UTC, drug007 wrote:

On 7/10/22 20:26, anonymouse wrote:

On Sunday, 10 July 2022 at 06:26:37 UTC, jfondren wrote:

```d
import std.variant : Variant;

size_t[] shape(Variant v) {
    import std.variant : VariantException;

    size_t[] s;
    try {
    while (true) {
    Variant elem = v[0];
    s ~= v.length;
    v = elem;
    }
    } catch (VariantException e) {
    return s;
    }
}
```


Thank you very much.



I'd like to say that using of exception to break loop is really 
bad. Exception is exceptional thing but in the case above the 
exception is ordinary completion of the loop happens on regular 
basis. Don't do that.


For reference, this is the more correct way:

```d
while (cast(TypeInfo_Array) v.type !is null) {
Variant elem = v[0];
// etc.
}
```

Hard to blame anyone for not coming up with that on their first 
try, especially since `TypeInfo_Array` is not even 
documented--you have to read the source of `object.d` to find out 
about it.


Re: How to obtain Variant underlying type?

2022-07-10 Thread anonymouse via Digitalmars-d-learn

On Sunday, 10 July 2022 at 06:26:37 UTC, jfondren wrote:

```d
import std.variant : Variant;

size_t[] shape(Variant v) {
import std.variant : VariantException;

size_t[] s;
try {
while (true) {
Variant elem = v[0];
s ~= v.length;
v = elem;
}
} catch (VariantException e) {
return s;
}
}
```


Thank you very much.



Re: How to obtain Variant underlying type?

2022-07-10 Thread jfondren via Digitalmars-d-learn

On Saturday, 9 July 2022 at 23:04:20 UTC, anonymouse wrote:

On Saturday, 9 July 2022 at 14:46:36 UTC, Adam D Ruppe wrote:


Impossible; Variant's type is only known at runtime, and this 
would require compile time knowledge.


Hmmm. Okay, thanks. What I really need to know is how many 
dimensions an array has and the total elements per dimension so 
that I can create temporary storage for it later.


 this(T)(T a)
 in(imported!"std.traits".isDynamic!T)
 {
 data = a; // data is of type Variant
 shape = [a.length, {?, ...}]; // what's the best way 
to deterine?

 }

Thanks,
--anonymouse


```d
import std.variant : Variant;

size_t[] shape(Variant v) {
import std.variant : VariantException;

size_t[] s;
try {
while (true) {
Variant elem = v[0];
s ~= v.length;
v = elem;
}
} catch (VariantException e) {
return s;
}
}

unittest {
assert([3, 1] == [[1], [2], [3]].Variant.shape);
assert([2, 1] == [[1], [2]].Variant.shape);
assert([2, 2] == [[1, 0], [2, 0]].Variant.shape);
assert([2] == [1, 2].Variant.shape);
assert([] == 2.Variant.shape);

// irregularity not checked
assert([2, 2] == [[1, 0], [2]].Variant.shape);
// arguably should be [2, 0]
assert([2] == [[], []].Variant.shape);
}
```


Re: How to obtain Variant underlying type?

2022-07-09 Thread anonymouse via Digitalmars-d-learn

On Saturday, 9 July 2022 at 14:46:36 UTC, Adam D Ruppe wrote:


Impossible; Variant's type is only known at runtime, and this 
would require compile time knowledge.


Hmmm. Okay, thanks. What I really need to know is how many 
dimensions an array has and the total elements per dimension so 
that I can create temporary storage for it later.


 this(T)(T a)
 in(imported!"std.traits".isDynamic!T)
 {
 data = a; // data is of type Variant
 shape = [a.length, {?, ...}]; // what's the best way to 
deterine?

 }

Thanks,
--anonymouse


Re: How to obtain Variant underlying type?

2022-07-09 Thread Adam D Ruppe via Digitalmars-d-learn

On Saturday, 9 July 2022 at 14:36:44 UTC, anonymouse wrote:
 auto vb = v.base; // what should I put here to achieve the 
following:

 typeof(vb); // int[][]


Impossible; Variant's type is only known at runtime, and this 
would require compile time knowledge.