Re: how to do this meta-programming? print the address of random element's address of a variable length of arrays?

2020-09-13 Thread mw via Digitalmars-d-learn

On Sunday, 13 September 2020 at 01:25:43 UTC, mw wrote:

On Saturday, 12 September 2020 at 20:29:40 UTC, Paul Backus
If you have a "real-life" application in mind for this, I'd be 
curious to hear what it is.


I'm wrapping a C library, trying to write a single D function / 
template that can work with a group of C functions, hence I 
need that kind of signature I described.


I'll post the code when I'm ready.


Here it is: D wrapper for https://ta-lib.org/

https://github.com/mingwugmail/talibd

I end up using C macro to generate D functions, the single 
template is this one:


https://github.com/mingwugmail/talibd/blob/master/source/talibd.h#L117
#define DECL_TA_FUNC(TA_FUNC, FUNC_INS, FUNC_OUTS, 
expected_lookback) __NL__\



and the macro instantiations are on line 144, 158, 168:

DECL_TA_FUNC(TA_MA, MA_INS, MA_OUTS, (MA_optInTimePeriod-1))
DECL_TA_FUNC(TA_RSI, RSI_INS, RSI_OUTS, RSI_optInTimePeriod)
DECL_TA_FUNC(TA_MACD, MACD_INS, MACD_OUTS, 
(optInSlowPeriod+optInSignalPeriod-2))



the generated D functions are here:

https://github.com/mingwugmail/talibd/blob/master/source/talibd.d#L47

you can take a look of the 3 generated functions to see the 
similarities, and pay attention to:


-- func decl: TA_xxx( ,  )
-- assertions on 
-- func calls: TA_xxx_Lookback()
-- func call: talib.TA_xxx(, arrays>, )



There are a number of C macro tricks was used, which I just did 
some googling to be able to get it done in C -- and with the 
added benefits that I can directly see the generated source file 
to debug in the development process.



I think it's a non-trivial task to get this compile-time 
meta-programming done in D, if it can be done at all (I'm not 
sure).



Anyone want to give it a try? and submit a PR :-)



Re: Why does a directly defined constructor hide a mixed-in constructor?

2020-09-13 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 13 September 2020 at 12:34:06 UTC, 60rntogo wrote:
However, if I directly insert the contents of X into Bar 
instead of mixing it in, it compiles just fine. What's going on 
here?


You can override members from mixin templates by giving a member 
with the same *name* (not the same signature!) directly.


mixin template foo() { int a; }

class Thing { mixin foo; string a; /* this a overrides foo's a */ 
}



This is pretty useful in a lot of cases but kinda annoying with 
overloading. To overload, you must use `alias` to merge the 
overload sets. For constructors, you need to use the name 
`__ctor` instead of `this` to make it compile:


```
struct Bar
{
  mixin X some_name; // notice the addition of a name

  this(Foo foo)
  {
this.x = [0, 0];
  }

  alias __ctor = some_name.__ctor; // merge the overloads
}
```

Read more here:

http://dpldocs.info/this-week-in-d/Blog.Posted_2020_01_20.html#understanding-mixin-templates

and here too:

https://stackoverflow.com/a/57712459/1457000


Re: how to do this meta-programming? print the address of random element's address of a variable length of arrays?

2020-09-13 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 13 September 2020 at 07:00:36 UTC, mw wrote:


Here it is: D wrapper for https://ta-lib.org/

https://github.com/mingwugmail/talibd

I end up using C macro to generate D functions, the single 
template is this one:


https://github.com/mingwugmail/talibd/blob/master/source/talibd.h#L117
#define DECL_TA_FUNC(TA_FUNC, FUNC_INS, FUNC_OUTS, 
expected_lookback) __NL__\


The most straightforward way to do this in D is with a mixin 
template. Something like:


mixin template DECL_TA_FUNC(string TA_FUNC, FUNC_INS, FUNC_OUTS, 
int expected_lookback)

