Re: Selected elements from splitter output

2021-05-04 Thread Chris Piker via Digitalmars-d-learn

On Tuesday, 4 May 2021 at 22:02:11 UTC, Ali Çehreli wrote:

On 5/4/21 1:40 PM, Chris Piker wrote:

> I only care about columns 0, 2, 3, 4, 8, 9, 10.

That's std.range.stride.

> char[][] wanted = string_range.get( [1, 5, 7] );  //
pseudo-code element

That's std.range.indexed.


Hey Thanks!

And even more, thanks for the book.  It's very well organized.  I 
keep a paper copy of "Programming in D" open on my desk all the 
time these days.  Looking forward to getting a few copies for 
work once we're back in the office.




Re: Pointer indirections

2021-05-04 Thread Ali Çehreli via Digitalmars-d-learn

On 5/4/21 3:06 PM, Imperatorn wrote:

>> Is there any limitation as to the number of pointer indirections?

No.

>> I have a construct:
>>a.b.c.d = x;
>> where all the variables are pointers to struct (the same struct).
>>
>> This fails with 'Access Violation',
>> but if I change the code to:
>>
>>  temp = a.b.c;
>>  temp.d = x;
>>
>> everything seems to work.

Sounds like "undefined behavior" somewhere in the program, effects of 
which can be confusing.


Ali



Re: Pointer indirections

2021-05-04 Thread Imperatorn via Digitalmars-d-learn

On Tuesday, 4 May 2021 at 21:16:10 UTC, DLearner wrote:

Hi

Is there any limitation as to the number of pointer 
indirections?


I have a construct:
   a.b.c.d = x;
where all the variables are pointers to struct (the same 
struct).


This fails with 'Access Violation',
but if I change the code to:

 temp = a.b.c;
 temp.d = x;

everything seems to work.

Best regards


Code or it didn't happen 


Re: Selected elements from splitter output

2021-05-04 Thread Ali Çehreli via Digitalmars-d-learn

On 5/4/21 3:02 PM, Ali Çehreli wrote:

>// Note: The above works only because 'stride' applies
>// "design by introspection" (DbI) and is able to work as a
>// RandomAccessRanges.

Ok, I was too enthusiastic there. The RandomAccessRange'ness of the 
input range changes how efficient stride() works but we can't say DbI is 
used there.


Ali




Re: Selected elements from splitter output

2021-05-04 Thread Ali Çehreli via Digitalmars-d-learn

On 5/4/21 1:40 PM, Chris Piker wrote:

> I only care about columns 0, 2, 3, 4, 8, 9, 10.

That's std.range.stride.

> char[][] wanted = string_range.get( [1, 5, 7] );  // pseudo-code element

That's std.range.indexed.

import std.range;
import std.stdio;

void main() {
  auto r = 10.iota.stride(2);
  writeln(r);

  writeln(r.indexed([1, 3]));

  // Note: The above works only because 'stride' applies
  // "design by introspection" (DbI) and is able to work as a
  // RandomAccessRanges. Not every range can do that; so, in a more
  // general case, you would have to turn your range to a
  // RandomAccessRange by calling std.array.array first:
  auto r2 = r.array;
  // The following can work with any InputRange only after doing that.
  writeln(r2.indexed([1, 3]));
}

Ali



Pointer indirections

2021-05-04 Thread DLearner via Digitalmars-d-learn

Hi

Is there any limitation as to the number of pointer indirections?

I have a construct:
   a.b.c.d = x;
where all the variables are pointers to struct (the same struct).

This fails with 'Access Violation',
but if I change the code to:

 temp = a.b.c;
 temp.d = x;

everything seems to work.

Best regards


Selected elements from splitter output

2021-05-04 Thread Chris Piker via Digitalmars-d-learn

Hi D

