Re: String mixin from within a template

2020-08-23 Thread data pulverizer via Digitalmars-d-learn

On Sunday, 23 August 2020 at 21:13:51 UTC, ag0aep6g wrote:
On Sunday, 23 August 2020 at 20:54:22 UTC, data pulverizer 
wrote:

compiled string 1: alias x0 = Remove(indicies[i] - i, Args);
Error: found - when expecting )
Error: semicolon expected to close alias declaration
Error: no identifier for declarator i
Error: declaration expected, not ,
... repeated for the other two cases ...


As the compiler tells you, the line

alias x0 = Remove(indicies[i] - i, Args);

doesn't parse.

You can't assign the result of a function call to an `alias`.
If `Remove` is indeed a function, you need to use `enum` 
instead of `alias`.

If `Remove` is a template, you're missing an exclamation mark.

You also have a typo: "indicies" should be "indices".


Good spot on both accounts, I've also made other changes and its 
finally working.


Many thanks!


Re: String mixin from within a template

2020-08-23 Thread ag0aep6g via Digitalmars-d-learn

On Sunday, 23 August 2020 at 20:54:22 UTC, data pulverizer wrote:

compiled string 1: alias x0 = Remove(indicies[i] - i, Args);
Error: found - when expecting )
Error: semicolon expected to close alias declaration
Error: no identifier for declarator i
Error: declaration expected, not ,
... repeated for the other two cases ...


As the compiler tells you, the line

alias x0 = Remove(indicies[i] - i, Args);

doesn't parse.

You can't assign the result of a function call to an `alias`.
If `Remove` is indeed a function, you need to use `enum` instead 
of `alias`.

If `Remove` is a template, you're missing an exclamation mark.

You also have a typo: "indicies" should be "indices".


Re: String mixin from within a template

2020-08-23 Thread data pulverizer via Digitalmars-d-learn

On Sunday, 23 August 2020 at 20:12:12 UTC, ag0aep6g wrote:
On Sunday, 23 August 2020 at 19:42:47 UTC, data pulverizer 
wrote:

`alias x` ~ i ~ ` = Remove(indexes[i] - i, x`~ (i - 1) ~ `);`

[...]

```d
Error: no identifier for declarator x
```

Indicating that the concatenation `~` is not working, and I 
only get the partial string when I print out `pragma(msg, 
_string_);`


You're having a misconception about concatenation.

This:

"foo " ~ 65 ~ " bar"

does not produce the string "foo 65 bar". It produces the 
string "foo A bar", because 65 == 'A'. In your case, when i == 
0, you get a null byte in the string, which is probably the 
cause for the partial output.


You can use std.conv or std.format to make a string from a 
number:


text("foo ", 65, " bar")
format("foo %s bar", 65)


Thanks for your update. I have changed the code:

```d
import std.conv: text;
template Remove(alias indices, Args...)
{
  enum N = indices.length;
  static foreach(i; 0..N)
  {
static if(i == 0)
{
  enum _string0_ = text(`alias x`, i, ` = Remove(indicies[i] 
- i, Args);`);

  pragma(msg, "compiled string 1: ", _string0_);
  mixin(_string0_);
}else{
  enum _string1_ = text(`alias x`, i, ` = Remove(indicies[i] 
- i, x`, (i - 1), `);`);

  pragma(msg, "compiled string 2: ", _string1_);
  mixin(_string1_);
}
  }
  enum _string2_ = text(`alias Remove = x`, N - 1, `;`);
  pragma(msg, "compiled string 3: ", _string2_);
  mixin(_string2_);
}
```

and I am getting the following errors:

```
compiled string 1: alias x0 = Remove(indicies[i] - i, Args);
Error: found - when expecting )
Error: semicolon expected to close alias declaration
Error: no identifier for declarator i
Error: declaration expected, not ,
... repeated for the other two cases ...
```

Thanks



Re: String mixin from within a template

2020-08-23 Thread ag0aep6g via Digitalmars-d-learn

On Sunday, 23 August 2020 at 19:42:47 UTC, data pulverizer wrote:

`alias x` ~ i ~ ` = Remove(indexes[i] - i, x`~ (i - 1) ~ `);`

