Re: Doubt about type Inference on templates

2023-11-23 Thread Antonio via Digitalmars-d-learn

On Wednesday, 22 November 2023 at 19:37:58 UTC, Paul Backus wrote:

This is a bug/limitation in the compiler. I couldn't find an 
existing report on issues.dlang.org, so I've reported it myself 
as [issue 24255][1].


Wow: It is a very concise bug example.

I tested with ```ldc``` ant it fails too.



For now, I think the best way to work around it is to specify 
the type in the lambda, as in `(int i) => i%2 == 0`.


agreed



The reason you see `void` is that when the compiler cannot 
figure out the type of a function literal, it treats it as a 
template function:


```d
static assert(__traits(isTemplate, i => i % 2 == 0));
```

And for silly historical reasons, when the compiler tries to 
determine the type of a template, it returns `void` instead of 
giving an error:


```d
template example() {}
static assert(is(typeof(example) == void)); // what??
```


Thanks Paul!!!





Re: Doubt about type Inference on templates

2023-11-22 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 22 November 2023 at 17:53:15 UTC, Antonio wrote:
Basically, it doesn't know witch version of ```filter``` to 
use, because it is inferring `i=>i%2==0` is `void` ?!?!?!


```
!()(IIterable!int, void)
```

If I explicitly write `(int i)=>i%2==0`, it compiles correctly 
again.


**Is it mandatory to explicitly tell that `S` is `int` when 
```IIterable!S source``` is  `IIterable!int` alredy?**


This is a bug/limitation in the compiler. I couldn't find an 
existing report on issues.dlang.org, so I've reported it myself 
as [issue 24255][1].


For now, I think the best way to work around it is to specify the 
type in the lambda, as in `(int i) => i%2 == 0`.


The reason you see `void` is that when the compiler cannot figure 
out the type of a function literal, it treats it as a template 
function:


```d
static assert(__traits(isTemplate, i => i % 2 == 0));
```

And for silly historical reasons, when the compiler tries to 
determine the type of a template, it returns `void` instead of 
giving an error:


```d
template example() {}
static assert(is(typeof(example) == void)); // what??
```

[1]: https://issues.dlang.org/show_bug.cgi?id=24255


Doubt about type Inference on templates

2023-11-22 Thread Antonio via Digitalmars-d-learn
Just for fun, I'm trying to implement an alternative base library 
to avoid template/mixin/static/traits code with only one 
objective:  make "intelliSense" code analyzers tasks easier.


I need "Generics"... but D has not generics:  I use templates in 
the "simplest" possible way


I.E.:
```d
interface IIterable(T)
{
  bool empty();
  void popFront();
  T front();
}

IIterable!S toIterable(S)(S[] source)
  => new ArrayIterable!S(source);
IIterable!S filter(S)(IIterable!S source, bool delegate(S item) 
predicate)

  => new Filter!S(source, predicate);
IIterable!S filter(S)(S[] source, bool delegate(S item) predicate)
  => toIterable(source).filter(predicate);
// ...

```

Then, in main.d I do
```d
import std.stdio;
void main(){
  
[1,2,3,4,5,6].toIterable!int.filter!int(i=>i%2==0).map!int(i=>i*2).toArray.writeln();

}

```

It works properly... until I remove the ```!int``` from the 
```filter``` method.


```
main.d(3,38): Error: none of the overloads of template `filter` 
are callable using argument types `!()(IIterable!int, void)`
iterable.d(21,13):Candidates are: `filter(S)(IIterable!S 
source, bool delegate(S item) predicate)`
iterable.d(23,13):`filter(S)(S[] source, 
bool delegate(S item) predicate)`

```

Basically, it doesn't know witch version of ```filter``` to use, 
because it is inferring `i=>i%2==0` is `void` ?!?!?!


```
!()(IIterable!int, void)
```

If I explicitly write `(int i)=>i%2==0`, it compiles correctly 
again.


**Is it mandatory to explicitly tell that `S` is `int` when 
```IIterable!S source``` is  `IIterable!int` alredy?**












Re: templates and traits

2023-03-18 Thread Chris Katko via Digitalmars-d-learn

On Saturday, 18 March 2023 at 20:42:50 UTC, Nick Treleaven wrote:

On Saturday, 18 March 2023 at 19:22:07 UTC, Chris Katko wrote:
...


So there's multiple sub-problems to solve. I asked this years 
ago, and got 90% of the way done and then lost the code and 
cannot find the original forum post.


Maybe it was this?:
https://forum.dlang.org/post/dqzxnctucwvyhstfz...@forum.dlang.org


YES! I tried google search, forum search, even going through all 
my accounts posts, even my e-mail.


I think I accidentally made that post without logging in so it's 
not attached to my account posts.


Re: templates and traits

2023-03-18 Thread Nick Treleaven via Digitalmars-d-learn

On Saturday, 18 March 2023 at 19:22:07 UTC, Chris Katko wrote:
...


So there's multiple sub-problems to solve. I asked this years 
ago, and got 90% of the way done and then lost the code and 
cannot find the original forum post.


Maybe it was this?:
https://forum.dlang.org/post/dqzxnctucwvyhstfz...@forum.dlang.org



templates and traits

2023-03-18 Thread Chris Katko via Digitalmars-d-learn

Given:
```D
struct pos {float x, y;}

draw(myBitmap, pos(320, 240), centered);
draw(pos(320, 240), myBitmap);
draw("text", myFont, pos(320, 240));
```

I'm writing a general "draw" template function that through 
compile-time, calls an associated DAllegro/Allegro 5 function:


```
draw(myBitmap, pos(320, 240), centered);   // 
al_draw_bitmap(myBitmap, pos.x - myBitmap.w/2, pos.y - 
myBitmap.h, 0);

draw(pos(320, 240), myBitmap); // order doesn't matter
draw("text", myFont, pos(320, 240)); // different function 
al_draw_text(...)

```

So there's multiple sub-problems to solve. I asked this years 
ago, and got 90% of the way done and then lost the code and 
cannot find the original forum post.


The pos(320,240) part works fine already. I need:

 - At compile-time, for a variadic template that can take any 
number of arguments, if specific arguments are available, I 
branch and use them to call a specific applicable C function.


I remember I need to write some sort of enum function that checks 
"IsAny" if an argument is passed at all, as well as one to find 
where that argument is. Passing duplicates probably don't matter 
(at least not right now), first valid argument is fine. I can't 
seem to write code (or find example code online) that does this.


But it's something like

```D
enum isAny() = ...;

void draw(T...)(T)
{
if(isAny(bitmap))
  {
  // it's a sprite, now find out if we need it rotated, 
stretched, etc.

  }
is(isAny(string))
  {
  // its text [...]
  }
}
```

A separate problem I've run into is, the 'centered' construct. If 
I have rotate(25) (rotate 25 degrees), that works. But I cannot 
just pass a type named "centered" with no variable attached to 
it, nor can I--I think--pass an enum.  I could do centered(false) 
or centered(0), but that's clunkier than just saying "if 
'centered' is an argument, we center it. If not, we don't." I 
could have a variable named centered, I guess. or an enum with 
{isCentered=1, notCentered=0} and detect if the enum is passed. 
Lot's of ways to skin this cat.


The idea here, is I've got a lot of optional arguments (centered, 
tinted, rotated, scaled, sheared, etc) that I can pick from and I 
don't want to have to sort through a list of 80 different 
permutations of function signatures, or, one gigantic 
megafunction with a ton of zeros/nulls for all the unused 
arguments.


This is a bit of a confusing problem to explain, so I've probably 
left something necessary out.





Combining Templates While Minimizing Bloat

2023-02-14 Thread jmh530 via Digitalmars-d-learn
The code below has two `foo` functions that take slices, one 
accepts a const(T)* iterator and one accepts a generic Iterator 
with the property that the slice isn't convertible to the first 
one. The nice thing about this is that if you pass it with a 
double* or const(double)*, then it doesn't increase template 
bloat. The problem, however, is that I have to either have two 
implementations or a separate `fooImpl` function to implement the 
desired functionality. Is there any way to combine together the 
`foo` functions in a way that maintains the template bloat 
reducing behavior of the first function?


The example below uses mir, but it just as easily could be 
adapted to other types.


```d
/+dub.sdl:
dependency "mir-algorithm" version="*"
+/
import std.stdio: writeln;
import mir.ndslice.slice;

void foo(T)(Slice!(const(T)*, 1) x)
{
writeln("here");
writeln("Iterator = ", typeid(IteratorOf!(typeof(x;
}

void foo(Iterator)(Slice!(Iterator, 1) x)
if (!is(Iterator : const(U)*, U))
{
writeln("there");
writeln("Iterator = ", typeid(IteratorOf!(typeof(x;
}

void main()
{
double[] x = [1.0, 2, 3];
auto y = x.sliced;
auto z = y.toConst;
foo(y); //prints "here" and "Iterator=const(double)*"
foo(z); //prints "here" and "Iterator=const(double)*"
auto a = y / 6;
foo(a); //prints "there" and "Iterator=(some long template 
text)"

}
```

I tried something like
```d
void foo(Iterator)(Slice!(const Iterator, 1) x) {}
```
but this isn't a valid mir iterator since it becomes 
const(double*) (a const pointer to a const double). What I need 
is const(double)* (a mutable pointer to a const double).


Re: How to Add CSS and JS to vibe.d templates

2023-01-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/19/23 11:44 PM, seany wrote:

Hi

Howcan one add CSS and JS to vibe.d templates? Here is my setup (vibe.d 
project initiated with dub using dub init myproject vibe.d):


./public:
main.css  main.js

./source:
app.d

./views:
auth2fa.dt  fail.dt  login.dt  pair.dt  passfail.dt  userfail.dt


I am trying to add a css file using `link(rel="stylesheet", 
type="text/css", href="main.css")` in the diet templates, but it has no 
effect. I took the files from here: 
https://codepen.io/ricardoolivaalonso/pen/YzyaRPN


Keep in mind, this literally translates to a `link` tag in the HTML. So 
here is what happens:


1. your vibe project is running, and passes out the compiled template to 
the browser.
2. The browser sees the link tag, and attempts to ask the server for the 
file "main.css"
3. The vibe project tries to match that to its routes, and cannot find 
it, and so returns an error.


So this takes 2 steps to remedy:

1. Register a `serveStaticFiles` route with the glob `public/*`. See the 
docs here: https://vibed.org/api/vibe.http.fileserver/serveStaticFiles
2. Change your link to refer to `public/main.css`, instead of just 
`main.css`.


This is how it looks in my code:

```d
 router.get("/public/*", serveStaticFiles(""));
```

And the links look like:

```pug
link(rel="stylesheet",href="/public/css/flatpickr.min.css")
```

as an example. Note that I put my css files into a css subdirectory 
under public, and my javascript files under a js subdirectory. It all 
depends on how you want to set it up.


-Steve


How to Add CSS and JS to vibe.d templates

2023-01-19 Thread seany via Digitalmars-d-learn

Hi

Howcan one add CSS and JS to vibe.d templates? Here is my setup 
(vibe.d project initiated with dub using dub init myproject 
vibe.d):


./public:
main.css  main.js

./source:
app.d

./views:
auth2fa.dt  fail.dt  login.dt  pair.dt  passfail.dt  userfail.dt


I am trying to add a css file using `link(rel="stylesheet", 
type="text/css", href="main.css")` in the diet templates, but it 
has no effect. I took the files from here: 
https://codepen.io/ricardoolivaalonso/pen/YzyaRPN


Note that (as discussed in my previous post by Steven 
Schveighoffer) , there are some errors in the jade/pug template 
file. But even if we correct them, and then I try to use the 
setup, I do not get the styles. (Of course, i can't point my 
browser to www.my.server/main.css or so, because those endpoints 
are not defined. However, as I understood, all non-defined 
endpoints should anyway be redirected to public)


Thank you.


Re: How to use templates in a separate library?

2022-06-24 Thread frame via Digitalmars-d-learn

On Thursday, 23 June 2022 at 23:50:42 UTC, monkyyy wrote:

On Thursday, 23 June 2022 at 08:12:32 UTC, CrazyMan wrote:

linking


make sure you use the -i flag when compiling


But note, that would be the opposite of using a library.


Re: How to use templates in a separate library?

2022-06-23 Thread monkyyy via Digitalmars-d-learn

On Thursday, 23 June 2022 at 08:12:32 UTC, CrazyMan wrote:

linking


make sure you use the -i flag when compiling




Re: How to use templates in a separate library?

2022-06-23 Thread frame via Digitalmars-d-learn

On Thursday, 23 June 2022 at 08:12:32 UTC, CrazyMan wrote:

I have a separate library and some template interface in it

```d
interface IFoo(T)
{
 void setValue(const(T) value);
}
```

But when using it in the main program, it throws a linking 
error. I found that you can make a sourceLibrary that copies 
the code instead of creating a binary. But with it, I also get 
a linking error, and at the same time it is no longer 
associated with my interface, but with a third-party dependency 
(bindbc.opengl)


What can I do to fix this?


This is insufficient information to help you.

- Separate library could mean multiple things: a compiler 
library, a static linked binary, a SO/DLL binary.


- What error is thrown?

- Are you using `extern` declarations?

For a successful build the linker needs to get all symbols from 
any referenced source. The template isn't an actual symbol, it's 
just a information for the compiler to generate one. It says 
nothing about the symbol will be really generated or not. Also 
the linker needs to know if a library has to be used.


How to use templates in a separate library?

2022-06-23 Thread CrazyMan via Digitalmars-d-learn

I have a separate library and some template interface in it

```d
interface IFoo(T)
{
 void setValue(const(T) value);
}
```