I have a white-space delimited file with quite a few columns, but 
I only care about columns 0, 2, 3, 4, 8, 9, 10.  Since I don't 
need most of the 60+ columns it seemed like:


   std.algorithm.iteration.splitter()

would be a better function to use then std.array.split().  My 
problem is that I don't know how to get the elements I care about 
from the splitter, for example:


char[] line;
char[][] cols_needed;
while(file.readln(line)){
   auto a = line.splitter()
   cols_needed = ???
}

On a related note, are there any standard library functions that 
select specific elements of a range by index without a loop?  So 
the logical equivalent of:


auto string_range
char[][] wanted = string_range.get( [1, 5, 7] );  // pseudo-code 
element selection


It's not a big deal if there's not something standard.

Thanks for the help,



Re: Should this always work?

2021-05-04 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Tuesday, 4 May 2021 at 14:18:30 UTC, Ola Fosheim Grøstad wrote:
On Tuesday, 4 May 2021 at 13:58:59 UTC, Steven Schveighoffer 
wrote:
Yeah, I wasn't aware of the more general usage, I thought it 
was always a pointer adjustment. But I also am not steeped in 
the terminology, just parroting what I've heard.


My understanding is that a thunk is the code object that 
fetches the value for you, in this case there might not be a 
thunk involved as the interface code can just apply a fixed 
offset?


I guess in D terms it can be best explained as a compiler 
internal "delegate". Let's take the example of getting the 
this-pointer:


Say, you want to write generic code gen, then you can let that 
code gen take a "delegate" that computes a this-pointer rather 
than writing many different code gens for different layouts. Then 
you trust the optimizer to get rid of it, or keep it if need be. 
That delegate would be a thunk. It may or may not exist at 
run-time based on the optimizer/language semantics.


You could also do something similar with an offset or switch 
statement. The point is, the code gen have no idea of how to 
obtain the this-pointer, the thunk does. It is a separate 
external code piece that obtains the value of the this-pointer.


Re: Should this always work?

2021-05-04 Thread Ola Fosheim Grøstad via Digitalmars-d-learn
On Tuesday, 4 May 2021 at 13:58:59 UTC, Steven Schveighoffer 
wrote:
Yeah, I wasn't aware of the more general usage, I thought it 
was always a pointer adjustment. But I also am not steeped in 
the terminology, just parroting what I've heard.


My understanding is that a thunk is the code object that fetches 
the value for you, in this case there might not be a thunk 
involved as the interface code can just apply a fixed offset?




Re: Should this always work?

2021-05-04 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/4/21 6:03 AM, Ola Fosheim Grøstad wrote:

On Tuesday, 4 May 2021 at 01:20:15 UTC, Q. Schroll wrote:

On Saturday, 1 May 2021 at 06:17:36 UTC, Mike Parker wrote:

On Saturday, 1 May 2021 at 04:55:10 UTC, frame wrote:
I always thought as long as an object implements an interface, it 
should be able to cast it from a void* if it really points to a 
supporting object.


No. An interface is like a pointer to a pointer.


Can you elaborate on this one? I don't really get it. Is an object 
handle also like a pointer to a pointer? (I feel like I can learn 
something here.)


Off the top of my head the object layout is something like this:
{
pointer to vtable0 for the class;
monitor mutex stuff;
pointer to interface 1 vtable1;
pointer to interface 2 vtable2;
...
pointer to interface N vtableN;
object data 1;
object data 2;
...
}


A pointer to interface 1 is a pointer to the pointer to vtable1 in the 
object above.




Yes, this is exactly how it is. See the ABI document:

https://dlang.org/spec/abi.html#classes

So a class reference is *also* a pointer to a pointer (to the vtable), 
and a interface reference is the same. However, the slight difference 
is, the pointer to the interface doesn't allow useful mechanisms until 
you apply the offset (necessitating a double indirection), whereas a 
class pointer (combined with compile-time type knowledge) the compiler 
can access member fields of the class.


-Steve


Re: Should this always work?

