Re: String mixin from within a template
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
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
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
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
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
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
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
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
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
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
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?
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?
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
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