But when using it in the main program, it throws a linking error. 
I found that you can make a sourceLibrary that copies the code 
instead of creating a binary. But with it, I also get a linking 
error, and at the same time it is no longer associated with my 
interface, but with a third-party dependency (bindbc.opengl)


What can I do to fix this?


Re: Mixin Templates and Operators

2022-04-12 Thread francesco.andreetto via Digitalmars-d-learn

On Wednesday, 6 April 2022 at 17:59:12 UTC, Adam D Ruppe wrote:

ooh yeah there's multiple here so the names don't 
overload and one on the time itself would override the ones 
from mixin template.


You'd have to alias them together on the type.


Hello Adam D Ruppe,

I see what you mean,
thank you very much for your answers!

-FA



Re: Mixin Templates and Operators

2022-04-12 Thread francesco.andreetto via Digitalmars-d-learn
On Wednesday, 6 April 2022 at 17:33:28 UTC, Steven Schveighoffer 
wrote:


As I mentioned elsewhere, it does work. But the situation I 
think must be that it's only one mixin template. Probably also 
you can't have any overloads in the type itself.


Note that I also think string mixins would work perfectly fine. 
And UFCS will never work for operator overloads, but that is by 
design.


-Steve


Hello Steve,

Thank you very much for your answers, you have been very clear 
and helpful!


-FA




Re: Mixin Templates and Operators

2022-04-12 Thread francesco.andreetto via Digitalmars-d-learn

On Wednesday, 6 April 2022 at 16:36:51 UTC, Tejas wrote:

Looks like a compiler bug, since substituting the real methods 
makes the `mixin template` code compile fine


Hi Tejas,
Thank you very much for your answer!

Also, remove the `const`, otherwise the method will word only 
on `const` instances even if the bug gets fixed


And thank you for this advice: I'll definitely remove the `const`!

FA


Re: Mixin Templates and Operators

2022-04-06 Thread Adam D Ruppe via Digitalmars-d-learn
On Wednesday, 6 April 2022 at 17:33:28 UTC, Steven Schveighoffer 
wrote:
As I mentioned elsewhere, it does work. But the situation I 
think must be that it's only one mixin template. Probably also 
you can't have any overloads in the type itself.


ooh yeah there's multiple here so the names don't 
overload and one on the time itself would override the ones from 
mixin template.


You'd have to alias them together on the type.


Re: Mixin Templates and Operators

2022-04-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/6/22 12:52 PM, Adam D Ruppe wrote:

On Wednesday, 6 April 2022 at 10:36:04 UTC, francesco.andreetto wrote:
Am I doing something wrong or it is impossible to use mixin templates 
like that?


mixin templates can't bring in operator overloads. The spec doesn't 
really say this I think, but that's the way it has been for a long time.


It only checks for operator overloads on the direct thing itself, no 
UFCS, no mixin template.


As I mentioned elsewhere, it does work. But the situation I think must 
be that it's only one mixin template. Probably also you can't have any 
overloads in the type itself.


Note that I also think string mixins would work perfectly fine. And UFCS 
will never work for operator overloads, but that is by design.


-Steve


Re: Mixin Templates and Operators

2022-04-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/6/22 6:36 AM, francesco.andreetto wrote:
I have two structs, point and vec, in which I want to implement some 
arithmetic operations.

The operations are:

```
point - point = vec
point + vec = point
```

Using mixin templates the code compiles but calling the operations in 
the main causes an "incompatible type" Error:


This seems like a bug in the compiler. You can mixin operator overloads 
using one mixin template, but not multiple.


e.g. raylib-d uses this:

https://github.com/schveiguy/raylib-d/blob/89733bab9fd1d3588c14f4aa54b62ad45022a105/source/raymathext.d#L75



I tried to implement a single template:

```d
mixin template sumDiff(T, R){
    R opBinary(string op)(T rhs) const
    if (op == "+" || op == "-"){
   return mixin("R(x " ~ op ~ " rhs.x, y " ~ op ~ "rhs.y, z " ~ op ~ 
" rhs.z)");

    }
}
```

but the same error occurs.


This is different from your original. If I do this, it works:

```d
mixin template both(T, R) {
   R opBinary(string op : "+")(T rhs) const
   {
  return R(x + rhs.x, y + rhs.y, z + rhs.z);
   }

   T opBinary(string op : "-")(R rhs) const
   {
  return T(x - rhs.x, y - rhs.y, z - rhs.z);
   }
}

struct point{
   float x, y, z;
   mixin both!(vec, point);
}
```


If I don't use the mixin templates and, instead, I overload the 
operations into the structures everything works.


It also works to call `opBinary` directly:

```d
vec v1 = p1.opBinary!"-"(p2);
```

Which leads me to believe it's not an ambiguity error, but rather just a 
straight omission on how the operator overloading works.


I think you should file a bug.

-Steve


Re: Mixin Templates and Operators

2022-04-06 Thread Adam D Ruppe via Digitalmars-d-learn
On Wednesday, 6 April 2022 at 10:36:04 UTC, francesco.andreetto 
wrote:
Am I doing something wrong or it is impossible to use mixin 
templates like that?


mixin templates can't bring in operator overloads. The spec 
doesn't really say this I think, but that's the way it has been 
for a long time.


It only checks for operator overloads on the direct thing itself, 
no UFCS, no mixin template.


Re: Mixin Templates and Operators

2022-04-06 Thread Tejas via Digitalmars-d-learn
On Wednesday, 6 April 2022 at 10:36:04 UTC, francesco.andreetto 
wrote:
I have two structs, point and vec, in which I want to implement 
some arithmetic operations.

The operations are:

```
point - point = vec
point + vec = point
```

Using mixin templates the code compiles but calling the 
operations in the main causes an "incompatible type" Error:


```d
mixin template sum(T, R) {
   R opBinary(string op)(T rhs) const
   if (op == "+"){
  return R(x + rhs.x, y + rhs.y, z + rhs.z);
   }
}

mixin template diff(T, R) {
   R opBinary(string op)(T rhs) const
   if (op == "-") {
  return R(x - rhs.x, y - rhs.y, z - rhs.z);
   }
}

struct point{
   float x, y, z;
   mixin diff!(point, vec);
   mixin sum!(vec, point);
}

struct vec{
   float x, y, z;
}

void main(){
   point p1 = {1,2,3}, p2 = {5,6,7};
   vec v1 = p1-p2;

   vec v2 = {2,-1,0};
   point p3 = p1+v2;
}
```
The output of `dub run` is

```
Performing "debug" build using /usr/bin/dmd for x86_64.
query ~master: building configuration "application"...
source/app.d(27,13): Error: incompatible types for `(p1) - 
(p2)`: both operands are of type `point`
source/app.d(30,15): Error: incompatible types for `(p1) + 
(v2)`: `point` and `vec`

/usr/bin/dmd failed with exit code 1.
```

I tried to implement a single template:

```d
mixin template sumDiff(T, R){
   R opBinary(string op)(T rhs) const
   if (op == "+" || op == "-"){
  return mixin("R(x " ~ op ~ " rhs.x, y " ~ op ~ "rhs.y, z 
" ~ op ~ " rhs.z)");

   }
}
```

but the same error occurs.

If I don't use the mixin templates and, instead, I overload the 
operations into the structures everything works.


```d
struct point{
   float x, y, z;

   vec opBinary(string op)(point rhs) const
   if (op == "-") {
  return vec(x - rhs.x, y - rhs.y, z - rhs.z);
   }

   point opBinary(string op)(vec rhs) const
   if (op == "+") {
  return point(x + rhs.x, y + rhs.y, z + rhs.z);
   }
}

struct vec{
   float x, y, z;
}

void main(){
   point p1 = {1,2,3}, p2 = {5,6,7};
   vec v1 = p1-p2;

   vec v2 = {2,-1,0};
   point p3 = p1+v2;
}
```

Am I doing something wrong or it is impossible to use mixin 
templates like that?


Looks like a compiler bug, since substituting the real methods 
makes the `mixin template` code compile fine


Also, remove the `const`, otherwise the method will word only on 
`const` instances even if the bug gets fixed


```d
mixin template sum(T, R) {
   R opBinary(string op)(T rhs) const
   if (op == "+"){
  return R(x + rhs.x, y + rhs.y, z + rhs.z);
   }
}

mixin template diff(T, R) {
   R opBinary(string op)(T rhs) const
   if (op == "-") {
  return R(x - rhs.x, y - rhs.y, z - rhs.z);
   }
}

struct point{
   float x, y, z;
   mixin diff!(point, vec);
   mixin sum!(vec, point);
}

struct vec{
   float x, y, z;
}

void main(){
   point p1 = {1,2,3}, p2 = {5,6,7};
   vec v1 = p1.opBinary!"-"(p2);   // made - explicit

   vec v2 = {2,-1,0};
   point p3 = p1.opBinary!"+"(v2);  // made + explicit
}


Mixin Templates and Operators

2022-04-06 Thread francesco.andreetto via Digitalmars-d-learn
I have two structs, point and vec, in which I want to implement 
some arithmetic operations.

The operations are:

```
point - point = vec
point + vec = point
```

Using mixin templates the code compiles but calling the 
operations in the main causes an "incompatible type" Error:


```d
mixin template sum(T, R) {
   R opBinary(string op)(T rhs) const
   if (op == "+"){
  return R(x + rhs.x, y + rhs.y, z + rhs.z);
   }
}

mixin template diff(T, R) {
   R opBinary(string op)(T rhs) const
   if (op == "-") {
  return R(x - rhs.x, y - rhs.y, z - rhs.z);
   }
}

struct point{
   float x, y, z;
   mixin diff!(point, vec);
   mixin sum!(vec, point);
}

struct vec{
   float x, y, z;
}

void main(){
   point p1 = {1,2,3}, p2 = {5,6,7};
   vec v1 = p1-p2;

   vec v2 = {2,-1,0};
   point p3 = p1+v2;
}
```
The output of `dub run` is

```
Performing "debug" build using /usr/bin/dmd for x86_64.
query ~master: building configuration "application"...
source/app.d(27,13): Error: incompatible types for `(p1) - (p2)`: 
both operands are of type `point`
source/app.d(30,15): Error: incompatible types for `(p1) + (v2)`: 
`point` and `vec`

/usr/bin/dmd failed with exit code 1.
```

I tried to implement a single template:

```d
mixin template sumDiff(T, R){
   R opBinary(string op)(T rhs) const
   if (op == "+" || op == "-"){
  return mixin("R(x " ~ op ~ " rhs.x, y " ~ op ~ "rhs.y, z " 
~ op ~ " rhs.z)");

   }
}
```

but the same error occurs.

If I don't use the mixin templates and, instead, I overload the 
operations into the structures everything works.


```d
struct point{
   float x, y, z;

   vec opBinary(string op)(point rhs) const
   if (op == "-") {
  return vec(x - rhs.x, y - rhs.y, z - rhs.z);
   }

   point opBinary(string op)(vec rhs) const
   if (op == "+") {
  return point(x + rhs.x, y + rhs.y, z + rhs.z);
   }
}

struct vec{
   float x, y, z;
}

void main(){
   point p1 = {1,2,3}, p2 = {5,6,7};
   vec v1 = p1-p2;

   vec v2 = {2,-1,0};
   point p3 = p1+v2;
}
```

Am I doing something wrong or it is impossible to use mixin 
templates like that?


Variadic templates with default parameters.

2022-04-02 Thread JG via Digitalmars-d-learn

Consider the following code:
```d
import std;

auto logVariadic(T...)(T x,int line=__LINE__,string 
file=__FILE__) {

writeln(file,":",line," ",x);
}

int variadicCnt;
auto logVariadicWrapper(T...)(T x, int line=__LINE__, string 
file=__FILE__) {

 variadicCnt++;
 logVariadic(x,line,file);
}

auto args(T...)(T x) {
static struct Args(T...) {
static foreach(i, t; T) {
mixin(t, " v",i,";");
}
}
return Args!T(x);
}
auto log(Args)(Args args, int line=__LINE__, string 
file=__FILE__) {

writeln(file,":",line," ",args.tupleof);
}
int cnt;
auto logWrapper(Args)(Args args, int line=__LINE__, string 
file=__FILE__) {

 cnt++;
 log(args,line,file);
}

void main()
{
logVariadic("Hello ",1234);
logVariadicWrapper(1234, " is a number."); //produces wrong 
line number and adds line number and file name at the end

writeln(variadicCnt);
log(args("Hello ",1234));
logWrapper(args(1234, " is a number."));
writeln(cnt);
}
```
Produces output:
onlineapp.d:32 Hello 1234
onlineapp.d:10 1234 is a number.33onlineapp.d
1
onlineapp.d:35 Hello 1234
onlineapp.d:36 1234 is a number.
1

Any other ways to be able to achieve the same without double 
wrapping arguments like above? I guess the above is okay but I 
thought I would see other options.
(I know that one can pass line and file as template arguments, 
but that produces a new instance of log or logWrapper per use).


Re: Help needed to learn templates

2022-03-20 Thread Vinod K Chandran via Digitalmars-d-learn
On Saturday, 19 March 2022 at 22:31:19 UTC, Stanislav Blinov 
wrote:


It is appearing not in the `static if`, but in the `is` 
expression, which I described further in the rest of my first 
reply. Sorry if that wasn't clear.



No, it was my mistake, I missed it.

The other template syntax - `template foo(alias T)` can take as 
`T` any symbol, not just a type.



I understand this.

It comes from you, the programmer. Like I said before, `is(T == 
U[], U)` means "is T an array of some type, the type which I 
(the programmer) would like to refer to as U?". That's all 
there is to it (well, not quite, but it should suffice for 
starters). You're simply introducing an identifier. So, when 
`T` is an `int[][][]`, naturally, `U` becomes an alias to 
`int[][]` (look at the converse - when `U` is `int[][]`, `U[]` 
is naturally an `int[][][]`).



Okay, got it.


You can think of that test as this:

```d
import std.traits : isDynamicArray;