2021-05-04 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/4/21 9:21 AM, Paul Backus wrote:

On Tuesday, 4 May 2021 at 10:21:42 UTC, Ola Fosheim Grøstad wrote:

On Saturday, 1 May 2021 at 16:06:05 UTC, Steven Schveighoffer wrote:
An interface cast involves a thunk (constant pointer adjustment) to 
get to the interface/object


Yes, but it isn't a https://en.wikipedia.org/wiki/Thunk ?


The article literally gives this exact use-case as an example:

https://en.wikipedia.org/wiki/Thunk#Object-oriented_programming


Yeah, I wasn't aware of the more general usage, I thought it was always 
a pointer adjustment. But I also am not steeped in the terminology, just 
parroting what I've heard.


-Steve


Re: Should this always work?

2021-05-04 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 4 May 2021 at 01:20:15 UTC, Q. Schroll wrote:

On Saturday, 1 May 2021 at 06:17:36 UTC, Mike Parker wrote:


No. An interface is like a pointer to a pointer.


Can you elaborate on this one? I don't really get it. Is an 
object handle also like a pointer to a pointer? (I feel like I 
can learn something here.)


So I have no deep knowledge of the implementation details. I only 
know that a class reference is a pointer under the hood, so it 
can be cast to `void*` and back, and that an interface reference 
has an extra level of indirection, so it can go to `void**` and 
back.


Re: Should this always work?

2021-05-04 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 4 May 2021 at 10:21:42 UTC, Ola Fosheim Grøstad wrote:
On Saturday, 1 May 2021 at 16:06:05 UTC, Steven Schveighoffer 
wrote:
An interface cast involves a thunk (constant pointer 
adjustment) to get to the interface/object


Yes, but it isn't a https://en.wikipedia.org/wiki/Thunk ?


The article literally gives this exact use-case as an example:

https://en.wikipedia.org/wiki/Thunk#Object-oriented_programming


Re: How to automatically generate function overloads

2021-05-04 Thread Blatnik via Digitalmars-d-learn

On Tuesday, 4 May 2021 at 11:21:20 UTC, Zone wrote:

```D
template Vectorize_Unary_Function(alias fun) {
float[N] Vectorize_Unary_Function(size_t N)(float[N] vec)
{
float[N] result;
static foreach (i; 0 .. N)
result[i] = fun(vec[i]);
return result;
}
}

alias clamp01 = Vectorize_Unary_Function!clamp01;
```

Not exactly what you were asking for but I hope it works, 
tricky part is I'm not sure how to generate the function name 
without string mixins so that's why I used alias instead.


Awesome, this does exactly what I wanted. Thanks for the help! :)


Re: How to automatically generate function overloads

2021-05-04 Thread Zone via Digitalmars-d-learn

On Tuesday, 4 May 2021 at 11:00:42 UTC, Blatnik wrote:
I'm porting over my linear algebra library from C++, and I have 
a bunch of functions that work on both scalars and vectors. The 
vector versions just apply the scalar function to every element 
of the vector, for example:


```D
float clamp01(float x) { return x < 0 ? 0 : (x > 1 ? 1 : x); }

float[N] clamp01(size_t N)(float[N] vec)
{
  float[N] result;
  static foreach (i; 0 .. N)
result[i] = clamp01(vec[i]);

  return result;
}
```

And this is great, I don't have to write the same function for 
different array lengths.


But I still have like 30-ish of these functions and I would 
like to generate the array overload automatically from the 
scalar overload.


So I would like something like a mixin, that I can use like 
this:


```D
mixin Vectorize_Unary_Function!clamp01; // Generates the code 
above.

mixin Vectorize_Unary_Function!floor;
mixin Vectorize_Unary_Function!ceil;
...
```

It doesn't have to be a mixin like this. I don't really care 
what it is as long as it works :)


How could I do this?