{
bool impl(...)
{
// ...
}

// Could also wrap the whole function in a string mixin,
// but this is easier.
mixin("alias ", TA_FUNC, " = impl;");
}

Which you would then use like this:

mixin DECL_TA_FUNC!(
"TA_MA",
Tuple!(int, "MA_optInTimePeriod", TA_MAType, "opInMAType"),
Tuple!(double[], "outMA"),
MA_optInTimePeriod - 1
);


Why does a directly defined constructor hide a mixed-in constructor?

2020-09-13 Thread 60rntogo via Digitalmars-d-learn

This code:

---
mixin template X()
{
  int[2] x;

  this(int[2] x...)
  {
this.x = x;
  }
}

struct Foo
{
}

struct Bar
{
  mixin X;

  this(Foo foo)
  {
this.x = [0, 0];
  }
}

void main()
{
  auto bar = Bar(1, 2);
}
---

produces the following error:

---
source/app.d(27,17): Error: constructor app.Bar.this(Foo foo) is 
not callable using argument types (int, int)
source/app.d(27,17):cannot pass argument 1 of type int to 
parameter Foo foo

---

However, if I directly insert the contents of X into Bar instead 
of mixing it in, it compiles just fine. What's going on here?


passing a parrameter read-only ref?

2020-09-13 Thread Martin via Digitalmars-d-learn

Hi,
i would like to create a function which takes the first parameter 
as a reference to a struct - but assure the calle that the 
reference is read-only. Can this be done?


If i am not mistaken, then the "in" Parameter Storage Class is 
what i want(?). But the documentation states that this feature 
should not be used.


For context: I want to write struct-methods outside the struct 
(like in golang).


Red-Black Gauss-seidel with mir

2020-09-13 Thread Christoph via Digitalmars-d-learn

Hi all,

I am trying to implement a sweep method for a 2D Red-black 
Gauss-Seidel Solver with the help of mir and its slices.

The fastest Version I discovered so far looks like this:
```
void sweep(T, size_t Dim : 2, Color color)(in Slice!(T*, 2) F, 
Slice!(T*, 2) U, T h2)

{
const auto m = F.shape[0];
const auto n = F.shape[1];
auto UF = U.field;
auto FF = F.field;

foreach (i; 1 .. m - 1)
{
for (size_t j = 1 + (i + 1 + color) % 2; j < n - 1; j += 
2)

{
auto flatindex = i * m + j;
UF[flatindex] = (
UF[flatindex - m] +
UF[flatindex + m] +
UF[flatindex - 1] +
UF[flatindex + 1] - h2 * FF[flatindex]) / 4.0;
}
}
}
```
Accessing the field of the mirslice directly seems to be 
incredibly fast and I assume this might be the fastest version 
for this purpose?


I have already implemented this in Python with numpy and there it 
looks like this:


```
def sweep_2D(color, F, U, h2):

m, n = F.shape

if color == 1:
# red
U[1:m - 1:2, 2:n - 1:2] = (U[0:m - 2:2, 2:n - 1:2] +
   U[2::2, 2:n - 1:2] +
   U[1:m - 1:2, 1:n - 2:2] +
   U[1:m - 1:2, 3::2] -
   F[1:m - 1:2, 2:n - 1:2] * h2) 
/ (4.0)

U[2:m - 1:2, 1:n - 1:2] = (U[1:m - 2:2, 1:n - 1:2] +
   U[3::2, 1:n - 1:2] +
   U[2:m - 1:2, 0:n - 2:2] +
   U[2:m - 1:2, 2::2] -
   F[2:m - 1:2, 1:n - 1:2] * h2) 
/ (4.0)

...

```
My Question now is: Is there a possibility too use the mir slices 
in a way that "looks" similar to the numpy version and is similar 
fast?
Below there is fastest version I found up to now, but it is still 
much slower then the version with the two for loops. It seems to 
me, that accessing and modifying only parts of a mirslice with 
this "indexed" syntax in combination with strided is really slow. 
Is this true or am I using the slices wrong?