// ...

static if (isDynamicArray!T)
{
alias U = typeof(T.init[0]);
// ...
}
```


Yes, in this case everything is simple and clear.

...which would roughly be the same thing - you test if `T` is a 
dynamic array of some type, and then make an alias for that 
array's element type. It's just that the `is` expression allows 
you to create such alias in situ.


Okay. Got the point. Thanks. Now, I understand that why Ali 
suggest me to learn **`is()`** expression.





Re: Help needed to learn templates

2022-03-19 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 19 March 2022 at 13:38:42 UTC, Vinod K Chandran 
wrote:
On Saturday, 19 March 2022 at 11:47:53 UTC, Stanislav Blinov 
wrote:


No.

First of all Thanks for the reply. The answer "No" is a wonder 
to me. Because, from my point of view, `U` is coming from 
nowhere. My understanding is, we can use any parameter of a 
template inside the template. So in this case `U` is not in the 
parameter list. It is suddenly appearing in that `static if`.


It is appearing not in the `static if`, but in the `is` 
expression, which I described further in the rest of my first 
reply. Sorry if that wasn't clear.





The test is not `T t == U[]`. It is `is(T t == U[], U)`.


Okay, I understand.

Actually, the lower case `t` is not needed there, you can 
simply write `is(T == U[], U)`.


So the `T` is not the type. It's the parameter. Right ? So a 
template doesn't need a type. Only the parameter, right ? (I 
think I am too dumb to ask this. Please forgive me.)


Oh don't worry, this topic is not at all obvious with the `is` 
expression having its own syntax and semantics. `T` is a type, a 
type you instantiate `rank` with. `template rank(T)` *does* 
expect a type as a parameter. The other template syntax - 
`template foo(alias T)` can take as `T` any symbol, not just a 
type.


Yes, and `U` then becomes `int[][]`. Which is why the template 
recurses down and instantiates itself with `U`, until `T` 
fails the test.


In order to understand this, I need to understand from where 
the `U` comes.


It comes from you, the programmer. Like I said before, `is(T == 
U[], U)` means "is T an array of some type, the type which I (the 
programmer) would like to refer to as U?". That's all there is to 
it (well, not quite, but it should suffice for starters). You're 
simply introducing an identifier. So, when `T` is an `int[][][]`, 
naturally, `U` becomes an alias to `int[][]` (look at the 
converse - when `U` is `int[][]`, `U[]` is naturally an 
`int[][][]`).


You can think of that test as this:

```d
import std.traits : isDynamicArray;

// ...

static if (isDynamicArray!T)
{
alias U = typeof(T.init[0]);
// ...
}
```

...which would roughly be the same thing - you test if `T` is a 
dynamic array of some type, and then make an alias for that 
array's element type. It's just that the `is` expression allows 
you to create such alias in situ.


Re: Help needed to learn templates

2022-03-19 Thread Vinod K Chandran via Digitalmars-d-learn

On Saturday, 19 March 2022 at 16:08:33 UTC, Ali Çehreli wrote:


Here is the clickable url:

  http://ddili.org/ders/d.en/is_expr.html

I just read it again and I still like what I wrote there. :) 
(Usually it is the other way around.)


Ali


Thanks. Let me read that chapter.




Re: Help needed to learn templates

2022-03-19 Thread Vinod K Chandran via Digitalmars-d-learn

On Saturday, 19 March 2022 at 15:58:25 UTC, Ali Çehreli wrote:


I wrote a chapter about the is expression but it's still 
mysterious to me. :)


  ddili.org/ders/d.en/is_expr.html



Thanks for the reply. I think I choose the wrong book. I knew 
about your book but I thought this one is specially written for 
templates. I will read the template chapters in **`Programming in 
D`**.


It means "if T matches U[] and U is a type". "a type" because 
it is just U in the is expression list.


So as per the eponymous trick, **`enum size_t rank`** will be 
executed directly. Right ? But in that case, **`rank`** template 
doesn't take a parameter. There is only the type parameter which 
is **`T`**. So I am still in confusion about **`U`**.


I believe at least some of the traits have been added since 
that doc document was written. I would write it in a much 
simpler way using template constraints today:


```d
template rank(T) {
  import std.traits : isArray;
  import std.range : ElementType;

  static if (isArray!T) {
enum size_t rank = 1 + rank!(ElementType!T);

  } else {
enum size_t rank = 0;
  }
}
```

This template is very easy to understand and I have no confusions 
about it. Because, it only takes **`T`** as type parameter and 
there is no magical **`U`**.


However, note how the template constraints had to be repeated 
as isArray!T and !isArray!T in that case.



Yeah, I noted.


Not at all! The is expression is the weirdest part of D.


Oh I see.




Re: Help needed to learn templates

2022-03-19 Thread Ali Çehreli via Digitalmars-d-learn

On 3/19/22 08:58, Ali Çehreli wrote:

> I wrote a chapter about the is expression but it's still mysterious to
> me. :)
>
>ddili.org/ders/d.en/is_expr.html

Here is the clickable url:

  http://ddili.org/ders/d.en/is_expr.html

I just read it again and I still like what I wrote there. :) (Usually it 
is the other way around.)


Ali



Re: Help needed to learn templates

2022-03-19 Thread Ali Çehreli via Digitalmars-d-learn

On 3/19/22 06:38, Vinod K Chandran wrote:
> On Saturday, 19 March 2022 at 11:47:53 UTC, Stanislav Blinov wrote:
>>
>> No.
>>
> First of all Thanks for the reply. The answer "No" is a wonder to me.

I wrote a chapter about the is expression but it's still mysterious to 
me. :)


  ddili.org/ders/d.en/is_expr.html

I may be saying some things wrong there but that's my mental model.

> Because, from my point of view, `U` is coming from nowhere.

Agreed. It is similar to U's coming from nowhere below:

void foo(U)(U[] array) {
}

So, in my mental model, that use of the is expression is the same but 
written in the reverse order from foo above:


static if (is(T t == U[], U))

It means "if T matches U[] and U is a type". "a type" because it is just 
U in the is expression list.


I believe at least some of the traits have been added since that doc 
document was written. I would write it in a much simpler way using 
template constraints today:


template rank(T) {
  import std.traits : isArray;
  import std.range : ElementType;

  static if (isArray!T) {
enum size_t rank = 1 + rank!(ElementType!T);

  } else {
enum size_t rank = 0;
  }
}

Or one can separate the logic in two template definitions:

import std.traits : isArray;

template rank(T)
if (isArray!T)
{
  import std.range : ElementType;
  enum size_t rank = 1 + rank!(ElementType!T);
}

template rank(T)
if (!isArray!T)
{
  enum size_t rank = 0;
}

However, note how the template constraints had to be repeated as 
isArray!T and !isArray!T in that case.


> My
> understanding is, we can use any parameter of a template inside the
> template. So in this case `U` is not in the parameter list. It is
> suddenly appearing in that `static if`.

In my mental model, the is expression uses at least a part of the 
template system.


>> you can simply write
>> `is(T == U[], U)`.
>>
> So the `T` is not the type.

T is the type because it is introduced as simply T in the parameter 
list. If it were 'int T', then it would be an int. So in that sense, it 
is a type-kind template parameter.


> It's the parameter. Right ? So a template
> doesn't need a type. Only the parameter, right ?

The way I read it is: "T is a type that matches U[] where U is a type as 
well."


> (I think I am too dumb
> to ask this. Please forgive me.)

Not at all! The is expression is the weirdest part of D.

Ali



Re: Help needed to learn templates

2022-03-19 Thread Vinod K Chandran via Digitalmars-d-learn

On Saturday, 19 March 2022 at 08:49:02 UTC, Salih Dincer wrote:




Thanks for the reply. You explained the idea very well and it's 
easy to understand for a novice.




Re: Help needed to learn templates

2022-03-19 Thread Vinod K Chandran via Digitalmars-d-learn
On Saturday, 19 March 2022 at 11:47:53 UTC, Stanislav Blinov 
wrote:


No.

First of all Thanks for the reply. The answer "No" is a wonder to 
me. Because, from my point of view, `U` is coming from nowhere. 
My understanding is, we can use any parameter of a template 
inside the template. So in this case `U` is not in the parameter 
list. It is suddenly appearing in that `static if`.




The test is not `T t == U[]`. It is `is(T t == U[], U)`.


Okay, I understand.

Actually, the lower case `t` is not needed there, you can 
simply write `is(T == U[], U)`.


So the `T` is not the type. It's the parameter. Right ? So a 
template doesn't need a type. Only the parameter, right ? (I 
think I am too dumb to ask this. Please forgive me.)


Yes, and `U` then becomes `int[][]`. Which is why the template 
recurses down and instantiates itself with `U`, until `T` fails 
the test.


In order to understand this, I need to understand from where the 
`U` comes.





Re: Help needed to learn templates

2022-03-19 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 19 March 2022 at 05:54:26 UTC, Vinod K Chandran 
wrote:


Question 1 - `U` is appearing in the first static if statement. 
But we had to write `U` on the template line, right? Like - 
`template rank(T, U)`


No.

Question 2 - The statif if test is - `T t == U[ ]` What does 
that mean ?


The test is not `T t == U[]`. It is `is(T t == U[], U)`.

https://dlang.org/spec/expression.html#is-identifier-equal

```
is ( Type Identifier == TypeSpecialization )

The condition is satisfied if Type is semantically correct and is 
the same as TypeSpecialization. The Identifier is declared to be 
either an alias of the TypeSpecialization or, if 
TypeSpecialization is dependent on Identifier, the deduced type.

```

You simply introduce new identifiers. Basically, the test means 
"is T an array of some type which I would like referred to as 
U?". Actually, the lower case `t` is not needed there, you can 
simply write `is(T == U[], U)`.


Question 3 - if `T t == U[ ]` is the test, then I think when we 
pass

```d
rank!(int[ ][ ][ ])
```
The test will be `int[ ][ ][ ] == U[ ]`, Right ?


Yes, and `U` then becomes `int[][]`. Which is why the template 
recurses down and instantiates itself with `U`, until `T` fails 
the test.


Re: Help needed to learn templates

2022-03-19 Thread Salih Dincer via Digitalmars-d-learn
On Saturday, 19 March 2022 at 05:54:26 UTC, Vinod K Chandran 
wrote:
Question 1 - `U` is appearing in the first static if statement. 
But we had to write `U` on the template line, right? Like - 
`template rank(T, U)`
Question 2 - The statif if test is - `T t == U[ ]` What does 
that mean ?
Question 3 - if `T t == U[ ]` is the test, then I think when we 
pass


You don't need anything extra while using it...

I think U is declare a range. Here is a recursive pattern. Just 
like the code I wrote below:


```d
import std.stdio;

alias outer O;

struct outer {
  int i;
  O * o;
}

int rank(T)(T* s) {
  int count = 1;

  if(s.o is null) return count;


  return count + rank(s.o);
}

void main() {
  auto test = O(1, new O(2, new O(3, new O)));

  rank(test.o).writeln;

  test.i.write(", ");
  test.o.i.write(", ");
  test.o.o.i.writeln;
} /* CONSOLEOUT:
3
1, 2, 3
*/
```
SDB@79


Help needed to learn templates

2022-03-18 Thread Vinod K Chandran via Digitalmars-d-learn

Hi all,
I am trying to learn D templates with Philippe Sigaud's "D 
Templates: A Tutorial". So far so good. I have completed first 19 
pages and in the 20th page, I found an obstacle. This is the code.

```d
module rank1;

template rank(T)
{
static if (is(T t == U[], U)) // is T an array of U, for some 
type U?
enum size_t rank = 1 + rank!(U); // then let’s recurse 
down.

else
enum size_t rank = 0; // Base case, ending the recursion.
}

module using_rank1;
import rank1;
static assert(rank!(int) == 0);
static assert(rank!(int[]) == 1);
static assert(rank!(int[][]) == 2);
static assert(rank!(int[][][]) == 3);
```
Question 1 - `U` is appearing in the first static if statement. 
But we had to write `U` on the template line, right? Like - 
`template rank(T, U)`
Question 2 - The statif if test is - `T t == U[ ]` What does that 
mean ?
Question 3 - if `T t == U[ ]` is the test, then I think when we 
pass

```d
rank!(int[ ][ ][ ])
```
The test will be `int[ ][ ][ ] == U[ ]`, Right ?


Re: Simple way to handle rvalues and templates.

2022-02-27 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 27 February 2022 at 06:11:28 UTC, Ali Çehreli wrote:


I don't like the name readFrom() yet but that works. :)



It seems very delicious, can stay as read():

```d
auto read(T, Endian E = Endian.bigEndian, R)
 (R range) {
  import bop = std.bitmanip;
  return bop.read!(T, E)(range);
}