[...]

```d
Error: no identifier for declarator x
```

Indicating that the concatenation `~` is not working, and I 
only get the partial string when I print out `pragma(msg, 
_string_);`


You're having a misconception about concatenation.

This:

"foo " ~ 65 ~ " bar"

does not produce the string "foo 65 bar". It produces the string 
"foo A bar", because 65 == 'A'. In your case, when i == 0, you 
get a null byte in the string, which is probably the cause for 
the partial output.


You can use std.conv or std.format to make a string from a number:

text("foo ", 65, " bar")
format("foo %s bar", 65)


String mixin from within a template

2020-08-23 Thread data pulverizer via Digitalmars-d-learn

Hi all,

I am trying to dynamically create compile time variables by using 
string and template mixins. I have tried both approaches and they 
have failed. The central thing I am trying to create is a line 
like this:


```d
`alias x` ~ i ~ ` = Remove(indexes[i] - i, Args);`
```

where a compile time variable xi that is x0, x1, ... is created 
and this:


```d
`alias x` ~ i ~ ` = Remove(indexes[i] - i, x`~ (i - 1) ~ `);`
```

a similar idea but on the other side we have x(i-1) so for i = 1:

```d
alias x1 = Remove(indices[i] - i, x0);
```

Here is the template mixin approach for the first:

```d
mixin template MakeString1(alias i)
{
  mixin(`alias x` ~ i ~ ` = Remove(indices[i] - i, Args);`);
}
```

and the string mixin for the second approach:

```d
template Remove(long[] indices, Args...)
{
  enum N = indices.length;
  static foreach(i; 0..N)
  {
static if(i == 0)
{
  //template mixin approach
  mixin MakeString1!(i);
}else{
  // string mixin apprach
  enum _string_ = `alias x` ~ i ~ ` = Remove(indices[i] - i, 
x`~ (i - 1) ~ `);`;

  mixin(_string_);
}
  }
  mixin(`alias Remove = x` ~ i ~ `;`);
}
```

The `Remove` in the template body is an overload and works fine, 
but my attempt to use these approaches to dynamically overload 
has failed. I get errors like


```d
Error: no identifier for declarator x
```

Indicating that the concatenation `~` is not working, and I only 
get the partial string when I print out `pragma(msg, _string_);`



Thanks in advance for your help.



Re: __FILE__ and __LINE__ in case of import expression

2020-08-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/23/20 8:42 AM, Andrey Zherikov wrote:

On Saturday, 22 August 2020 at 03:43:10 UTC, Steven Schveighoffer wrote:

On 8/21/20 6:34 PM, Adam D. Ruppe wrote:

On Friday, 21 August 2020 at 22:12:48 UTC, Steven Schveighoffer wrote:
And honestly, if it says the source is "mixin-50, line 1", I think 
people will get it.


I could probably live with that too, but the status quo is pretty 
useful as-is.


I wonder if the compiler could detect when you are using a string 
literal vs. a generated or imported string, and change the behavior 
accordingly.


As far as I understand behavior of this is that mixin() changes __FILE__ 
to point to the location of this mixin. But import expression doesn't do 
so. So if import("file") could change __FILE__ to "file" and __LINE__ to 
1 internally that will make sense IMHO.

I mean something like this:
     //__FILE__='test', __LINE__=1
mixin(  //__FILE__='test-mixin-2', __LINE__=2
     //__FILE__='test-mixin-2', __LINE__=3
import("file")  //__FILE__='file', __LINE__=1   - only inside 
import()  !!!

     //__FILE__='test-mixin-2', __LINE__=5
)
     //__FILE__='test', __LINE__=7



import("file") returns a string, the source of the string is no longer 
available for the compiler after it's done importing it as a string.


However, you can easily use the #line directive to automate this...

string getImport(string file)()
{
   return "#line 1 " ~ file ~ "\n" ~ import(file);
}

mixin(getImport!"file");

-Steve


Re: __FILE__ and __LINE__ in case of import expression

2020-08-23 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 23 August 2020 at 12:50:36 UTC, Andrey Zherikov wrote:
Even this approach can lead to unclear result if you move 
'q{...}' outside of mixin:


Yes, that's why I write it very specifically the way I do, with 
q{ and mixin on the same line.


Re: __FILE__ and __LINE__ in case of import expression

2020-08-23 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 21 August 2020 at 22:34:49 UTC, Adam D. Ruppe wrote:
On Friday, 21 August 2020 at 22:12:48 UTC, Steven Schveighoffer 
wrote:

Who does that though?


An incompetent coder:

http://dpldocs.info/experimental-docs/source/arsd.cgi.d.html#L5713
http://dpldocs.info/experimental-docs/source/arsd.cgi.d.html#L5943
http://dpldocs.info/experimental-docs/source/arsd.cgi.d.html#L6018
http://dpldocs.info/experimental-docs/source/arsd.cgi.d.html#L6058


Even this approach can lead to unclear result if you move 
'q{...}' outside of mixin:

=
void test(string file = __FILE__, size_t line = __LINE__)
{
writefln("file: '%s', line: '%s'", file, line);
}

int main(string[] args)
{
enum code = q{
// empty line 15
// empty line 16
// empty line 17
// empty line 18
// empty line 19
test(); // line 20
};

test();// line 23
mixin(code);   // line 24
test();// line 25
return 0;  // line 26
}  // line 27
===

The output is the following:
file: 'test.d', line: '23'
file: 'test.d-mixin-24', line: '30'
file: 'test.d', line: '25'

Note that there is no line 30!


Re: __FILE__ and __LINE__ in case of import expression

2020-08-23 Thread Andrey Zherikov via Digitalmars-d-learn
On Saturday, 22 August 2020 at 03:43:10 UTC, Steven Schveighoffer 
wrote:

On 8/21/20 6:34 PM, Adam D. Ruppe wrote:
On Friday, 21 August 2020 at 22:12:48 UTC, Steven 
Schveighoffer wrote:
And honestly, if it says the source is "mixin-50, line 1", I 
think people will get it.


I could probably live with that too, but the status quo is 
pretty useful as-is.


I wonder if the compiler could detect when you are using a 
string literal vs. a generated or imported string, and change 
the behavior accordingly.


As far as I understand behavior of this is that mixin() changes 
__FILE__ to point to the location of this mixin. But import 
expression doesn't do so. So if import("file") could change 
__FILE__ to "file" and __LINE__ to 1 internally that will make 
sense IMHO.

I mean something like this:
//__FILE__='test', __LINE__=1
mixin(  //__FILE__='test-mixin-2', __LINE__=2
//__FILE__='test-mixin-2', __LINE__=3
import("file")  //__FILE__='file', __LINE__=1   - only 
inside import()  !!!

//__FILE__='test-mixin-2', __LINE__=5
)
//__FILE__='test', __LINE__=7



Re: vibe.d and my first web service

2020-08-23 Thread Pierce Ng via Digitalmars-d-learn

On Sunday, 23 August 2020 at 09:56:25 UTC, Andre Pany wrote:
Please have a look at the end of this site: 
https://d-land.sepany.de/tutorials/cloud/sichere-docker-images-fuer-cloud-anwendungen-erstellen/
It describes how to build really small vibed applications on 
Alpine by using docker scratch image.


Also it is possible to cache the dub package builds, but i am 
writing from my mobile and have currently no example: you copy 
dub.json / dub.selections.json first into your docker image. 
Dub.json contains a configuration with name e.g. "prebuild" and 
as far as I remember targetType "None". You execute dub build 
with this configuration and after that you copy all source code 
files into your docker image and build the complete application.

This will give you a lot faster docker builds.



Thank you, Andre. I'll try these.




Re: vibe.d and my first web service

2020-08-23 Thread Andre Pany via Digitalmars-d-learn

On Sunday, 23 August 2020 at 06:41:03 UTC, Pierce Ng wrote:

On Thursday, 20 August 2020 at 18:13:46 UTC, ddcovery wrote:

[...]


Recently I too started to look at web frameworks for compiled 
languages. Currently playing with Free Pascal - fast compiler, 
several web frameworks to evaluate, and Object Pascal is easy 
to pick up. At the same time I checked out D and Vibe, and was 
put off by the control-c thing.


[...]


Please have a look at the end of this site: 
https://d-land.sepany.de/tutorials/cloud/sichere-docker-images-fuer-cloud-anwendungen-erstellen/
It describes how to build really small vibed applications on 
Alpine by using docker scratch image.


Also it is possible to cache the dub package builds, but i am 
writing from my mobile and have currently no example: you copy 
dub.json / dub.selections.json first into your docker image. 
Dub.json contains a configuration with name e.g. "prebuild" and 
as far as I remember targetType "None". You execute dub build 
with this configuration and after that you copy all source code 
files into your docker image and build the complete application.

This will give you a lot faster docker builds.

Kind regards
Andre


Re: how stdin stream works?

2020-08-23 Thread Flade via Digitalmars-d-learn

On Thursday, 20 August 2020 at 19:13:31 UTC, Ali Çehreli wrote:

On 8/19/20 11:46 AM, Flade wrote:


[...]


Thanks Steve! I will get the input a string then as you said 
and then I'll try to convert it! Thanks a lot, have a nice day!


In some cases clearerr() and readln() may be what is needed:

import std.stdio;

void main() {
  int x;

  bool accepted = false;

  while (!accepted) {
try {
  write("x: ");
  readf(" %d", x);
  accepted = true;

} catch (Exception msg) {

  writeln("Please give a right coordinate");
  stdin.clearerr();
  stdin.readln();
}
  }

  writeln("x is ", x);
}

Note that I used " %d" because "%d/n" would not clean when 
nothing was input by just hitting the Enter key. A space 
character in the format string means "read and ignore any 
whitespace at this point" and I like it. :)


Also note I changed the name of the variable as 'accepted'. :)