```D
float clamp01(float x) { return x < 0 ? 0 : (x > 1 ? 1 : x); }

template Vectorize_Unary_Function(alias fun) {
float[N] Vectorize_Unary_Function(size_t N)(float[N] vec)
{
float[N] result;
static foreach (i; 0 .. N)
result[i] = fun(vec[i]);
return result;
}
}

alias clamp01 = Vectorize_Unary_Function!clamp01;


void main() {
float[5] vec = [1,2,3,4,5];
float[5] other = clamp01(vec);
writeln(vec);
writeln(other);
}
```

Not exactly what you were asking for but I hope it works, tricky 
part is I'm not sure how to generate the function name without 
string mixins so that's why I used alias instead.


Re: How to automatically generate function overloads

2021-05-04 Thread Blatnik via Digitalmars-d-learn

On Tuesday, 4 May 2021 at 11:00:42 UTC, Blatnik wrote:

How could I do this?


I've already tried this:

```D
mixin template Vectorize_Unary_Function(alias Function)
{
  float[N] Function(size_t N)(float[N] vec)
  {
float[N] result;
static foreach (i; 0 .. N)
  result[i] = Function(vec[i]);
return result;
  }
}
```

But it didn't work.

```D
mixin Vectorize_Unary_Function!clamp01;

float[2] vec = [1, 2];
float[2] clamped = clamp01(vec); // Error
```

I think it actually declared a function called "Function" instead 
of calling it "clamp01" like the alias I passed in.


How to automatically generate function overloads

2021-05-04 Thread Blatnik via Digitalmars-d-learn
I'm porting over my linear algebra library from C++, and I have a 
bunch of functions that work on both scalars and vectors. The 
vector versions just apply the scalar function to every element 
of the vector, for example:


```D
float clamp01(float x) { return x < 0 ? 0 : (x > 1 ? 1 : x); }

float[N] clamp01(size_t N)(float[N] vec)
{
  float[N] result;
  static foreach (i; 0 .. N)
result[i] = clamp01(vec[i]);

  return result;
}
```

And this is great, I don't have to write the same function for 
different array lengths.


But I still have like 30-ish of these functions and I would like 
to generate the array overload automatically from the scalar 
overload.


So I would like something like a mixin, that I can use like this:

```D
mixin Vectorize_Unary_Function!clamp01; // Generates the code 
above.

mixin Vectorize_Unary_Function!floor;
mixin Vectorize_Unary_Function!ceil;
...
```

It doesn't have to be a mixin like this. I don't really care what 
it is as long as it works :)


How could I do this?


Re: Should this always work?

2021-05-04 Thread Ola Fosheim Grøstad via Digitalmars-d-learn
On Saturday, 1 May 2021 at 16:06:05 UTC, Steven Schveighoffer 
wrote:
An interface cast involves a thunk (constant pointer 
adjustment) to get to the interface/object


Yes, but it isn't a https://en.wikipedia.org/wiki/Thunk ?




Re: Should this always work?

2021-05-04 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Tuesday, 4 May 2021 at 01:20:15 UTC, Q. Schroll wrote:

On Saturday, 1 May 2021 at 06:17:36 UTC, Mike Parker wrote:

On Saturday, 1 May 2021 at 04:55:10 UTC, frame wrote:
I always thought as long as an object implements an 
interface, it should be able to cast it from a void* if it 
really points to a supporting object.


No. An interface is like a pointer to a pointer.


Can you elaborate on this one? I don't really get it. Is an 
object handle also like a pointer to a pointer? (I feel like I 
can learn something here.)


Off the top of my head the object layout is something like this:
{
pointer to vtable0 for the class;
monitor mutex stuff;
pointer to interface 1 vtable1;
pointer to interface 2 vtable2;
...
pointer to interface N vtableN;
object data 1;
object data 2;
...
}


A pointer to interface 1 is a pointer to the pointer to vtable1 
in the object above.