void main() {
  import std.system;

  ubyte[8] d = [ 0xFF, 0xFF, 0xFF, 0xFF,
 0xAA, 0xAA, 0xFF, 0xFF ];

  ushort us = d[4..6].read!ushort;
  assert(us == 0x);
}
```
SDB79


Re: Simple way to handle rvalues and templates.

2022-02-26 Thread Ali Çehreli via Digitalmars-d-learn

On 2/26/22 19:38, Chris Piker wrote:

> But this doesn't work:
> ```d
> import std.bitmanip, std.system;
> ubyte[8192] data;
>
> ushort us = data[4..6].read!(ushort, Endian.bigEndian);
> ```
> The reasons for this are probably old hat for seasoned D programmers by
> this is really confusing for newbies.

Agreed. read() is designed to advance the buffer that it is given. It is 
thought to be convenient for the next read() operation because the 
semantics would be "read a ushort and then read an int", etc. And the 
buffer would be consumed by read().


To play the way read() wants us to play, the first thing that comes to 
mind is to read original data into a storage and define a range (data 
below) for read() to consume.


However, it requires skipping over bytes by e.g. dropExactly(), which is 
presumably a very fast operation for slices:


void main() {
  import std.bitmanip, std.system;
  ubyte[8192] storage;
  auto data = storage[];

  import std.range;
  data.dropExactly(4);

  ushort us = data.read!(ushort, Endian.bigEndian);
  // Here, data is ready for the next read.
}

Another option is to write a wrapper which takes your slice by copy so 
that read() is happy as it consumes a parameter instead of your rvalue:


import std.system;

// Adapting read()'s interface with one difference: 'ref' is removed:

auto readFrom(T, Endian endianness = Endian.bigEndian, R)(R range) {
  import std.bitmanip;
  return range.read!(ushort, endianness);
}

void main() {
  import std.bitmanip, std.system;
  ubyte[8192] data;

  ushort us = data[4..6].readFrom!(ushort, Endian.bigEndian);
}

I don't like the name readFrom() yet but that works. :)

Ali



Simple way to handle rvalues and templates.

2022-02-26 Thread Chris Piker via Digitalmars-d-learn

Hi D

I have bit of code that was tripping me up.  I need to parse 
small fields out of a big binary read, and it looks like some 
operations just can't be composed when it comes to

using templates.  So this works:
```d
import std.bitmanip, std.system;
ubyte[8192] data;

ubyte[] temp = data[4..6];
ushort us = temp.read!(ushort, Endian.bigEndian);
// intentionally provided the default byte order for readability
```
But this doesn't work:
```d
import std.bitmanip, std.system;
ubyte[8192] data;

ushort us = data[4..6].read!(ushort, Endian.bigEndian);
```
The reasons for this are probably old hat for seasoned D 
programmers by this is really confusing for newbies.


Is there a better way to handle this instead of making a bunch of 
temporary variables that I don't care about?  Matlab has this 
behavior too, statements that should be composable aren't, and it 
drives me crazy since Java and Python don't seem to suffer from 
this problem near a much.


Re: Can anyone provide an example of how D templates are overridable by global symbols?

2022-02-02 Thread Siarhei Siamashka via Digitalmars-d-learn

On Saturday, 29 January 2022 at 00:52:10 UTC, H. S. Teoh wrote:
Trying out what I suggested on different OS's and toolchains 
will give you a good idea of what's actually out there.


I will just reply with a quote from 
https://forum.dlang.org/post/mailman.400.1643853436.20251.digitalmars-d-le...@puremagic.com : "In any case, just because it worked by chance does not mean it's OK".


Re: Can anyone provide an example of how D templates are overridable by global symbols?

2022-01-28 Thread Ali Çehreli via Digitalmars-d-learn

On 1/28/22 16:17, Siarhei Siamashka wrote:
> On Friday, 28 January 2022 at 23:43:00 UTC, H. S. Teoh wrote:
>> You don't have to rely on any opinions. Try it out yourself and find
>> out for sure.
>
> I guess, my problem and the source of all confusion is that I'm way too
> used to developing C++ code.

I am confused too. Weak symbols are a concept beyond D and C++ so it 
should be the same with C++. Testing, the following C++ program does 
compile foo as a weak symbol as well:


template 
void foo() {
}

int main() {
  foo();
}

> And in the C++ ecosystem your
> recommendation is a recipe for disaster.

And it is.

> It's absolutely necessary to
> have perfect understanding about what's going on and which guarantees
> are provided.

Good luck with that. :) There aren't many people who know what linkers 
and loaders actually do.


> Accidentally relying on undefined behavior will backfire,
> because [Murphy's law](https://en.wikipedia.org/wiki/Murphy%27s_law) is
> unfortunately very real.

Yes.

What Johan said makes the most sense to me: The onus of ensuring ODR is 
on the user. Given the state of languages and linkers, I have to ensure 
that.


Ali



Re: Can anyone provide an example of how D templates are overridable by global symbols?

2022-01-28 Thread H. S. Teoh via Digitalmars-d-learn
On Sat, Jan 29, 2022 at 12:17:49AM +, Siarhei Siamashka via 
Digitalmars-d-learn wrote:
> On Friday, 28 January 2022 at 23:43:00 UTC, H. S. Teoh wrote:
> > You don't have to rely on any opinions. Try it out yourself and find
> > out for sure.
> 
> I guess, my problem and the source of all confusion is that I'm way
> too used to developing C++ code. And in the C++ ecosystem your
> recommendation is a recipe for disaster. It's absolutely necessary to
> have perfect understanding about what's going on and which guarantees
> are provided. Accidentally relying on undefined behavior will
> backfire, because [Murphy's
> law](https://en.wikipedia.org/wiki/Murphy%27s_law) is unfortunately
> very real.

Trying out what I suggested on different OS's and toolchains will give
you a good idea of what's actually out there.


T

-- 
If lightning were to ever strike an orchestra, it'd always hit the conductor 
first.


Re: Can anyone provide an example of how D templates are overridable by global symbols?

2022-01-28 Thread Siarhei Siamashka via Digitalmars-d-learn

On Friday, 28 January 2022 at 23:43:00 UTC, H. S. Teoh wrote:
You don't have to rely on any opinions. Try it out yourself and 
find out for sure.


I guess, my problem and the source of all confusion is that I'm 
way too used to developing C++ code. And in the C++ ecosystem 
your recommendation is a recipe for disaster. It's absolutely 
necessary to have perfect understanding about what's going on and 
which guarantees are provided. Accidentally relying on undefined 
behavior will backfire, because [Murphy's 
law](https://en.wikipedia.org/wiki/Murphy%27s_law) is 
unfortunately very real.


Re: Can anyone provide an example of how D templates are overridable by global symbols?

2022-01-28 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jan 28, 2022 at 11:01:41PM +, Siarhei Siamashka via 
Digitalmars-d-learn wrote:
[...]
> Internet seems to disagree about what happens when multiple weak
> symbols are encountered and various interpretations can be found:
> "Given multiple weak symbols, choose any of the weak symbols", "if
> there exists several weak symbols, GCC will choose one that have the
> largest size (memory occupation)", etc. And I'm not inclined to
> happily rely on either of these opinions.

You don't have to rely on any opinions. Try it out yourself and find out
for sure. E.g., compile several versions of exactly the same function
(e.g, each printing something different), make sure you mark them as
weak functions and rename the object files into different names.  Link
them all together with another object file that contains main() that
calls the weak symbol. Running the program ought to tell you which
version got linked.  Try linking in different orders (specify the object
files in different orders in your compile/link command) to see what
differences there might be.


T

-- 
Democracy: The triumph of popularity over principle. -- C.Bond


Re: Can anyone provide an example of how D templates are overridable by global symbols?

2022-01-28 Thread Siarhei Siamashka via Digitalmars-d-learn

On Thursday, 27 January 2022 at 21:50:12 UTC, kinke wrote:

An example:

[...]

Now if the calls are inlined, the behavior might not be 
consistent anymore. So separate compilations with different 
compiler flags can cause observable differences.


Thanks! This was very informative. Though I'm not convinced that 
having a single (but randomly chosen) function used across the 
whole program is much better than a random mix of multiple 
versions. Especially if (unlike your example) this function 
doesn't identify itself in a user visible way. Both cases are 
bad, one is just much worse than the other.


Internet seems to disagree about what happens when multiple weak 
symbols are encountered and various interpretations can be found: 
"Given multiple weak symbols, choose any of the weak symbols", 
"if there exists several weak symbols, GCC will choose one that 
have the largest size (memory occupation)", etc. And I'm not 
inclined to happily rely on either of these opinions.


Re: Can anyone provide an example of how D templates are overridable by global symbols?

2022-01-27 Thread kinke via Digitalmars-d-learn

An example:

a.d:
```
import core.stdc.stdio;

void foo()() {
version (Oops)
printf("  foo - oops\n");
else
printf("  foo\n");
}

void doA() {
printf("doA:\n");
foo!();
}
```

b.d:
```
import core.stdc.stdio;
import a;

void main() {
printf("main:\n");
foo!();
doA();
}
```

```bash
$ dmd -c a.d -version=Oops
$ dmd -c b.d
$ dmd a.o b.o -of=ab
$ ./ab
main:
  foo - oops
doA:
  foo - oops
$ dmd b.o a.o -of=ba
$ ./ba
main:
  foo
doA:
  foo
```

Each object file contains a foo!() instantiation (in a.o, the 
Oops version). No inlining, so the linker takes one of the weak 
definitions, and we end up with a consistent behavior for both 
calls - but the picked version is determined by the order of the 
object files.


Now if the calls are inlined, the behavior might not be 
consistent anymore. So separate compilations with different 
compiler flags can cause observable differences.


Re: Can anyone provide an example of how D templates are overridable by global symbols?

2022-01-27 Thread Siarhei Siamashka via Digitalmars-d-learn
On Thursday, 9 December 2021 at 21:06:54 UTC, Siarhei Siamashka 
wrote:
On Thursday, 9 December 2021 at 20:53:52 UTC, Siarhei Siamashka 
wrote:
  How would one construct a simple example of a template 
symbol getting successfully overridden by a global symbol?


Forgot to mention that a template function can be overridden by 
another function with the same name. But only as long as all of 
this happens in the scope of a single module. Here are a few 
examples (all of them successfully compile and run):


```D
import std.stdio;

T f(T)(T a, T b) { return a + b; }
int f(int a, int b) { return a - b; }

void main()
{
  f(2, 1).writeln; // prints "1"
}
```

```D
import std.stdio;

int f(int a, int b) { return a - b; }
T f(T)(T a, T b) { return a + b; }

void main()
{
  f(2, 1).writeln; // prints "1"
}
```

```D
import std.stdio;

import template_f;
int f(int a, int b) { return a - b; }

void main()
{
  f(2, 1).writeln; // prints "1"
}
```

```D
import std.stdio;

import nontemplate_f;
T f(T)(T a, T b) { return a + b; }

void main()
{
  f(2, 1).writeln; // prints "3"
}
```

This mostly agrees with the following part of the D language 
specification: https://dlang.org/spec/module.html#name_lookup


Except that having a template function and a non-template 
function with the same name within the same module scope doesn't 
seem to be explicitly documented in the D specification. But such 
name clash appears to be resolved in favor of a non-template 
function. And this behavior shouldn't inhibit functions inlining.


Re: How to properly use variadic templates (functions)?

2021-12-22 Thread eugene via Digitalmars-d-learn

sorry for intervening... :)

On Wednesday, 22 December 2021 at 08:17:03 UTC, rempas wrote:

No garbage collector, no exceptions


GOLDEN WORDS!!!

Yeah, Seriously D's developers and user really underestimate 
the fact that the biggest percent of people not using D are 
doing so because of the Garbage Collector. D's community makes 
it like it's not much of a big deal but it actually is.


Exactly!



Re: How to properly use variadic templates (functions)?

2021-12-22 Thread rempas via Digitalmars-d-learn

On Tuesday, 21 December 2021 at 22:50:57 UTC, russhy wrote:


I took a look and to be honest, it's the same story as 
everything in the STD, they try to do everything at the same 
time, so they up end calling each other, you end up lost in 
multiple 8k LOC modules, not understanding what the function is 
doing anymore, it's a rotten place


Finally someone said it!!! No offense to the Phobos developers 
but the library is a huge mess in runtime/compile performance and 
its API is not always clean and consistent making the library 
annoying to use some times. Hell, even libc is not very good as 
it is very bare bones and believe it or not, we could achieve 
better performance for most staff from libc. We need a new system 
library that won't depend on anything ASAP! No garbage collector, 
no exceptions, no complicated struct types etc. Just a simple, 
clean, consistent, really fast and easy to use library!




Plus they are not nogc

Yeah, Seriously D's developers and user really underestimate the 
fact that the biggest percent of people not using D are doing so 
because of the Garbage Collector. D's community makes it like 
it's not much of a big deal but it actually is.


OP's attempt is clean, you know what's up, you can read the 
code, free of dependencies (for now), and hopefully nogc



i want to encourage more code like that

Thanks! Code readability and a clean and easy to use API is the 
plan for the library. I want people to enjoy using the library 
while they will have the best possible runtime and compile 
performance at the same time. I am a novice even to the easier 
high level programming and so I will not a lot of help. But this 
will not stop me and hopefully we can make something great 
together!


Re: How to properly use variadic templates (functions)?

2021-12-21 Thread russhy via Digitalmars-d-learn
On Tuesday, 21 December 2021 at 18:51:38 UTC, Stanislav Blinov 
wrote:

On Tuesday, 21 December 2021 at 15:42:59 UTC, russhy wrote:
Please keep us updated, that'll be interesting to see how a 
pure D printf would look like!


It already exists, it's called std.format.write.formattedWrite, 
in terms of which things like std.stdio.writef are implemented.


I took a look and to be honest, it's the same story as everything 
in the STD, they try to do everything at the same time, so they 
up end calling each other, you end up lost in multiple 8k LOC 
modules, not understanding what the function is doing anymore, 
it's a rotten place


Plus they are not nogc

OP's attempt is clean, you know what's up, you can read the code, 
free of dependencies (for now), and hopefully nogc



i want to encourage more code like that


Re: How to properly use variadic templates (functions)?

2021-12-21 Thread Stanislav Blinov via Digitalmars-d-learn

On Tuesday, 21 December 2021 at 15:42:59 UTC, russhy wrote:
Please keep us updated, that'll be interesting to see how a 
pure D printf would look like!


It already exists, it's called std.format.write.formattedWrite, 
in terms of which things like std.stdio.writef are implemented.


Re: How to properly use variadic templates (functions)?

2021-12-21 Thread rempas via Digitalmars-d-learn
On Tuesday, 21 December 2021 at 17:33:09 UTC, Steven 
Schveighoffer wrote:


The reason your original isn't working is that indexing a list 
of differently-typed things cannot be done using a runtime 
index.


I'd say that an inner function + static foreach + switch is the 
best way to convert from runtime to compile-time values. And in 
general, I would say having function templates that handle each 
arg type are usually conducive to clean and easy code.


But in the case you are suggesting, as long as you don't need 
to iterate them out of order, what you can do is foreach the 
args tuple, and do something like:


```d
foreach(arg; args)
{
   writeUpToNextDelimeter(prompt); // updates prompt to point 
at next delimiter

   processArg(arg, prompt);
}
```

-Steve


Got that! Thanks a lot Steve!



Re: How to properly use variadic templates (functions)?

2021-12-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/21/21 4:28 AM, rempas wrote:

On Tuesday, 21 December 2021 at 08:42:35 UTC, vit wrote:


You can use switch + static foreach:

```d
import std.stdio;

    //this print args in reverse order:
    void print(T...)(string prompt, T args)
    {
    void print_arg(size_t index){
    switch(index){
    static foreach(i, a; args){
    case i:
    // handle your other types
    write(a);
    return;
    }
    default:
    assert(0, "no impl");
    }
    }

    write(prompt);
    size_t len = args.length;
    while(len --> 0)
    print_arg(len);
    }

    void main(){
    print("Prompt (ignored): ", "Hello", " world!\n", 123);
    }