```
static if (color == Color.red)
{
U[1 .. m - 1, 1 .. n - 1].strided!(0, 1)(2, 2)[] = U[0 .. 
m - 2, 1 .. n - 1].strided!(0, 1)(2, 2) / 4.0;
U[1 .. m - 1, 1 .. n - 1].strided!(0, 1)(2, 2)[] += U[2 
.. m, 1 .. n - 1].strided!(0, 1)(2, 2) / 4.0;
U[1 .. m - 1, 1 .. n - 1].strided!(0, 1)(2, 2)[] += U[1 
.. m - 1, 0 .. n - 2].strided!(0, 1)(2, 2) / 4.0;
U[1 .. m - 1, 1 .. n - 1].strided!(0, 1)(2, 2)[] += U[1 
.. m - 1, 2 .. n].strided!(0, 1)(2, 2) / 4.0;
U[1 .. m - 1, 1 .. n - 1].strided!(0, 1)(2, 2)[] -= F[1 
.. m - 1, 1 .. n - 1].strided!(0, 1)(2, 2) * h2 / 4.0;


U[2 .. m - 1, 2 .. n - 1].strided!(0, 1)(2, 2)[] = U[1 .. 
m - 2, 2 .. n - 1].strided!(0, 1)(2, 2) / 4.0;
U[2 .. m - 1, 2 .. n - 1].strided!(0, 1)(2, 2)[] += U[3 
.. m, 2 .. n - 1].strided!(0, 1)(2, 2) / 4.0;
U[2 .. m - 1, 2 .. n - 1].strided!(0, 1)(2, 2)[] += U[2 
.. m - 1, 1 .. n - 2].strided!(0, 1)(2, 2) / 4.0;
U[2 .. m - 1, 2 .. n - 1].strided!(0, 1)(2, 2)[] += U[2 
.. m - 1, 3 .. n].strided!(0, 1)(2, 2) / 4.0;
U[2 .. m - 1, 2 .. n - 1].strided!(0, 1)(2, 2)[] -= F[2 
.. m - 1, 2 .. n - 1].strided!(0, 1)(2, 2) * h2 / 4.0;


}
...

```

Thanks for your help in Advance!

Christoph



Re: Why does a directly defined constructor hide a mixed-in constructor?

2020-09-13 Thread 60rntogo via Digitalmars-d-learn

On Sunday, 13 September 2020 at 13:10:15 UTC, Adam D. Ruppe wrote:
This is pretty useful in a lot of cases but kinda annoying with 
overloading. To overload, you must use `alias` to merge the 
overload sets. For constructors, you need to use the name 
`__ctor` instead of `this` to make it compile:


Yes, that works. Thanks!


Re: passing a parrameter read-only ref?

2020-09-13 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 13 September 2020 at 13:35:15 UTC, Martin wrote:

Hi,
i would like to create a function which takes the first 
parameter as a reference to a struct - but assure the calle 
that the reference is read-only. Can this be done?


Yes, you can do this with `ref const`.


Call C variadic function from D variadic function

2020-09-13 Thread James Blachly via Digitalmars-d-learn

Summary:
Can a typesafe D variadic function, or D variadic template pass its 
parameters to a C variadic function?


Background:
I maintain a library binding [0] to htslib, a high-performance and very 
widely used C library for high-throughput sequencing (hts) data files. 
We use this internally and haven't polished it for a release on the 
announce forum or biomed twitter, etc. yet.


In the course of upgrading it to support the latest API/ABI (htslib-1.10 
/ so.3), I need to add support for several new functions.


One of these is a variadic function with the signature:

`int sam_hdr_add_line(sam_hdr_t *h, const char *type, ...);`