Ali


Wait! Oh man I just checked your name I'm currently reading 
your book and I wanted to say that you did an EXCELLENT work and 
I love it! Thanks a lot! You are great!!!


Re: how stdin stream works?

2020-08-23 Thread Flade via Digitalmars-d-learn

On Thursday, 20 August 2020 at 19:13:31 UTC, Ali Çehreli wrote:

On 8/19/20 11:46 AM, Flade wrote:


[...]


In some cases clearerr() and readln() may be what is needed:

import std.stdio;

void main() {
  int x;

  bool accepted = false;

  while (!accepted) {
try {
  write("x: ");
  readf(" %d", x);
  accepted = true;

} catch (Exception msg) {

  writeln("Please give a right coordinate");
  stdin.clearerr();
  stdin.readln();
}
  }

  writeln("x is ", x);
}

Note that I used " %d" because "%d/n" would not clean when 
nothing was input by just hitting the Enter key. A space 
character in the format string means "read and ignore any 
whitespace at this point" and I like it. :)


Also note I changed the name of the variable as 'accepted'. :)

Ali


Thanks a lot! Very useful info!!! And sorry for answering so 
late, I wasn't expecting someone to answer so I wasn't checking. 
Have a great day my friend!


Re: vibe.d and my first web service

2020-08-23 Thread Pierce Ng via Digitalmars-d-learn

On Thursday, 20 August 2020 at 18:13:46 UTC, ddcovery wrote:
Last month I decided it was time to start a new project (my own 
company) and I reviewed some languages/frameworks for web 
development (REST services, image processing, PDF generation, 
...):  Java based ones (I'm experienced with 
scala/playframework and spring/java, and Kotlin is really 
nice), c# and Net core, Node/Typescript (Last 6 years I have 
been mainly a node backend developer) and,  finally, native 
ones (GO, Rust and D... I developed some windows apps in 90's 
using Symantec C++ but 20 years are a really long time).

[...]
Finally I'm using Rust (with Rocket and Diesel):  it's my money 
folks :).


Recently I too started to look at web frameworks for compiled 
languages. Currently playing with Free Pascal - fast compiler, 
several web frameworks to evaluate, and Object Pascal is easy to 
pick up. At the same time I checked out D and Vibe, and was put 
off by the control-c thing.


I prefer to deploy my programs as Alpine Linux Docker containers. 
Good that D is already available for Alpine. For the hello world 
Vibe example, on my Ubuntu 20.04 laptop:


% ls -l helloworld.*
-rwxr-xr-x 3 pierce pierce 8664832 Aug 23 14:04 helloworld.dmd*
-rwxr-xr-x 3 pierce pierce 2858944 Aug 23 14:04 helloworld.ldc*

The Docker images created by multistage builds:

% sudo docker images | egrep hellow
helloworldldc   86be595038026 hours 
ago 114MB
helloworlddmd   d377c0ab97ec6 hours 
ago 19.6MB


Is the huge size difference to be expected?

For both DMD and LDC, the Docker image building process took 
long. Does the following mean that everything was downloaded and 
built each time? Possible to structure the Dockerfile so that 
some bits get cached, as per "the Docker way"? (For Free Pascal, 
executables built on Ubuntu run on Alpine as is with the 
libc6-compat package, so building Docker images is really fast 
since it just involves copying a few files and reuses some cached 
Docker layers.)


 ---> Running in a95e6ef7a8c1
Fetching vibe-core 1.9.3 (getting selected version)...
Fetching botan-math 1.0.3 (getting selected version)...
Fetching taggedalgebraic 0.11.16 (getting selected version)...
Fetching vibe-d 0.9.0 (getting selected version)...
Fetching memutils 1.0.4 (getting selected version)...
Fetching stdx-allocator 2.77.5 (getting selected version)...
Fetching botan 1.12.18 (getting selected version)...
Fetching diet-ng 1.7.2 (getting selected version)...
Fetching openssl 1.1.6+1.0.1g (getting selected version)...
Fetching eventcore 0.9.7 (getting selected version)...
Fetching mir-linux-kernel 1.0.1 (getting selected version)...
Fetching libasync 0.8.6 (getting selected version)...
Running pre-generate commands for vibe-d:tls...
Performing "release" build using ldc2 for x86_64.
taggedalgebraic 0.11.16: building configuration "library"...
eventcore 0.9.7: building configuration "epoll"...
stdx-allocator 2.77.5: building configuration "library"...
vibe-core 1.9.3: building configuration "epoll"...
vibe-d:utils 0.9.0: building configuration "library"...
vibe-d:data 0.9.0: building configuration "library"...
mir-linux-kernel 1.0.1: building configuration "library"...
vibe-d:crypto 0.9.0: building configuration "library"...
diet-ng 1.7.2: building configuration "library"...
vibe-d:stream 0.9.0: building configuration "library"...
vibe-d:textfilter 0.9.0: building configuration "library"...
vibe-d:inet 0.9.0: building configuration "library"...
vibe-d:tls 0.9.0: building configuration "openssl"...
vibe-d:http 0.9.0: building configuration "library"...
/usr/include/d/std/conv.d(4614,38): Deprecation: constructor 
`vibe.stream.wrapper.ProxyStream.this` is deprecated - Use 
createProxyStream instead.
/usr/include/d/std/conv.d(4618,21): Deprecation: constructor 
`vibe.stream.wrapper.ProxyStream.this` is deprecated - Use 
createProxyStream instead.
/usr/include/d/std/range/primitives.d(174,38): Deprecation: 
`alias byKeyValue this` is deprecated - Iterate over .byKeyValue 
instead.
/usr/include/d/std/range/primitives.d(176,27): Deprecation: 
`alias byKeyValue this` is deprecated - Iterate over .byKeyValue 
instead.
/usr/include/d/std/range/primitives.d(174,38): Deprecation: 
`alias byKeyValue this` is deprecated - Iterate over .byKeyValue 
instead.
/usr/include/d/std/range/primitives.d(176,27): Deprecation: 
`alias byKeyValue this` is deprecated - Iterate over .byKeyValue 
instead.

vibe-d:mail 0.9.0: building configuration "library"...
vibe-d:mongodb 0.9.0: building configuration "library"...
/usr/include/d/std/format.d(3645,26): Deprecation: function 
`std.typecons.Nullable!string.Nullable.get_` is deprecated - 
Implicit conversion with `alias Nullable.get this` will be 
removed after 2.096. Please use `.get` explicitly.
/usr/include/d/std/format.d(3645,26): Deprecation: function 
`std.typecons.Nullable!(Alternate).Nullable.get_` is deprecated - 
Implicit conversion with `alias