```


Cool! That's probably what I wanted to do! It seems that when looping 
inside a "static foreach" and taking the index, then I can compare it 
with a value that is not calculated at compile time. This way I can also 
check for the type of the variables and do my original plan which will 
make the function even better! Thanks a lot for the help dude!!!


The reason your original isn't working is that indexing a list of 
differently-typed things cannot be done using a runtime index.


I'd say that an inner function + static foreach + switch is the best way 
to convert from runtime to compile-time values. And in general, I would 
say having function templates that handle each arg type are usually 
conducive to clean and easy code.


But in the case you are suggesting, as long as you don't need to iterate 
them out of order, what you can do is foreach the args tuple, and do 
something like:


```d
foreach(arg; args)
{
   writeUpToNextDelimeter(prompt); // updates prompt to point at next 
delimiter

   processArg(arg, prompt);
}
```

-Steve


Re: How to properly use variadic templates (functions)?

2021-12-21 Thread rempas via Digitalmars-d-learn

On Tuesday, 21 December 2021 at 15:42:59 UTC, russhy wrote:
Please keep us updated, that'll be interesting to see how a 
pure D printf would look like!


Glad someone is interested! I'm actually planning to make a whole 
library ;)


Check my 
[thread](https://forum.dlang.org/thread/frjbgaymuxjqperis...@forum.dlang.org) were I'm asking about your opinion on formatting and what is my current approach.


Re: How to properly use variadic templates (functions)?

2021-12-21 Thread russhy via Digitalmars-d-learn
Please keep us updated, that'll be interesting to see how a pure 
D printf would look like!


Re: How to properly use variadic templates (functions)?

2021-12-21 Thread rempas via Digitalmars-d-learn

On Tuesday, 21 December 2021 at 08:42:35 UTC, vit wrote:


You can use switch + static foreach:

```d
import std.stdio;

//this print args in reverse order:
void print(T...)(string prompt, T args)
{
void print_arg(size_t index){
switch(index){
static foreach(i, a; args){
case i:
// handle your other types
write(a);
return; 
}
default:
assert(0, "no impl");
}
}

write(prompt);
size_t len = args.length;
while(len --> 0)
print_arg(len);
}

void main(){
print("Prompt (ignored): ", "Hello", " world!\n", 123);
}

```


Cool! That's probably what I wanted to do! It seems that when 
looping inside a "static foreach" and taking the index, then I 
can compare it with a value that is not calculated at compile 
time. This way I can also check for the type of the variables and 
do my original plan which will make the function even better! 
Thanks a lot for the help dude!!!


Re: How to properly use variadic templates (functions)?

2021-12-21 Thread vit via Digitalmars-d-learn

On Tuesday, 21 December 2021 at 08:26:17 UTC, rempas wrote:

On Tuesday, 21 December 2021 at 08:11:39 UTC, Anonymouse wrote:


I'm not certain I understand, but won't `foreach (i, a; args) 
{ /* ... */ }` in his example do that?


As in, if you necessarily must index `args` instead of using a 
foreach variable,


```d
import core.stdc.stdio : putc, stdout;

void print(T...)(string prompt, T args)
{
foreach (i, a; args)
{
alias A = typeof(args[i]);

static if (is(A : string))
{
for (int j = 0; j < args[i].length; j++)
{
putc(args[i][j], stdout);
}
}
else
{
// handle your other types
print("", A.stringof);
}
}
}

void main()
{
print("Prompt (ignored)", "Hello", " world!\n", 123);
}
```


No it will not. I will try to explain it the best way I can. 
When I say I want to index args, I mean that I want to index 
and choose which argument to use rather than use them 
continuously one after another inside a `foreach`. For example 
check the following call:


`print("Hello %s!%c", "world", '\n');`

In that case I want to first print print from "H" up to (but 
not include) "%s". Then I want to print the first argument. 
After that, I want to print the '!' character and then I want 
to print the second argument. So I need a way to keep track 
which argument was the last one I printed and manually choose 
which argument to use. So `foreach` will not do in that case 
because I don't want to continuously use the arguments one 
after another. Is is more clear now? "writef" exists in phobos 
so I'm pretty sure that there is a way to do that.


You can use switch + static foreach:

```d
import std.stdio;

//this print args in reverse order:
void print(T...)(string prompt, T args)
{
void print_arg(size_t index){
switch(index){
static foreach(i, a; args){
case i:
// handle your other types
write(a);
return; 
}
default:
assert(0, "no impl");
}
}

write(prompt);
size_t len = args.length;
while(len --> 0)
print_arg(len);
}

void main(){
print("Prompt (ignored): ", "Hello", " world!\n", 123);
}

```


Re: How to properly use variadic templates (functions)?

2021-12-21 Thread rempas via Digitalmars-d-learn

On Tuesday, 21 December 2021 at 08:11:39 UTC, Anonymouse wrote:


I'm not certain I understand, but won't `foreach (i, a; args) { 
/* ... */ }` in his example do that?


As in, if you necessarily must index `args` instead of using a 
foreach variable,


```d
import core.stdc.stdio : putc, stdout;

void print(T...)(string prompt, T args)
{
foreach (i, a; args)
{
alias A = typeof(args[i]);

static if (is(A : string))
{
for (int j = 0; j < args[i].length; j++)
{
putc(args[i][j], stdout);
}
}
else
{
// handle your other types
print("", A.stringof);
}
}
}

void main()
{
print("Prompt (ignored)", "Hello", " world!\n", 123);
}
```


No it will not. I will try to explain it the best way I can. When 
I say I want to index args, I mean that I want to index and 
choose which argument to use rather than use them continuously 
one after another inside a `foreach`. For example check the 
following call:


`print("Hello %s!%c", "world", '\n');`

In that case I want to first print print from "H" up to (but not 
include) "%s". Then I want to print the first argument. After 
that, I want to print the '!' character and then I want to print 
the second argument. So I need a way to keep track which argument 
was the last one I printed and manually choose which argument to 
use. So `foreach` will not do in that case because I don't want 
to continuously use the arguments one after another. Is is more 
clear now? "writef" exists in phobos so I'm pretty sure that 
there is a way to do that.


Re: How to properly use variadic templates (functions)?

2021-12-21 Thread Anonymouse via Digitalmars-d-learn

On Tuesday, 21 December 2021 at 06:44:36 UTC, rempas wrote:
This will not do for me because I want to do formatted output 
and I need the index. But thanks a lot for tying to help!


I'm not certain I understand, but won't `foreach (i, a; args) { 
/* ... */ }` in his example do that?


As in, if you necessarily must index `args` instead of using a 
foreach variable,


```d
import core.stdc.stdio : putc, stdout;

void print(T...)(string prompt, T args)
{
foreach (i, a; args)
{
alias A = typeof(args[i]);

static if (is(A : string))
{
for (int j = 0; j < args[i].length; j++)
{
putc(args[i][j], stdout);
}
}
else
{
// handle your other types
print("", A.stringof);
}
}
}

void main()
{
print("Prompt (ignored)", "Hello", " world!\n", 123);
}
```


Re: How to properly use variadic templates (functions)?

2021-12-20 Thread rempas via Digitalmars-d-learn

On Monday, 20 December 2021 at 22:02:02 UTC, russhy wrote:
Here how i'd do, but i'm not sure how to keep track of the 
index of the arguments, i forgot..


```D
import core.stdc.stdio: putc, stdout;

void print(T...)(string prompt, T args)
{
foreach (a; args)
{
alias A = typeof(a);

static if (is(A : string))
{
for (int j = 0; j < a.length; j++)
{
putc(a[j], stdout);
}
}
else
{
// handle your other types
print("", A.stringof);
}
}

}

void main()
{
print("Prompt (ignored)", "Hello", " world!\n", 123);
}
```


This will not do for me because I want to do formatted output and 
I need the index. But thanks a lot for tying to help!


Re: How to properly use variadic templates (functions)?

2021-12-20 Thread rempas via Digitalmars-d-learn

On Monday, 20 December 2021 at 21:49:59 UTC, Adam D Ruppe wrote:


still use

foreach(arg; args)

and skip that index variable.


I know I can use foreach ("static foreach" more specifically) but 
I need to be able to get the index to choose a specific argument 
because I want to do formatting (that's why I said "printf")


Re: How to properly use variadic templates (functions)?

2021-12-20 Thread russhy via Digitalmars-d-learn
Here how i'd do, but i'm not sure how to keep track of the index 
of the arguments, i forgot..


```D
import core.stdc.stdio: putc, stdout;

void print(T...)(string prompt, T args)
{
foreach (a; args)
{
alias A = typeof(a);

static if (is(A : string))
{
for (int j = 0; j < a.length; j++)
{
putc(a[j], stdout);
}
}
else
{
// handle your other types
print("", A.stringof);
}
}

}

void main()
{
print("Prompt (ignored)", "Hello", " world!\n", 123);
}
```



Re: How to properly use variadic templates (functions)?

2021-12-20 Thread Adam D Ruppe via Digitalmars-d-learn

On Monday, 20 December 2021 at 21:26:45 UTC, rempas wrote:

  // Suppose all 'args' are of type "string" for this example


still use

foreach(arg; args)

and skip that index variable.


How to properly use variadic templates (functions)?

2021-12-20 Thread rempas via Digitalmars-d-learn
I'm trying to implement "printf" and I'm getting an error. The 
smallest possible code to demonstrate the error is:


```
import core.stdc.stdio;

void print(T...)(string prompt, T args) {
  // Suppose all 'args' are of type "string" for this example
  ulong carg = 0;
  for (ulong i = 0; i < args[carg].length; i++) {
putc(args[carg][i], stdout);
  }
}

void main() {
  print("Prompt (ignored)", "Hello", " world!\n");
}
```

The error output I'm getting is:

```
test.d(6): Error: variable `carg` cannot be read at compile time
test.d(7): Error: variable `carg` cannot be read at compile time
test.d(12): Error: template instance `test.print!(string, 
string)` error instantiating

```

There is another error in my original code. Let's see the 
following line:


`u64 str_len = strlen(args[carg]); //u64 = ulong`