Of course, we can call this directly from D with hardcoded parameters. 
However, one of the focuses of our library is "bindings + wrappers" to 
make this feel more like native D. Thus, we want a variadic function to 
which we may pass D strings (it is also a struct member function).


With help from Herringway on IRC, we came up with a solution using mixin:


```
/// Add a single line to an existing header
auto addLine(T...)(RecordType type, T kvargs)
if(kvargs.length > 0 && isSomeString!(T[0]))
{
static assert (kvargs.length %2 == 0);   // K-V pairs => even 
number of variadic args


string varargMagic(size_t len)
{
string args = "sam_hdr_add_line(this.h, type.ptr, ";
for(int i=0; iInterestingly, compilation fails if the mixin consists only of the 
comma-separated parameters ("Comma expression" [1])



Question:
If a variadic template, despite presenting to the user a "dynamic 
array", MUST know its parameter list at compile-time, is there a way 
(other than with mixins as shown) to pass this parameter list to 
extern(C) linkage function with variadic parameters?



(bonus question: if yes, can it be done with typesafe variadic function 
where I believe parameter list is known at either compile time OR 
runtime, depending on how called)



Thanks all in advance



[0] dhtslib
https://code.dlang.org/packages/dhtslib
https://github.com/blachlylab/dhtslib

[1] https://dlang.org/spec/expression.html#expression


Re: Call C variadic function from D variadic function

2020-09-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/13/20 12:55 PM, James Blachly wrote:

Summary:
Can a typesafe D variadic function, or D variadic template pass its 
parameters to a C variadic function?


Background:
I maintain a library binding [0] to htslib, a high-performance and very 
widely used C library for high-throughput sequencing (hts) data files. 
We use this internally and haven't polished it for a release on the 
announce forum or biomed twitter, etc. yet.


In the course of upgrading it to support the latest API/ABI (htslib-1.10 
/ so.3), I need to add support for several new functions.


One of these is a variadic function with the signature:

`int sam_hdr_add_line(sam_hdr_t *h, const char *type, ...);`

Of course, we can call this directly from D with hardcoded parameters. 
However, one of the focuses of our library is "bindings + wrappers" to 
make this feel more like native D. Thus, we want a variadic function to 
which we may pass D strings (it is also a struct member function).


With help from Herringway on IRC, we came up with a solution using mixin:


```
     /// Add a single line to an existing header
     auto addLine(T...)(RecordType type, T kvargs)
     if(kvargs.length > 0 && isSomeString!(T[0]))
     {
     static assert (kvargs.length %2 == 0);   // K-V pairs => even 
number of variadic args


     string varargMagic(size_t len)
     {
     string args = "sam_hdr_add_line(this.h, type.ptr, ";
     for(int i=0; iInterestingly, compilation fails if the mixin consists only of the 
comma-separated parameters ("Comma expression" [1])



Question:
If a variadic template, despite presenting to the user a "dynamic 
array", MUST know its parameter list at compile-time, is there a way 
(other than with mixins as shown) to pass this parameter list to 
extern(C) linkage function with variadic parameters?


Was just talking about this exact problem with Adam Ruppe. 
Unfortunately, because the parameters are an expression tuple, and not a 
compile-time tuple, you can't use stuff like staticMap.


Manu's ... dip would be perfect for this:

return sam_hdr_add_line(this.h, this.ptr, toStringz(kvargs)..., null);

I think the only way it works today is if you use the mixin technique.

-Steve


Re: Call C variadic function from D variadic function

2020-09-13 Thread Paul Backus via Digitalmars-d-learn
On Sunday, 13 September 2020 at 17:23:42 UTC, Steven 
Schveighoffer wrote:

On 9/13/20 12:55 PM, James Blachly wrote:


```
     /// Add a single line to an existing header
     auto addLine(T...)(RecordType type, T kvargs)
     if(kvargs.length > 0 && isSomeString!(T[0]))
     {
     static assert (kvargs.length %2 == 0);   // K-V pairs 
=> even number of variadic args


     string varargMagic(size_t len)
     {
     string args = "sam_hdr_add_line(this.h, type.ptr, 
";

     for(int i=0; i     args ~= "toStringz(kvargs[" ~ i.to!string ~ 
"]), ";

     args ~= "null)";
     return args;
     }

     return mixin(varargMagic(kvargs.length));
     }
```

Interestingly, compilation fails if the mixin consists only of 
the comma-separated parameters ("Comma expression" [1])



Question:
If a variadic template, despite presenting to the user a 
"dynamic array", MUST know its parameter list at compile-time, 
is there a way (other than with mixins as shown) to pass this 
parameter list to extern(C) linkage function with variadic 
parameters?


Was just talking about this exact problem with Adam Ruppe. 
Unfortunately, because the parameters are an expression tuple, 
and not a compile-time tuple, you can't use stuff like 
staticMap.


You actually can, if you define the right kind of helper function:

/// Add a single line to an existing header
auto addLine(T...)(RecordType type, T kvargs)
if(kvargs.length > 0 && isSomeString!(T[0]))
{
static assert (kvargs.length %2 == 0);   // K-V pairs => 
even number of variadic args

immtuable(char)* argToStringz(alias arg)()
{
return toStringz(arg);
}

return sam_hdr_add_line(this.h, this.ptr, 
staticMap!(argToStringz, kvargs), null);

}

The clever trick here is that, because of optional parentheses 
[1], `argToStringz!(kvargs[i])` can be interpreted either as the 
name of a function or a function call, depending on the context 
it appears in.


[1] https://dlang.org/spec/function.html#optional-parenthesis


Re: how to do this meta-programming? print the address of random element's address of a variable length of arrays?

2020-09-13 Thread mw via Digitalmars-d-learn

On Sunday, 13 September 2020 at 10:16:46 UTC, Paul Backus wrote:

On Sunday, 13 September 2020 at 07:00:36 UTC, mw wrote:


Here it is: D wrapper for https://ta-lib.org/

https://github.com/mingwugmail/talibd

I end up using C macro to generate D functions, the single 
template is this one:


https://github.com/mingwugmail/talibd/blob/master/source/talibd.h#L117
#define DECL_TA_FUNC(TA_FUNC, FUNC_INS, FUNC_OUTS, 
expected_lookback) __NL__\


The most straightforward way to do this in D is with a mixin 
template. Something like:


mixin template DECL_TA_FUNC(string TA_FUNC, FUNC_INS, 
FUNC_OUTS, int expected_lookback)

{
bool impl(...)
{
// ...
}

// Could also wrap the whole function in a string mixin,
// but this is easier.
mixin("alias ", TA_FUNC, " = impl;");
}

Which you would then use like this:

mixin DECL_TA_FUNC!(
"TA_MA",
Tuple!(int, "MA_optInTimePeriod", TA_MAType, "opInMAType"),
Tuple!(double[], "outMA"),
MA_optInTimePeriod - 1
);



Thanks, I will do the exercise some other day.

But, I'd reflect on my experience so far on compile-time 
meta-programming in D as a novice user, the big problems are:


-- in D, there are too many choices, with no clear guideline 
which one is *THE* one to use for a particular purpose: language 
or library mechanisms? mixin? template? AliasSeq / aliasSeqOf? 
Tuple? (non-)?-eponymous version of ...?; and even for a 
particular option, e.g. Tuple!(int, "MA_optInTimePeriod", 
TA_MAType, "opInMAType"),  there are choices to use either token 
(int) or string ("MA_optInTimePeriod"). And user does not have a 
strong guide on which choice is *THE* way to proceed. Each 
mechanism seems to have / fit a particular purpose, but when you 
start to use it, you'll probably find there are new problems 
come-in later, and you want to revisit the choice you made 
earlier on.


By contrast, in C: there is only *ONE* mechanism, i.e. macro, 
that's it.


-- in D, there is no easy way to convert between token <==> 
string. Given a token, does token.stringof always work to paste 
with other strings to generate a new token? and given a string, 
does mixin!"string" always work to be a valid token?


By contrast, in C: there is only *ONE* way: xxx ## yyy.

-- in D, there is no easy way to see directly the generated 
source code by the compiler at compile-time, which makes the 
debug difficult during development.


By contrast, in C: one can easily see the result via: cpp -P 
foo.h > foo.c



As I said earlier, I'm not very experienced with C macros either, 
however with some googling, I was able to work out a C macro 
version to generate D code; but with all the help so far, I still 
have no confidence that I can work out a solution in D to 
implement this:


```
 bool impl(...)
 {
 // ...
 }
```



Re: Call C variadic function from D variadic function

2020-09-13 Thread ag0aep6g via Digitalmars-d-learn

```
     /// Add a single line to an existing header
     auto addLine(T...)(RecordType type, T kvargs)
     if(kvargs.length > 0 && isSomeString!(T[0]))
     {
     static assert (kvargs.length %2 == 0);   // K-V pairs => even 
number of variadic args


     string varargMagic(size_t len)
     {
     string args = "sam_hdr_add_line(this.h, type.ptr, ";
     for(int i=0; i
[...]

Question:
If a variadic template, despite presenting to the user a "dynamic 
array", MUST know its parameter list at compile-time, is there a way 
(other than with mixins as shown) to pass this parameter list to 
extern(C) linkage function with variadic parameters?


Easy peasy:

import std.meta: Repeat;
Repeat!(kvargs.length, const(char)*) zs;
foreach (i, ref z; zs) z = toStringz(kvargs[i]);
return sam_hdr_add_line(this.h, type.ptr, zs, null);

By the way, `kvargs` is not a dynamic array. Its length is not dynamic, 
and it's not an array.


Also, you don't just want to pass the parameters forward. That would be 
trivial: `sam_hdr_add_line(this.h, type.ptr, kvargs, null)`. You want to 
run them through another function first. That's where the difficulty 
comes from.


(bonus question: if yes, can it be done with typesafe variadic function 
where I believe parameter list is known at either compile time OR 
runtime, depending on how called)


I don't see when it would matter how the function is called, but you can 
declare it in two different ways:


1) True typesafe variadic:

auto addLine(RecordType type, string[] kvargs ...)

2) Template + typesafe variadic:

auto addLine(size_t n)(RecordType type, string[n] kvargs ...)

In the first one, `kvargs.length` is a dynamic value. You can't use it 
to generate the arguments for a `sam_hdr_add_line` call.


In the second one, `kvargs.length` is a static value. So you can do the 
same things as in the `T...` template. And just like the `T...` 
template, it will generate a new function for every distinct 
`kvargs.length`.


Re: Call C variadic function from D variadic function

2020-09-13 Thread James Blachly via Digitalmars-d-learn

On 9/13/20 2:35 PM, ag0aep6g wrote:

Easy peasy:

     import std.meta: Repeat;
     Repeat!(kvargs.length, const(char)*) zs;
     foreach (i, ref z; zs) z = toStringz(kvargs[i]);
     return sam_hdr_add_line(this.h, type.ptr, zs, null);


Great, thank you!

By the way, `kvargs` is not a dynamic array. Its length is not dynamic, 
and it's not an array.


I was incorrectly recalling the error message compiler emitted when 
using the typesafe variadic FUNCTION (your method 1, below)


Also, you don't just want to pass the parameters forward. That would be 
trivial: `sam_hdr_add_line(this.h, type.ptr, kvargs, null)`. You want to 
run them through another function first. That's where the difficulty 
comes from.


Right, I indeed left that out of the problem statement; the trivial 
variadic template params pass right on through which is awesome.


I don't see when it would matter how the function is called, but you can 
declare it in two different ways:


My assumption is that if called passing a [runtime] dynamic array, of 
course the parameter list cannot be known, but the (below) "Type 1 True 
typesafe variadic" can also be called with a fixed parameter list known 
at compile-time.



1) True typesafe variadic:

     auto addLine(RecordType type, string[] kvargs ...)

2) Template + typesafe variadic:

     auto addLine(size_t n)(RecordType type, string[n] kvargs ...)

In the first one, `kvargs.length` is a dynamic value. You can't use it 
to generate the arguments for a `sam_hdr_add_line` call.


My point of surprise was that -- depending on how invoked ( f(anArray) 
versus f(1,2,3) the compiler may know at compile-time the parameter 
list. But from a complexity standpoint it makes sense that it is 
nonetheless not possible to use.


In the second one, `kvargs.length` is a static value. So you can do the 
same things as in the `T...` template. And just like the `T...` 
template, it will generate a new function for every distinct 
`kvargs.length`.


Great, I never thought of parameterizing as a static array. This looks 
the best IMO.


Re: Call C variadic function from D variadic function

2020-09-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/13/20 2:35 PM, Paul Backus wrote:

On Sunday, 13 September 2020 at 17:23:42 UTC, Steven Schveighoffer wrote:

On 9/13/20 12:55 PM, James Blachly wrote:


```
 /// Add a single line to an existing header
 auto addLine(T...)(RecordType type, T kvargs)
 if(kvargs.length > 0 && isSomeString!(T[0]))
 {
 static assert (kvargs.length %2 == 0);   // K-V pairs => 
even number of variadic args


 string varargMagic(size_t len)
 {
 string args = "sam_hdr_add_line(this.h, type.ptr, ";
 for(int i=0; iInterestingly, compilation fails if the mixin consists only of the 
comma-separated parameters ("Comma expression" [1])



Question:
If a variadic template, despite presenting to the user a "dynamic 
array", MUST know its parameter list at compile-time, is there a way 
(other than with mixins as shown) to pass this parameter list to 
extern(C) linkage function with variadic parameters?


Was just talking about this exact problem with Adam Ruppe. 
Unfortunately, because the parameters are an expression tuple, and not 
a compile-time tuple, you can't use stuff like staticMap.


You actually can, if you define the right kind of helper function:

     /// Add a single line to an existing header
     auto addLine(T...)(RecordType type, T kvargs)
     if(kvargs.length > 0 && isSomeString!(T[0]))
     {
     static assert (kvargs.length %2 == 0);   // K-V pairs => even 
number of variadic args

     immtuable(char)* argToStringz(alias arg)()
     {
     return toStringz(arg);
     }

     return sam_hdr_add_line(this.h, this.ptr, 
staticMap!(argToStringz, kvargs), null);

     }

The clever trick here is that, because of optional parentheses [1], 
`argToStringz!(kvargs[i])` can be interpreted either as the name of a 
function or a function call, depending on the context it appears in.


That's cool. And horrific at the same time :) I mean the templates that 
you have to instantiate for this...


I would prefer the mixin solution, even though it's uglier. I think 
something that abstracts that out would be a nice thing to have for 
std.meta.


-Steve


Re: Red-Black Gauss-seidel with mir

2020-09-13 Thread 9il via Digitalmars-d-learn

On Sunday, 13 September 2020 at 14:48:30 UTC, Christoph wrote:

Hi all,

I am trying to implement a sweep method for a 2D Red-black 
Gauss-Seidel Solver with the help of mir and its slices.

The fastest Version I discovered so far looks like this:
```
void sweep(T, size_t Dim : 2, Color color)(in Slice!(T*, 2) F, 
Slice!(T*, 2) U, T h2)

{
const auto m = F.shape[0];
const auto n = F.shape[1];
auto UF = U.field;
auto FF = F.field;

[...]


Hi Christoph,

More details are required. What compiler and command line has 
been used?

The full source of the benchmark would be helpful.

Kind regards,
Ilya


Re: how to do this meta-programming? print the address of random element's address of a variable length of arrays?

2020-09-13 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 13 September 2020 at 18:24:01 UTC, mw wrote:
But, I'd reflect on my experience so far on compile-time 
meta-programming in D as a novice user, the big problems are:


-- in D, there are too many choices, with no clear guideline 
which one is *THE* one to use for a particular purpose: 
language or library mechanisms? mixin? template? AliasSeq / 
aliasSeqOf? Tuple? (non-)?-eponymous version of ...?; and even 
for a particular option, e.g. Tuple!(int, "MA_optInTimePeriod", 
TA_MAType, "opInMAType"),  there are choices to use either 
token (int) or string ("MA_optInTimePeriod"). And user does not 
have a strong guide on which choice is *THE* way to proceed. 
Each mechanism seems to have / fit a particular purpose, but 
when you start to use it, you'll probably find there are new 
problems come-in later, and you want to revisit the choice you 
made earlier on.


By contrast, in C: there is only *ONE* mechanism, i.e. macro, 
that's it.


I think the biggest issue here is that, like you said, it's hard 
to find good resources for learning how to use D's various 
reflection and code-generation facilities. In the community 
Discord, we've tried to collect some links in the #resources 
channel, which you might find helpful:


- Philippe Sigaud's "D Template Tutorial"
  http://dpldocs.info/experimental-docs/std.typecons.Tuple.html

- Bradley Chatha's "Intro to D metaprogramming"
  https://bradley.chatha.dev/Blog

- Vladimir Panteleev's "Functional Image Processing in D"
  
https://blog.thecybershadow.net/2014/03/21/functional-image-processing-in-d/


Ideally, we'd have some official, easy-to-find place where 
tutorials like this could be collected (maybe on the Wiki?), but 
so far no one's taken the initiative to set that up. One of the 
downsides of having a volunteer community, I suppose.


-- in D, there is no easy way to convert between token <==> 
string. Given a token, does token.stringof always work to paste 
with other strings to generate a new token? and given a string, 
does mixin!"string" always work to be a valid token?


There's no 100% reliable way to round-trip a token to a string 
and back again, because the same token can have a different 
meaning depending on what scope it's used in. Adam Ruppe goes 
over some alternatives to string mixins you can use to avoid this 
pitfall in one of his "Tips of the Week":


http://www.arsdnet.net/this-week-in-d/2016-feb-21.html

-- in D, there is no easy way to see directly the generated 
source code by the compiler at compile-time, which makes the 
debug difficult during development.


By contrast, in C: one can easily see the result via: cpp -P 
foo.h > foo.c


I agree that this is an issue. There are a couple compiler flags 
that can help (-mixin=filename, -vcg-ast), but mostly you're 
stuck with printf-style debugging via `pragma(msg)`.


Re: Call C variadic function from D variadic function

2020-09-13 Thread mw via Digitalmars-d-learn
Just a observation, from the questions & answers in this thread 
and mine[1]: I think meta-programming in D is somehow like C++, 
it starts becoming a baroque language. The language is complex 
enough that there may be ways to get things done, but it's just 
quite difficult for ordinary users to find *THE* way.



[1] 
https://forum.dlang.org/thread/ujcbioaghvofwowih...@forum.dlang.org


Get enum value name as string at compile time?

2020-09-13 Thread Steven Schveighoffer via Digitalmars-d-learn

Consider the enum:

enum Foo { a, b }

Foo.a.stringof => "a"
enum x = Foo.a;
x.stringof => "cast(Foo)0"

Is there another way I can take an enum value that's known at compile 
time (but not the actual identifier), and get the name of it? I know I 
can use a switch, or to!string. But I was hoping this was easy for the 
compiler to figure out some way without involving CTFE.


-Steve