Now this should also give me the error that the variable "carg" 
cannot be read at compile time (which it probably does as it 
gives me an error when trying to use "str_len" inside a "for 
loop") but instead it gives me the following error:


```
Error: function `core.stdc.string.strlen(scope const(char*) s)` 
is not callable using argument types `(string)`
   cannot pass argument `_param_1` of type `string` to 
parameter `scope const(char*) s`

```

Any ideas?


Re: How to insert code in place with templates/mixins?

2021-12-20 Thread rempas via Digitalmars-d-learn

On Monday, 20 December 2021 at 18:58:39 UTC, bachmeier wrote:


You can see the ["String mixins" section 
here](http://ddili.org/ders/d.en/mixin.html) for more details. 
Mixins are generated at compile time, so if you're referring to 
a string mixin inside a runtime loop, the code will not be 
generated every time the loop runs.


Thanks! Yeah after I commented, I thought a little bit about how 
they generate code at compile time like you said and understand 
that what I'm saying doesn't make much sense. Have a nice day my 
friend!


Re: How to insert code in place with templates/mixins?

2021-12-20 Thread bachmeier via Digitalmars-d-learn

On Monday, 20 December 2021 at 18:23:44 UTC, rempas wrote:
On Monday, 20 December 2021 at 18:12:35 UTC, Stanislav Blinov 
wrote:


https://dlang.org/spec/traits.html#identifier


Thanks!!! Finally I was able to do it! The code is the 
following (well not in my final project but it's a 
demonstration):


```
enum add_char(string c) =
  `if (stdout_index < STDOUT_BUF_LEN) {
stdout_buffer[stdout_index++] =` ~ c ~ `;
continue;
  } else {
sys_write(1, stdout_buffer.ptr, cast(i32)stdout_index);
stdout_index = 0;
stdout_buffer[stdout_index++] =` ~ c ~ `;
continue;
  }`;

void main() {
  mixin(add_char!(__traits(identifier, c)));
}
```

I don't know if there is another way to do it but this works 
for me. Also another thing that I want to ask is if the "mixin" 
is generated every time inside a loop and if there is a better 
way to do that?


You can see the ["String mixins" section 
here](http://ddili.org/ders/d.en/mixin.html) for more details. 
Mixins are generated at compile time, so if you're referring to a 
string mixin inside a runtime loop, the code will not be 
generated every time the loop runs.


Re: How to insert code in place with templates/mixins?

2021-12-20 Thread rempas via Digitalmars-d-learn
On Monday, 20 December 2021 at 18:12:35 UTC, Stanislav Blinov 
wrote:


https://dlang.org/spec/traits.html#identifier


Thanks!!! Finally I was able to do it! The code is the following 
(well not in my final project but it's a demonstration):


```
enum add_char(string c) =
  `if (stdout_index < STDOUT_BUF_LEN) {
stdout_buffer[stdout_index++] =` ~ c ~ `;
continue;
  } else {
sys_write(1, stdout_buffer.ptr, cast(i32)stdout_index);
stdout_index = 0;
stdout_buffer[stdout_index++] =` ~ c ~ `;
continue;
  }`;

void main() {
  mixin(add_char!(__traits(identifier, c)));
}
```

I don't know if there is another way to do it but this works for 
me. Also another thing that I want to ask is if the "mixin" is 
generated every time inside a loop and if there is a better way 
to do that?


Re: How to insert code in place with templates/mixins?

2021-12-20 Thread rempas via Digitalmars-d-learn

On Monday, 20 December 2021 at 18:06:32 UTC, rempas wrote:

On Monday, 20 December 2021 at 11:58:58 UTC, Tejas wrote:


Ehh, it still fails; should've explicitly put the length of 
the array and the `extern (C)` in `main`


```d
module demo;

[ ... ]

extern(C) /+added this because you used -betterC+/ void main() 
{


while (true) {
mixin(add_char!'%');
mixin(add_char!'$');
}
}
```


Thanks! A mixin is not necessary, it will do the same thing 
without it.


Well it seem that it actually needs it...


Re: How to insert code in place with templates/mixins?

2021-12-20 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 20 December 2021 at 18:03:09 UTC, rempas wrote:

> Now the problem is that I want it to get the name of so 
> symbol and add it to a string literal.
Let's check this example: enum state(alias name) = `name` ~ ` = 
10;`;


https://dlang.org/spec/traits.html#identifier




Re: How to insert code in place with templates/mixins?

2021-12-20 Thread rempas via Digitalmars-d-learn

On Monday, 20 December 2021 at 11:58:58 UTC, Tejas wrote:


Ehh, it still fails; should've explicitly put the length of the 
array and the `extern (C)` in `main`


```d
module demo;

[ ... ]

extern(C) /+added this because you used -betterC+/ void main() {

while (true) {
mixin(add_char!'%');
mixin(add_char!'$');
}
}
```


Thanks! A mixin is not necessary, it will do the same thing 
without it.


Re: How to insert code in place with templates/mixins?

2021-12-20 Thread rempas via Digitalmars-d-learn

On Monday, 20 December 2021 at 11:30:09 UTC, rumbu wrote:


Enums (that's why the string is declarated as enum) are 
evaluated at compile time, the concatenation op will not end in 
your code as instruction, so you can do anything outside 
betterC rules as long you do it at compile time. You are just 
building some code to use later, the compiler does not generate 
any instruction for it.


In the example above you can press the AST button to see 
exactly how your code is generated.


Wnen you have doubts about a generated string you can always 
test it with ```pragma msg```. In this case, if you write:


```
pragma(msg, add_char!'%');
```

you will have in the output exactly what the compiler will 
generate for your mixin.


That's cool! And I was wondering how I can make sting literal 
concatenation at compile time. Now the problem is that I want it 
to get the name of so symbol and add it to a string literal. 
Let's check this example: enum state(alias name) = `name` ~ ` = 
10;`;


I want this to add the token of that will be used as name in the 
string. For example, I want `state!val;` to get "expanded" as 
`val = 10;` rather than `10 = 10;`. So I don't want it to take 
the value of "val" but the word/token "val" itself. I tried using 
`alias` instead of `char` for the parameter but it didn't worked. 
Do you know how I can do that?


Re: How to insert code in place with templates/mixins?

2021-12-20 Thread Tejas via Digitalmars-d-learn

On Monday, 20 December 2021 at 11:30:09 UTC, rumbu wrote:

On Monday, 20 December 2021 at 10:49:20 UTC, rempas wrote:

On Monday, 20 December 2021 at 09:30:30 UTC, rumbu wrote:

Thanks a lot for the info. When I try to use this code, I'm 
getting the following error:


```
Error: expression expected, not `%`
Error: expression expected, not `%`
```


My fault, I forgot to put some char delimiters. You can find 
tested code here:


https://run.dlang.io/is/KfdED0

So I suppose there is a problem with string concatenation. I 
couldn't use it anyway because it is inefficient and because 
I'm using betterC. Do you know any other way that I can 
concatenate strings that does not depend an the Garbage 
Collector or the standard library?


Enums (that's why the string is declarated as enum) are 
evaluated at compile time, the concatenation op will not end in 
your code as instruction, so you can do anything outside 
betterC rules as long you do it at compile time. You are just 
building some code to use later, the compiler does not generate 
any instruction for it.


In the example above you can press the AST button to see 
exactly how your code is generated.


Wnen you have doubts about a generated string you can always 
test it with ```pragma msg```. In this case, if you write:


```
pragma(msg, add_char!'%');
```

you will have in the output exactly what the compiler will 
generate for your mixin.


Ehh, it still fails; should've explicitly put the length of the 
array and the `extern (C)` in `main`


```d
module demo;

//i am just declaring these to have them.
size_t stdout_index;
enum STDOUT_BUF_LEN = 42;
char[STDOUT_BUF_LEN] stdout_buffer; /+indexing an uninitialized 
dynamic array resulted in out of bounds error even for index == 
0+/

alias i32 = int;
void sys_write(int i, void* p, int index) {}
//


enum add_char(char c) =

  `if (stdout_index < STDOUT_BUF_LEN) {
stdout_buffer[stdout_index++] ='` ~ c ~ `';
continue;
  } else {
sys_write(1, stdout_buffer.ptr, cast(i32)stdout_index);
stdout_index = 0;
stdout_buffer[stdout_index++] ='` ~ c ~ `';
continue;
  }`;

extern(C) /+added this because you used -betterC+/ void main()
{

while (true) {
mixin(add_char!'%');
mixin(add_char!'$');
}



}
```


Re: How to insert code in place with templates/mixins?

2021-12-20 Thread rumbu via Digitalmars-d-learn

On Monday, 20 December 2021 at 10:49:20 UTC, rempas wrote:

On Monday, 20 December 2021 at 09:30:30 UTC, rumbu wrote:

Thanks a lot for the info. When I try to use this code, I'm 
getting the following error:


```
Error: expression expected, not `%`
Error: expression expected, not `%`
```


My fault, I forgot to put some char delimiters. You can find 
tested code here:


https://run.dlang.io/is/KfdED0

So I suppose there is a problem with string concatenation. I 
couldn't use it anyway because it is inefficient and because 
I'm using betterC. Do you know any other way that I can 
concatenate strings that does not depend an the Garbage 
Collector or the standard library?


Enums (that's why the string is declarated as enum) are evaluated 
at compile time, the concatenation op will not end in your code 
as instruction, so you can do anything outside betterC rules as 
long you do it at compile time. You are just building some code 
to use later, the compiler does not generate any instruction for 
it.


In the example above you can press the AST button to see exactly 
how your code is generated.


Wnen you have doubts about a generated string you can always test 
it with ```pragma msg```. In this case, if you write:


```
pragma(msg, add_char!'%');
```

you will have in the output exactly what the compiler will 
generate for your mixin.







Re: How to insert code in place with templates/mixins?

2021-12-20 Thread rempas via Digitalmars-d-learn

On Monday, 20 December 2021 at 09:30:30 UTC, rumbu wrote:


because you cannot have statements directly in a template (the 
fact that is a mixin template is irelevant), only declarations.


If you want to just insert some random code, use strings. You 
can create a templated enum to store your parametrized string. 
Please note how your parameter (c) becomes part of the 
resulting string through concatenation (~):


```
enum add_char(char c) =

  `if (stdout_index < STDOUT_BUF_LEN) {
stdout_buffer[stdout_index++] =` ~ c ~ `;
continue;
  } else {
sys_write(1, stdout_buffer.ptr, cast(i32)stdout_index);
stdout_index = 0;
stdout_buffer[stdout_index++] =` ~ c ~ `;
continue;
  }`;

```

and when you want the code inserted:

```
mixin(add_char!'%');
```

If you want to be sure that your string is syntactically 
correct, use token strings 
(https://dlang.org/spec/lex.html#token_strings)


Thanks a lot for the info. When I try to use this code, I'm 
getting the following error:


```
Error: expression expected, not `%`
Error: expression expected, not `%`
```

So I suppose there is a problem with string concatenation. I 
couldn't use it anyway because it is inefficient and because I'm 
using betterC. Do you know any other way that I can concatenate 
strings that does not depend an the Garbage Collector or the 
standard library?


Re: How to insert code in place with templates/mixins?

2021-12-20 Thread rumbu via Digitalmars-d-learn

On Monday, 20 December 2021 at 08:45:50 UTC, rempas wrote:
Here I am having a problem with templates again. No matter how 
much I read, I can't seem to understand how templates/mixins 
work.


So any ideas why this doesn't work?


because you cannot have statements directly in a template (the 
fact that is a mixin template is irelevant), only declarations.


If you want to just insert some random code, use strings. You can 
create a templated enum to store your parametrized string. Please 
note how your parameter (c) becomes part of the resulting string 
through concatenation (~):


```
enum add_char(char c) =

  `if (stdout_index < STDOUT_BUF_LEN) {
stdout_buffer[stdout_index++] =` ~ c ~ `;
continue;
  } else {
sys_write(1, stdout_buffer.ptr, cast(i32)stdout_index);
stdout_index = 0;
stdout_buffer[stdout_index++] =` ~ c ~ `;
continue;
  }`;

```

and when you want the code inserted:

```
mixin(add_char!'%');
```

If you want to be sure that your string is syntactically correct, 
use token strings (https://dlang.org/spec/lex.html#token_strings)





How to insert code in place with templates/mixins?

2021-12-20 Thread rempas via Digitalmars-d-learn
Here I am having a problem with templates again. No matter how 
much I read, I can't seem to understand how templates/mixins 
work. So I'm having the following code (just a snippet of the 
real code):


```
if (c != '%') {
  if (stdout_index < STDOUT_BUF_LEN) {
stdout_buffer[stdout_index++] = c;
continue;
  } else {
sys_write(1, stdout_buffer.ptr, cast(i32)stdout_index);
stdout_index = 0;
stdout_buffer[stdout_index++] = c;
continue;
  }
}
```

And I want to create a macro (using the C terms) to make the code 
inside the first if statement (`if (c != '%')`) into a template 
that will be able to used and added in place (not as a function 
as I don't want to function call). I tried to make it both a 
template and a mixin template and It will not compile, rather it 
will give my the following error:


```
Error: declaration expected, not `if`
Error: declaration expected, not `continue`
Error: declaration expected, not `else`
Error: basic type expected, not `0`
Error: found `0` when expecting `;`
Error: no identifier for declarator 
`stdout_buffer[stdout_index++]`

Error: declaration expected, not `=`
Error: declaration expected, not `continue`
Error: unrecognized declaration
```

It should be clear what I tried to still I will post what I tried 
in case someone is curious to see:


```
mixin template add_char() {
  if (stdout_index < STDOUT_BUF_LEN) {
stdout_buffer[stdout_index++] = c;
continue;
  } else {
sys_write(1, stdout_buffer.ptr, cast(i32)stdout_index);
stdout_index = 0;
stdout_buffer[stdout_index++] = c;
continue;
  }
}
```

So any ideas why this doesn't work?


Re: Can anyone provide an example of how D templates are overridable by global symbols?

2021-12-09 Thread Siarhei Siamashka via Digitalmars-d-learn
On Thursday, 9 December 2021 at 20:53:52 UTC, Siarhei Siamashka 
wrote:
  2. How would one construct a simple example of a template 
symbol getting successfully overridden by a global symbol?


Here's my unsuccessful attempt:

```D
module template_f;

T f(T)(T a, T b) { return a + b; }
```

```D
module nontemplate_f;

int f(int a, int b) { return a - b; }
```

```D
import std.stdio;

import template_f;
import nontemplate_f;

void main()
{
  f(2, 1).writeln;
}

```

```text
$ gdc-10.3.0 test.d
test.d:8:4: error: nontemplate_f.f at nontemplate_f.d:3:5 
conflicts with template_f.f!int.f at template_f.d:3:3

8 |   f(2, 1).writeln;
  |^
```
This is prohibited at the compilation stage and doesn't even 
reach the linker.


I guess, something a bit more elaborate needs to be done to 
simulate a global symbol from a rogue object file overriding a 
template from phobos in the resulting compiled binary. The 
question is how to achieve this.


Can anyone provide an example of how D templates are overridable by global symbols?

2021-12-09 Thread Siarhei Siamashka via Digitalmars-d-learn
A quote of Iain Buclaw from 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102765 about GDC 
behaviour:


D semantics for template symbols is that they must be 
overridable - even by normal global symbols.


So in version 11.1, the default linkage for templates was 
switched over to weak, and with that, you can't safely inline 
them without violating ODR.


My (most likely wrong) interpretation of this is that the D 
language standard somehow makes it impossible to make template 
inlining decisions at the compilation stage and this job has to 
be delegated to the linker. And as a result, the use of LTO 
becomes required for generating fast binaries. Another 
implication is that fast incremental rebuilds of optimized 
binaries are likely highly problematic.


So I have two questions:

  1. What is the exact wording of the D language standard on this 
matter?


  2. How would one construct a simple example of a template 
symbol getting successfully overridden by a global symbol?


Thanks!


Re: C++ bindings: const(T) dropped in return types of templates ?

2021-12-09 Thread Jan via Digitalmars-d-learn

On Thursday, 9 December 2021 at 07:58:46 UTC, frame wrote:

On Thursday, 9 December 2021 at 07:41:32 UTC, frame wrote:

On Monday, 6 December 2021 at 20:31:47 UTC, Jan wrote:

So am I missing something, or did the compiler somehow forget 
about the const-ness?


Sounds like a bug to me, eg this one:
https://issues.dlang.org/show_bug.cgi?id=20685


But this is no show stopper, you can always force the mangling 
with the pragma directive.

https://dlang.org/spec/pragma.html#mangle


Oh it's a known bug for over a year already :(

It is a bit of a show stopper for me, since the mangled name that 
I have isn't always correct (CastXML uses Clang and that seems to 
pick different calling conventions sometimes, than what MSVC 
would do, so the mangled names that I get are not guaranteed to 
be correct).


Well, I'll work around it for now, thanks for the answer.


Re: C++ bindings: const(T) dropped in return types of templates ?

2021-12-09 Thread frame via Digitalmars-d-learn

On Thursday, 9 December 2021 at 07:41:32 UTC, frame wrote:

On Monday, 6 December 2021 at 20:31:47 UTC, Jan wrote:

So am I missing something, or did the compiler somehow forget 
about the const-ness?


Sounds like a bug to me, eg this one:
https://issues.dlang.org/show_bug.cgi?id=20685


But this is no show stopper, you can always force the mangling 
with the pragma directive.

https://dlang.org/spec/pragma.html#mangle


Re: C++ bindings: const(T) dropped in return types of templates ?

2021-12-08 Thread frame via Digitalmars-d-learn

On Monday, 6 December 2021 at 20:31:47 UTC, Jan wrote:

So am I missing something, or did the compiler somehow forget 
about the const-ness?


Sounds like a bug to me, eg this one:
https://issues.dlang.org/show_bug.cgi?id=20685



C++ bindings: const(T) dropped in return types of templates ?

2021-12-06 Thread Jan via Digitalmars-d-learn
I am trying to auto-generate bindings for C++ code in D. I've 
come across something that looks like a bug in DMD to me, but 
since I'm such a newbie in D maybe I am missing something.


My C++ class looks like this:

```cpp
template 
struct Vec3Template
{
  static const Vec3Template ZeroVector();
};
```

And my D binding code looks like this:

```cpp
extern(C++) struct Vec3Template(TYPE)
{
  static const(Vec3Template!(TYPE)) ZeroVector();
}
alias Vec3 = Vec3Template!(float);
```

However, when I try to use Vec3.ZeroVector() I am getting a 
linker error about unresolved symbols. It works with other 
functions, the error is specific to this function.


Now it complains that it can't find this one:
`?ZeroVector@?$Vec3Template@M@@SA?AU1@XZ`

However, I am using castXml to extract my C++ information, and 
that says that the mangled name should be:

`?ZeroVector@?$Vec3Template@M@@SA?BU1@XZ`

Running both names through undname.exe, an MSVC tool that 
generates the undecorated function name from the mangled name, it 
says that the latter function definition should be:
`public: static struct Vec3Template const __cdecl 
Vec3Template::ZeroVector(void)`


Whereas the former definition would be:
`public: static struct Vec3Template __cdecl 
Vec3Template::ZeroVector(void)`


So the one that D tries to link against is missing the `const`.

However, unless I misunderstood how to apply const to a type in 
D, you can see that I did wrap the type in const(). (I also tried 
immutable, but that's not allowed for extern C++ code).


So am I missing something, or did the compiler somehow forget 
about the const-ness?


I'm currently using DMD64 D Compiler v2.098.0-dirty


Re: Regular Templates May Be `mixin`d?

2021-10-03 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 3 October 2021 at 03:34:19 UTC, surlymoor wrote:

Lord, I'm careless. Thanks.
So the difference between a `mixin template` and a regular one 
is that the former may only be used with a `mixin` statement?


Yes, exactly.


Re: Regular Templates May Be `mixin`d?

2021-10-02 Thread surlymoor via Digitalmars-d-learn

On Sunday, 3 October 2021 at 03:04:29 UTC, Paul Backus wrote:

On Sunday, 3 October 2021 at 02:52:20 UTC, surlymoor wrote:
This compiles and works. I checked the spec, and I don't see 
anything; probably missed it, however; mentioning the fact 
that regular templates may be used with `mixin`. Is this 
expected?


Yes, this is intentional and expected. From the spec:

A TemplateMixin takes an arbitrary set of declarations from 
the body of a TemplateDeclaration and inserts them into the 
current context.


Source: https://dlang.org/spec/template-mixin.html

Notice that it is specified to work with any template 
declaration, not just one declared as a `mixin template`.


Lord, I'm careless. Thanks.
So the difference between a `mixin template` and a regular one is 
that the former may only be used with a `mixin` statement?


Re: Regular Templates May Be `mixin`d?

2021-10-02 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 3 October 2021 at 02:52:20 UTC, surlymoor wrote:
This compiles and works. I checked the spec, and I don't see 
anything; probably missed it, however; mentioning the fact that 
regular templates may be used with `mixin`. Is this expected?


Yes, this is intentional and expected. From the spec:

A TemplateMixin takes an arbitrary set of declarations from the 
body of a TemplateDeclaration and inserts them into the current 
context.


Source: https://dlang.org/spec/template-mixin.html

Notice that it is specified to work with any template 
declaration, not just one declared as a `mixin template`.


Regular Templates May Be `mixin`d?

2021-10-02 Thread surlymoor via Digitalmars-d-learn

```d
// Modified sixth example from 
https://dlang.org/spec/template-mixin.html


int y = 3;

template Foo()
{
int abc() { return y; }
}

void main()
{
int y = 8;
mixin Foo; // local y is picked up, not global y
assert(abc() == 8);
}
```
This compiles and works. I checked the spec, and I don't see 
anything; probably missed it, however; mentioning the fact that 
regular templates may be used with `mixin`. Is this expected?


Re: Templates for instantiating derived class

2021-09-20 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/20/21 6:16 PM, rjkilpatrick wrote:
Essentially, I would like to write a template that calls the constructor 
of the parent class or the constructor of the inherited class, depending 
on its type.




...


Some kind of `return new this(...)` would be good, but that's not possible.
I think it has to be done with templates, but I'm not sure how to do this.

Any help would be greatly appreciated.


What you want is to change that operator into a virtual function. Yes, 
you still have to write the overrides, but you could if you want use a 
mixin. Adam's solution works, but only uses the static type.


```d
class Super {
private int _a;
this(){}
this(int a) {
_a = a;
}

Super performAdd(int rhs) const {
return new Super(_a + rhs);
}

alias opBinary(string op : "+") = performAdd;
}

class Derived : Super {
this(){}
this(int a) {
_a = a + 1;
}

override Derived performAdd(int rhs) {
return new Derived(_a + rhs);
}
}

void main() {
import std : writeln;

Super foo = new Super(1);
Super foo2 = foo + 1; // Works fine as calls `Super` constructor

Derived bar = new Derived(2);
Derived bar2 = bar + 1; // works now

Super b2 = bar;
Derived d2 = cast(Derived)(b2 + 1); // ok, *and* calls Derive's 
version of performAdd

assert(d2 !is null && d2._a == bar2._a);
}
```


Re: Templates for instantiating derived class

2021-09-20 Thread Adam Ruppe via Digitalmars-d-learn

On Monday, 20 September 2021 at 22:16:47 UTC, rjkilpatrick wrote:

auto opBinary(string op)(int rhs) const if (op == "+") {
return new Super(_a + rhs); // Creates of type Super 
even when called from derived class

}


Make this

auto opBinary(string op, this This)(int rhs) .
  return new This(_a + rhs);
}


The template this param is the static type it is called on.

https://dlang.org/spec/template.html#template_this_parameter


Note though that this is the static type. If you  do

Super thing = new Derived();
thing + 5;


it will still return Super since that's the type it was called 
through. If you want it to actually return derived, you'll have 
to add a virtual factory function:



class Super {
protected Super factory() { return new Super(); }
}

class Derived : Super {
override Derived factory() { return new Derived(); }
}


Then you can call obj.factory to get the right dynamic type. 
(forward args as needed etc.)


Some kind of `return new this(...)` would be good, but that's 
not possible.


You can do `return new typeof(this)(...);` fyi but it is again 
the static type of this, which will be whatever it is where it is 
defined. This is a useful trick if you were to make that factory 
function a mixin template or something though.


Templates for instantiating derived class

2021-09-20 Thread rjkilpatrick via Digitalmars-d-learn
Essentially, I would like to write a template that calls the 
constructor of the parent class or the constructor of the 
inherited class, depending on its type.


```d
#!/usr/bin/env dub
/+ dub.sdl:
name "mwe"
+/
class Super {
private int _a;
this(){}
this(int a) {
_a = a;
}

auto opBinary(string op)(int rhs) const if (op == "+") {
return new Super(_a + rhs); // Creates of type Super even 
when called from derived class

}
}

class Derived : Super {
this(){}
this(int a) {
_a = a + 1;
}
}

void main() {
import std : writeln;

Super foo = new Super(1);
Super foo2 = foo + 1; // Works fine as calls `Super` 
constructor


Derived bar = new Derived(2);
Derived bar2 = bar + 1; // Cannot implicitly cast `Super` to 
`Derived`

}
```

Some kind of `return new this(...)` would be good, but that's not 
possible.
I think it has to be done with templates, but I'm not sure how to 
do this.


Any help would be greatly appreciated.


Re: vibe.d: is it possible to use bare HTML with the functionalty of DIET templates ?

2021-09-01 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/31/21 8:40 PM, someone wrote:

On Tuesday, 31 August 2021 at 14:06:32 UTC, Steven Schveighoffer wrote:

The generation of code to output the page depends on the diet file 
format (i.e. code islands are designated by the leading `-`).



However, vibe-d does not require using the diet template system.


Does that means I can still get the code islands resolved on a, say, 
plain-XHTML file ?


Or does that means that I should output HTML/XHTML from my own functions 
instead ?


Vibe just provides an output range for use in diet. You can use 
anything, including just writing the data yourself, or using an 
alternative template system.


Given how templating systems work (and how D allows strings to be used 
as code using mixins), it's likely pretty trivial to write a simple 
templating system to do this. All you need is an escape protocol that 
is unlikely to appear in HTML, and you can probably get away with a 10 
line function that doesn't need to actually parse the HTML.


Probably. Bit I am not a huge fan of modifying libraries for minor 
functionality fixes (unless is really really necessary). For whatever 
reasons I already have custom nginx builds etc etc so I do not want to 
keep tracking and fixing more software -in the end is a pain-in-the-ass.


You aren't modifying anything. Vibe-d provides default access to 
diet-ng, but you have no obligation to use it. Just use the output range 
(`HTTPServerResponse.bodyWriter`) and hook up your preferred templating 
system.


I think you are misunderstanding the architecture of vibe. There is no 
need to replace anything inside vibe to use a different templating 
system, it does not depend on diet at all, just provides default access.


The views directory isn't exactly special either (though there may be 
code in dub that deals with looking at modification times), nor is the 
extension `.dt`.


Most of the diet compiler is dealing with transforming the pug format 
into HTML, and proper string interpolation. The code island stuff is 
quite trivial (just copied as-is).


Oh, and I realized I forgot about string interpolation. You definitely 
want a way to change D expressions into string output. You can still do 
this with code-islands, but a good template system would handle the 
boilerplate for you.


Which leads me to -- diet really should be split into 2 parts, one that 
handles the pug parsing and compiling, and one that handles proper 
string interpolation. Then you could leverage that second part.


-Steve


Re: vibe.d: is it possible to use bare HTML with the functionalty of DIET templates ?

2021-08-31 Thread someone via Digitalmars-d-learn

On Tuesday, 31 August 2021 at 07:40:10 UTC, bauss wrote:


You might be interested in https://yuraiweb.org/

Even though it's a work in progress then you should be able to 
get by just fine with the basics for now.


Thanks for the tip bauss :) !

I am exploring it right now. Main problem is the lack of 
documentation:


https://yuraiweb.org/docs/specifications/basics ... every section 
is empty.


My two cents-so-far:

https://yuraiweb.org/

Functionality   DietYurai

...

Total Score*9(11)/2020/20

* A higher score is better.

Methinks things like this are downs, its like insulting the 
intelligence of their potential customers. They are advertising 
software not kitchen appliances for gramma. At least they are 
reminding me that higher scores are better ... thanks for the tip 
you yurai developers !


Re: vibe.d: is it possible to use bare HTML with the functionalty of DIET templates ?

2021-08-31 Thread someone via Digitalmars-d-learn
On Tuesday, 31 August 2021 at 14:06:32 UTC, Steven Schveighoffer 
wrote:


The generation of code to output the page depends on the diet 
file format (i.e. code islands are designated by the leading 
`-`).



However, vibe-d does not require using the diet template system.


Does that means I can still get the code islands resolved on a, 
say, plain-XHTML file ?


Or does that means that I should output HTML/XHTML from my own 
functions instead ?


There are others which probably do what you want (search on 
code.dlang.org), but I'm a huge fan of diet templates (I 
actually prefer writing non-template html that way), so I don't 
have any experience with others.


https://yuraiweb.org/ as pointed by another user seems something 
I probably want to give it a try -it still relies on vibe.d but 
switched to plain HTML with its own code-islands more-or-less 
a-la ASP.net ... although it is still a work-in-progress.


Given how templating systems work (and how D allows strings to 
be used as code using mixins), it's likely pretty trivial to 
write a simple templating system to do this. All you need is an 
escape protocol that is unlikely to appear in HTML, and you can 
probably get away with a 10 line function that doesn't need to 
actually parse the HTML.


Probably. Bit I am not a huge fan of modifying libraries for 
minor functionality fixes (unless is really really necessary). 
For whatever reasons I already have custom nginx builds etc etc 
so I do not want to keep tracking and fixing more software -in 
the end is a pain-in-the-ass.


However, I think vibe.d perhaps ought to provide a switch/flag to 
enable/disable DIET constructs on source files (views) resolving 
its code islands. Or more straightforward, if the requested file 
already has another extension other than the one used by DIET 
files just resolve the code-islands and be with it. No 
client-side code changes -business as usual. Or use another 
directory other than /views/ for bare files without DIET syntax. 
Just thinking ... what do you think ?



-Steve





Re: vibe.d: is it possible to use bare HTML with the functionalty of DIET templates ?

2021-08-31 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/30/21 8:09 PM, someone wrote:
Regarding vibe.d I think I'll give it a try (maybe placing it behind 
nginx at first) since I do really got a good first-impression ... kudos 
to the developers/maintainers :)


I like the idea of having D at my disposal within a web page, actually, 
it is a terrific feature to say the least.


What I do not like (even a bit) are the pseudo-HTML DIET templates. I 
can understand they can make life easy for some, but I am not the guy 
having any trouble writing well-good-structured HTML/XHTML/XML/etc to 
begin with, nor I am the kind of guy grunting because I will be forced 
to write closing tags and the like.


That being said, my specific question is:

Can I use vibe.d *without* DIET templates manually writing say, XHTML 
1.1 pages, *while having D* at my disposal with the - prefixes I have 
seen so far ?


The generation of code to output the page depends on the diet file 
format (i.e. code islands are designated by the leading `-`).


However, vibe-d does not require using the diet template system. There 
are others which probably do what you want (search on code.dlang.org), 
but I'm a huge fan of diet templates (I actually prefer writing 
non-template html that way), so I don't have any experience with others.


Given how templating systems work (and how D allows strings to be used 
as code using mixins), it's likely pretty trivial to write a simple 
templating system to do this. All you need is an escape protocol that is 
unlikely to appear in HTML, and you can probably get away with a 10 line 
function that doesn't need to actually parse the HTML.


-Steve


Re: vibe.d: is it possible to use bare HTML with the functionalty of DIET templates ?

2021-08-31 Thread bauss via Digitalmars-d-learn

On Tuesday, 31 August 2021 at 00:09:14 UTC, someone wrote:
Regarding vibe.d I think I'll give it a try (maybe placing it 
behind nginx at first) since I do really got a good 
first-impression ... kudos to the developers/maintainers :)


I like the idea of having D at my disposal within a web page, 
actually, it is a terrific feature to say the least.


What I do not like (even a bit) are the pseudo-HTML DIET 
templates. I can understand they can make life easy for some, 
but I am not the guy having any trouble writing 
well-good-structured HTML/XHTML/XML/etc to begin with, nor I am 
the kind of guy grunting because I will be forced to write 
closing tags and the like.


That being said, my specific question is:

Can I use vibe.d *without* DIET templates manually writing say, 
XHTML 1.1 pages, *while having D* at my disposal with the - 
prefixes I have seen so far ?


I mean, I am almost sure I can write D functions returning text 
and making my web page on-the-fly, but this is not what I have 
in mind, I would like to have an actual text file for a web 
page with the aforementioned - prefixes to actually hook D code 
leveraging the pre-compiled feature of DIET templates.


You might be interested in https://yuraiweb.org/

Even though it's a work in progress then you should be able to 
get by just fine with the basics for now.


Re: vibe.d: is it possible to use bare HTML with the functionalty of DIET templates ?

2021-08-30 Thread Adam D Ruppe via Digitalmars-d-learn

On Tuesday, 31 August 2021 at 00:09:14 UTC, someone wrote:
Can I use vibe.d *without* DIET templates manually writing say, 
XHTML 1.1 pages, *while having D* at my disposal with the - 
prefixes I have seen so far ?


I don't know much about vibe.d (I have my own D web stuff) but 
just for fun I wanted to try passing my dom.d through the ctfe 
engine to do the embedded code thing.


50ish lines for the basic extractor i slapped together in 20 mins.

---

import arsd.dom;

string toD(string s) {
return `append(` ~ "`" ~ s ~ "`" ~ `);`;
}

template loadTemplateMixin(string doc) {
string helper() {
Document document = new Document;
document.parseSawAspCode = (string) => true;
document.parseStrict(doc);

string code;

void expand(Element element) {
if(auto asp = cast(AspCode) element) {
if(asp.source.length > 3 && asp.source[1] == 
'=')
code ~= `append(` ~ asp.source[2 .. 
$-1] ~ `);`;
else
code ~= asp.source[1 .. $-1];
} else if(auto tn = cast(TextNode) element) {
code ~= toD(tn.toString());
} else if(auto sn = cast(SpecialElement) element) {
code ~= toD(sn.toString());
} else {
code ~= toD("<" ~ element.tagName);
foreach(k, v; element.attributes) {
code ~= toD(" ");
code ~= toD(k.htmlEntitiesEncode);
code ~= toD("=\"");
code ~= toD(v.htmlEntitiesEncode);
code ~= toD("\"");
}

code ~= toD(">");
foreach(child; element.children)
expand(child);
code ~= toD("");
}
}

expand(document.root);

return code;

}
enum loadTemplateMixin = helper();
}


// USAGE HERE

// this could be in a file import("file.html") too btw
enum doc = ` foocssid="main"><%= my_string[0 .. 5] %>

foo
foo
foo
<% foreach(item; strings)
append(item);
%>
`;

void main() {

string html;

// and it can see these variables in the <% %> blocks
string my_string = "hello world";

string[] strings = ["omg", "wtf", "lol"];

void append(string s) {
html ~= s;
}

mixin(loadTemplateMixin!doc);

import std.stdio;
writeln(html);

}
---


Not exactly the fastest compile though but I could prolly 
optimize that if i spent a lil more time on it.


Now that it yields a string though you can return that to vibe 
using whatever method it uses.


Also note that you get a compile error on malformed input xhtml 
too.


vibe.d: is it possible to use bare HTML with the functionalty of DIET templates ?

2021-08-30 Thread someone via Digitalmars-d-learn
Regarding vibe.d I think I'll give it a try (maybe placing it 
behind nginx at first) since I do really got a good 
first-impression ... kudos to the developers/maintainers :)


I like the idea of having D at my disposal within a web page, 
actually, it is a terrific feature to say the least.


What I do not like (even a bit) are the pseudo-HTML DIET 
templates. I can understand they can make life easy for some, but 
I am not the guy having any trouble writing well-good-structured 
HTML/XHTML/XML/etc to begin with, nor I am the kind of guy 
grunting because I will be forced to write closing tags and the 
like.


That being said, my specific question is:

Can I use vibe.d *without* DIET templates manually writing say, 
XHTML 1.1 pages, *while having D* at my disposal with the - 
prefixes I have seen so far ?


I mean, I am almost sure I can write D functions returning text 
and making my web page on-the-fly, but this is not what I have in 
mind, I would like to have an actual text file for a web page 
with the aforementioned - prefixes to actually hook D code 
leveraging the pre-compiled feature of DIET templates.


Re: equivalent of std.functional.partial for templates?

2021-08-11 Thread jmh530 via Digitalmars-d-learn

On Wednesday, 11 August 2021 at 14:08:59 UTC, Paul Backus wrote:

[snip]

Should have read further--this does not work with template 
functions due to [issue 1807.][1] My mistake.


[1]: https://issues.dlang.org/show_bug.cgi?id=1807


Looks like that strengthens the case for moving forward with 
DIP1023 (or something more general).


Re: equivalent of std.functional.partial for templates?

2021-08-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On Wednesday, 11 August 2021 at 14:08:59 UTC, Paul Backus wrote:

On Wednesday, 11 August 2021 at 14:03:50 UTC, Paul Backus wrote:
On Wednesday, 11 August 2021 at 14:00:33 UTC, Steven 
Schveighoffer wrote:

I have a template function like this:

```d
auto foo(T, Args...)(Args args) {...}
```

If I try to bind the T only, and produce a partial template 
function which can accept any number of parameters, but has T 
already specified, I get an error, because instantiating 
`foo!T` means Args is length 0.


https://phobos.dpldocs.info/std.meta.ApplyLeft.html


Should have read further--this does not work with template 
functions due to [issue 1807.][1] My mistake.


[1]: https://issues.dlang.org/show_bug.cgi?id=1807


So first, I though ApplyLeft would work, but I convinced myself 
it was focused on applying the template to arguments 
individually, but that's just the example used. ApplyLeft is 
exactly what I'm looking for, but as you said (and as my example 
shows), it doesn't work in this case. It would be nice to have 
something that would work (or make ApplyLeft work via a compiler 
change).


Thanks for the nudge!

-Steve


Re: equivalent of std.functional.partial for templates?

2021-08-11 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 11 August 2021 at 14:03:50 UTC, Paul Backus wrote:
On Wednesday, 11 August 2021 at 14:00:33 UTC, Steven 
Schveighoffer wrote:

I have a template function like this:

```d
auto foo(T, Args...)(Args args) {...}
```

If I try to bind the T only, and produce a partial template 
function which can accept any number of parameters, but has T 
already specified, I get an error, because instantiating 
`foo!T` means Args is length 0.


https://phobos.dpldocs.info/std.meta.ApplyLeft.html


Should have read further--this does not work with template 
functions due to [issue 1807.][1] My mistake.


[1]: https://issues.dlang.org/show_bug.cgi?id=1807


Re: equivalent of std.functional.partial for templates?

2021-08-11 Thread Paul Backus via Digitalmars-d-learn
On Wednesday, 11 August 2021 at 14:00:33 UTC, Steven 
Schveighoffer wrote:

I have a template function like this:

```d
auto foo(T, Args...)(Args args) {...}
```

If I try to bind the T only, and produce a partial template 
function which can accept any number of parameters, but has T 
already specified, I get an error, because instantiating 
`foo!T` means Args is length 0.


https://phobos.dpldocs.info/std.meta.ApplyLeft.html


equivalent of std.functional.partial for templates?

2021-08-11 Thread Steven Schveighoffer via Digitalmars-d-learn

I have a template function like this:

```d
auto foo(T, Args...)(Args args) {...}
```

If I try to bind the T only, and produce a partial template 
function which can accept any number of parameters, but has T 
already specified, I get an error, because instantiating `foo!T` 
means Args is length 0.


I was surprised not to see something in std.meta that could 
create this for me. In `std.functional` there is `partial` (which 
bizarrely only allows one parameter to be specified), but I don't 
see an equivalent for template parameters.


For functions, it seems IFTI can't see through to infer the 
template parameters of the alias, but you can have a function 
wrapper:


```d
template bindFirst(alias F, Args...)
{
   // this doesn't work
   // alias bindFirst(Args2...) = F!(Args, Args2);
   // but this does
   auto bindFirst(Args2...)(Args2 args2) { return 
F!(Args)(args2); }

}

alias bf = bindFirst!(foo, int);
bf("hello", 5); // ok
```

It would be nice if the alias worked, but I don't know what's 
involved to make IFTI work there. I know I can alter foo to be a 
template within a template. Perhaps that's the right answer. 
However, this doesn't help for functions already written that I 
can't alter.


Any ideas on how to solve this? I know my function solution is 
not very flexible...


-Steve


Re: nested templates using Complex! with slices, ... confused, I am!

2021-08-09 Thread james.p.leblanc via Digitalmars-d-learn

On Monday, 9 August 2021 at 18:44:34 UTC, Paul Backus wrote:

On Monday, 9 August 2021 at 18:35:56 UTC, james.p.leblanc wrote:

```d
T[] foo_temp(Complex!T[])(T x, T y){
  auto r = [x, x];
  auto i = [y, y];
  auto z = [ Complex!T(x, y), Complex!T(x,y) ];
  return z;
}
```

void main(){
  auto yd = foo_double(1.1, 2.2);
  writeln(yd); ...
}


But, no ... I am WRONG!  I get the message:

qqq.d(18): Error: identifier expected for template value 
parameter


I think what you want is:

```d
Complex!T[] foo_temp(T)(T x, T y) {
  auto r = [x, x];
  auto i = [y, y];
  auto z = [ Complex!T(x, y), Complex!T(x,y) ];
  return z;
}
```

This is what I get when I take one of the non-template versions 
and replace `float` or `double` with `T`.


H.S & Paul,

Wow, thanks for the quick replies!

It all seems so simple now ... but I just could not see it!

I had been completely (and confidently, unfortunately) 
misunderstanding

the syntax of that left most column.

Thanks again,
James




  1   2   3   4   5   6   7   8   9   10   >