Re: Template specialized functions creating runtime instructions?
On Tuesday, August 20, 2019 5:48:04 PM MDT ads via Digitalmars-d-learn wrote: > This piece of code creates a fizzbuzz string with template > parameters. > > auto fizzbuzz(uint N)() { > string accumulate; > return fizzbuzz!N(accumulate); > } > > auto fizzbuzz(uint N)(ref string result) if (N % 3 && N % 5) { > import std.conv : to; > > result ~= N.to!string ~ "\n"; > return fizzbuzz!(N - 1)(result); > } > > auto fizzbuzz(uint N)(ref string result) if (!(N % 15)) { > result ~= "FizzBuzz\n"; > return fizzbuzz!(N - 1)(result); > } > > auto fizzbuzz(uint N)(ref string result) if (!(N % 3) && N % 5) { > result ~= "Fizz\n"; > return fizzbuzz!(N - 1)(result); > } > > auto fizzbuzz(uint N)(ref string result) if (!(N % 5) && N % 3) { > result ~= "Buzz\n"; > return fizzbuzz!(N - 1)(result); > } > > auto fizzbuzz(uint N : 0)(ref string result) { > return result; > } > > void main() { > import std.stdio : writeln; > > fizzbuzz!50().writeln(); > } > > > https://godbolt.org/z/hWENgc > > In the generated assembly, it looks like it is creating a lot of > runtime instructions, contrary to my belief that templated codes > are purely compile-time. I was expecting that the compiler would > deduce the fizzbuzz string until 50 in compile-time and just > print it in the run-time. Why is this not the case? Function templates create normal functions when they're instantiated. They aren't going to be removed from the binary any more than a non-templated function would be. And the compiler has no way of knowing which functions can be removed from the final executable. It's just creating object files that get linked into the final executable. It's the linker that would have to strip unnecessary stuff out. And since fizzbuzz!50 is called at runtime, even if the linker did strip out functions that weren't needed, it couldn't strip out any of fizzbuzz!50 or anything that it calls. The compiler doesn't call functions at compile time unless they're used in a context where the value must be known at compile time. So, fizzbuzz!50.writeln(); is not going to involve any fnuctions being called at compile time. Each function template that needs to be instantiated would be instantiated, but that just creates a bunch of functions that can be called. For any functions to be called at compile time, you'd have to force it by calling a function in a context where the result must be known at compile time. e.g. enum value = fizzbuzz!50(); would result in fizzbuzz!50 being called at compile time, and then the value could be passed to writeln at runtime. If you actually want templates to do all of their work at compile time, then you wouldn't use functions. You'd just use eponymous templates. e.g. something like template factorial(int n) { static if(n == 1) enum factorial = n; else enum factorial = factorial!(n - 1) * n; } in which case the you'd use it by doing something like enum result = factorial!5; or int result = factorial!5; In either case, because factorial is purely a template, the work would be done at compile time. Alternatively, you can just call functions at compile time - you just have to make sure that the call is in a context where the result must be known at compile time. e.g. int factorial(int n) { int result = 1; foreach(i; 2 .. n + 1) result *= i; return result; } enum result = factorial(5); There arguably isn't much point in using templated functions the way you are. It would be simpler to just write a function that calculated the result normally, and then if you want to have the result at compile time, you just call the function and use the result to give an enum its value. - Jonathan M Davis
Re: Template specialized functions creating runtime instructions?
On 21.08.19 01:48, ads wrote: This piece of code creates a fizzbuzz string with template parameters. auto fizzbuzz(uint N)() { string accumulate; return fizzbuzz!N(accumulate); } auto fizzbuzz(uint N)(ref string result) if (N % 3 && N % 5) { import std.conv : to; result ~= N.to!string ~ "\n"; return fizzbuzz!(N - 1)(result); } [...] void main() { import std.stdio : writeln; fizzbuzz!50().writeln(); } https://godbolt.org/z/hWENgc In the generated assembly, it looks like it is creating a lot of runtime instructions, contrary to my belief that templated codes are purely compile-time. I was expecting that the compiler would deduce the fizzbuzz string until 50 in compile-time and just print it in the run-time. Why is this not the case? What you have there are function templates. You're generating functions at compile time, and then you're calling those generated functions at run time. To do it all at compile time, you can skip the "functions" part and generate the result directly: template fizzbuzz(uint N) if (N % 3 && N % 5) { import std.conv : to; enum fizzbuzz = N.to!string ~ "\n" ~ fizzbuzz!(N - 1); } /* ... etc ... */ You won't be able to use an accumulator, because mutation like that doesn't mix with templates. Alternatively, you can skip the "templates" part and call normal functions at compile time (CTFE): auto fizzbuzz(uint N) { string accumulate; return fizzbuzz(N, accumulate); } auto fizzbuzz(uint N, ref string result) { import std.conv : to; if (N % 3 && N % 5) result ~= N.to!string ~ "\n"; /* ... etc ... */ } void main() { import std.stdio : writeln; enum fz = fizzbuzz(50); writeln(fz); }
Re: Template specialized functions creating runtime instructions?
On Wednesday, 21 August 2019 at 00:04:37 UTC, H. S. Teoh wrote: On Tue, Aug 20, 2019 at 11:48:04PM +, ads via Digitalmars-d-learn wrote: [...] 2) Deducing the string as you describe would require CTFE (compile-time function evaluation), which usually isn't done unless the result is *required* at compile-time. The typical way to force this to happen is to store the result into an enum: enum myStr = fizzbuzz!...(...); writeln(myStr); Since enums have to be known at compile-time, this forces CTFE evaluation of fizzbuzz, which is probably what you're looking for here. T Thank you for clearing those up. However even if I force CTFE (line 35), it doesn't seem to help much. https://godbolt.org/z/MytoLF
Re: Template specialized functions creating runtime instructions?
On Tuesday, 20 August 2019 at 23:48:04 UTC, ads wrote: https://godbolt.org/z/hWENgc A somewhat similar translation in C++ also creates a lot of runtime instructions https://godbolt.org/z/psyUtq
Re: Template specialized functions creating runtime instructions?
On Tue, Aug 20, 2019 at 11:48:04PM +, ads via Digitalmars-d-learn wrote: [...] > In the generated assembly, it looks like it is creating a lot of > runtime instructions, contrary to my belief that templated codes are > purely compile-time. I was expecting that the compiler would deduce > the fizzbuzz string until 50 in compile-time and just print it in the > run-time. Why is this not the case? Let's clear up a few things: 1) "Template code" is not the same thing as "compile-time". Templates are essentially "code stencils", used for generating multiple copies (usually with variations) of the same *runtime* code. The *expansion* of the template is done at compile-time, but the *result* is often runtime code (e.g., template functions, like you have here). 2) Deducing the string as you describe would require CTFE (compile-time function evaluation), which usually isn't done unless the result is *required* at compile-time. The typical way to force this to happen is to store the result into an enum: enum myStr = fizzbuzz!...(...); writeln(myStr); Since enums have to be known at compile-time, this forces CTFE evaluation of fizzbuzz, which is probably what you're looking for here. 3) And BTW, don't confuse "templates" and CTFE, because they are not the same thing, in spite of being both done "at compile-time". See: https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time T -- Those who've learned LaTeX swear by it. Those who are learning LaTeX swear at it. -- Pete Bleackley
Template specialized functions creating runtime instructions?
This piece of code creates a fizzbuzz string with template parameters. auto fizzbuzz(uint N)() { string accumulate; return fizzbuzz!N(accumulate); } auto fizzbuzz(uint N)(ref string result) if (N % 3 && N % 5) { import std.conv : to; result ~= N.to!string ~ "\n"; return fizzbuzz!(N - 1)(result); } auto fizzbuzz(uint N)(ref string result) if (!(N % 15)) { result ~= "FizzBuzz\n"; return fizzbuzz!(N - 1)(result); } auto fizzbuzz(uint N)(ref string result) if (!(N % 3) && N % 5) { result ~= "Fizz\n"; return fizzbuzz!(N - 1)(result); } auto fizzbuzz(uint N)(ref string result) if (!(N % 5) && N % 3) { result ~= "Buzz\n"; return fizzbuzz!(N - 1)(result); } auto fizzbuzz(uint N : 0)(ref string result) { return result; } void main() { import std.stdio : writeln; fizzbuzz!50().writeln(); } https://godbolt.org/z/hWENgc In the generated assembly, it looks like it is creating a lot of runtime instructions, contrary to my belief that templated codes are purely compile-time. I was expecting that the compiler would deduce the fizzbuzz string until 50 in compile-time and just print it in the run-time. Why is this not the case?
Re: How to set a global var to a user defined section.
On Tuesday, 20 August 2019 at 17:33:17 UTC, lili wrote: Hi: With gcc we can use _ attribute _((section("name")) var; how to same in dlang? As for C(++), not standardized in the language itself. With LDC: import ldc.attributes : section; @section("name") __gshared int myGlobal;
Re: Linker errors to Windows functions
On Tuesday, 20 August 2019 at 17:29:15 UTC, Dennis wrote: On Tuesday, 20 August 2019 at 17:17:01 UTC, Vladimirs Nordholm wrote: [...] Importing only specifies that you expect the symbols to be there, it doesn't mean the functions are linked in. [...] Thank you for the explanation Dennis. Never done the `pragma(lib, ...)` before, but that definitely solved the problem!
How to set a global var to a user defined section.
Hi: With gcc we can use _ attribute _((section("name")) var; how to same in dlang?
Re: Linker errors to Windows functions
On Tuesday, 20 August 2019 at 17:17:01 UTC, Vladimirs Nordholm wrote: In code I have `import core.sys.windows.winuser;`, but still get this error. Importing only specifies that you expect the symbols to be there, it doesn't mean the functions are linked in. On Windows there are three targets, 32-bit OMF (old dmd default), 32-bit MSCoff and 64-bit MSCoff (dub defaults to MSCoff since not too long ago). While DMD ships with import libraries for all targets, I never know which ones get linked in by default and which ones don't. Usually when I get Windows linking errors I either switch the target (the OMF import libraries are sometimes lacking, so then I compile with --arch=x86_mscoff or --arch=x86_64) or explicitly link the import libraries. Just quickly Google a function like GetSystemMetrics: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics On the bottom it says "Library: User32.lib" so I add `pragma(lib, "User32.lib");` to my module using it.
Linker errors to Windows functions
Hello. I recently reinstalled Windows 10 (build 1903), and downloaded DMD (v2.087.1) and dub (v1.16.0). My project no longer compiles, giving the following errors: error LNK2019: unresolved external symbol GetSystemMetrics referenced in [...] error LNK2019: unresolved external symbol SetWindowPos referenced in function [...] The function `GetSystemMetrics` and `SetWindowPos` can be found at https://github.com/dlang/druntime/blob/master/src/core/sys/windows/winuser.d , line 3874 and 4095 respectively. In code I have `import core.sys.windows.winuser;`, but still get this error. Any clues to why this might happen?
Re: Downloading a file and showing progress via curl.
On Tuesday, 20 August 2019 at 11:51:03 UTC, Daniel Kozak wrote: For that you can use https://dlang.org/phobos/std_file#append Don't do that. It will reopen and close the file on every received chunk. Not only is it slow, but if the file is renamed/moved/deleted while the download is occurring, the file will be corrupted. The same will happen if you run the program twice, if you don't clean up. The correct way is to open a File once, then use rawWrite for every received chunk.
Re: What is "dmd" Internal API, can I use it just like std Library Reference?
On Tue, Aug 20, 2019 at 12:52:31PM +, BoQsc via Digitalmars-d-learn wrote: [...] > I found https://dlang.org/phobos/dmd_console.html and wanted to use > it. But it seems I'm not being successful, and I do not understand > why. [...] Because this is code inside the compiler, when you're compiling the compiler, not something that you can call from user code. --T
Re: What is "dmd" Internal API, can I use it just like std Library Reference?
On Tuesday, 20 August 2019 at 12:52:31 UTC, BoQsc wrote: Hello everyone, again, I had an idea that I want some colors in the output of Command Line (For Windows) and the Terminal (For Linux) yesterday was talks about terminal colors in IRC-channel: u can use VT-codes for changing colors: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#text-formatting probably for Win10 only. idk for which Linux/Terminals it working too // Windows code import std, core.sys.windows.windows; void main() { auto hc = GetStdHandle( STD_OUTPUT_HANDLE ); assert( hc != INVALID_HANDLE_VALUE); uint mod; auto ok = GetConsoleMode( hc, ); assert( ok); ok = SetConsoleMode( hc, mod | ENABLE_VIRTUAL_TERMINAL_PROCESSING ); assert( ok); writeln( "\x1b[38;2;255;100;0mTRUECOLOR"); writeln( "\x1b[30;47mHello from Inversed" ); writeln( "\x1b[38;2;255;0;255mTRUECOLOR\x1b[0m" ); // last "\x1b[0m" - make colors default readln; }
Re: How do I execute a sql-file inside D code
On Tuesday, 20 August 2019 at 11:33:33 UTC, Anders S wrote: I'm creating an application that connect to a database and write data from another application. Now when I start the application I want it to check if the database exists and if not create the database and it's tables. I have everything working IF the database and tables exist. Use this code to check conn.exec("CREATE DATABASE IF NOT EXISTS boxweb;"); however haven't found a way to run the sql file that create the tables. The file is in the source folder Any ideas ? You need to use an additional library to communicate with the database. The library to use depends on the type of database (Oracle, DB2, sqlite, Hana, postgres,...) Which database type do you target? Kind regards Andre
Re: What is "dmd" Internal API, can I use it just like std Library Reference?
On Tue, Aug 20, 2019 at 2:55 PM BoQsc via Digitalmars-d-learn wrote: > > Hello everyone, again, > > I had an idea that I want some colors in the output of Command > Line (For Windows) and > the Terminal (For Linux) > > I found https://dlang.org/phobos/dmd_console.html and wanted to > use it. > But it seems I'm not being successful, and I do not understand > why. > > Here, you can see that I'm trying to import dmd.console; > > > import std.stdio : writeln; > > import dmd.console; > > > > void main() > > { > > writeln("Hello World"); > > } > > And the output says that, dmd.console; do not exist? > What are these Internal APIs for? > > C:\Users\Juozas\Desktop>rdmd color.d > > color.d(2): Error: module `console` is in file 'dmd\console.d' > > which cannot be read It is internal and it is part of dmd compiler sources but it is not supposed to be used in normal D code. If you want colors in console you can try this: https://github.com/Kripth/terminal you can use it as a dup dependency or just add terminal.d to your code base
Re: What is "dmd" Internal API, can I use it just like std Library Reference?
On Tuesday, 20 August 2019 at 12:52:31 UTC, BoQsc wrote: And the output says that, dmd.console; do not exist? These are for when you are working on the compiler's source itself.
What is "dmd" Internal API, can I use it just like std Library Reference?
Hello everyone, again, I had an idea that I want some colors in the output of Command Line (For Windows) and the Terminal (For Linux) I found https://dlang.org/phobos/dmd_console.html and wanted to use it. But it seems I'm not being successful, and I do not understand why. Here, you can see that I'm trying to import dmd.console; import std.stdio : writeln; import dmd.console; void main() { writeln("Hello World"); } And the output says that, dmd.console; do not exist? What are these Internal APIs for? C:\Users\Juozas\Desktop>rdmd color.d color.d(2): Error: module `console` is in file 'dmd\console.d' which cannot be read
Re: Downloading a file and showing progress via curl.
On Tuesday, 20 August 2019 at 11:51:03 UTC, Daniel Kozak wrote: For that you can use https://dlang.org/phobos/std_file#append Thank you, seems to work. import std.net.curl : HTTP; import std.stdio: writeln; import std.file : append; void main() { auto http = HTTP(); // Track progress http.method = HTTP.Method.get; http.url = "https://upload.wikimedia.org/wikipedia/commons/5/53/Wikipedia-logo-en-big.png;; http.onReceive = (ubyte[] data) { append("Wikipedia-logo-en-big.png", data); return data.length; }; http.onProgress = (size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow) { writeln("Progress ", dltotal, ", ", dlnow, ", ", ultotal, ", ", ulnow); return 0; }; http.perform(); }
Re: Downloading a file and showing progress via curl.
On Tue, Aug 20, 2019 at 1:40 PM BoQsc via Digitalmars-d-learn wrote: > > Hello everyone, > I found this snippet on > https://dlang.org/phobos/std_net_curl.html#.HTTP > > > import std.net.curl : HTTP; > > import std.stdio : writeln; > > > > void main() > > { > > auto http = HTTP(); > > // Track progress > > http.method = HTTP.Method.get; > > http.url = > > "https://upload.wikimedia.org/wikipedia/commons/5/53/Wikipedia-logo-en-big.png;; > > http.onReceive = (ubyte[] data) { return data.length; }; > > http.onProgress = (size_t dltotal, size_t dlnow, size_t > > ultotal, size_t ulnow) { > > writeln("Progress ", dltotal, ", ", dlnow, ", ", > > ultotal, ", ", ulnow); > > return 0; > > }; > > http.perform(); > > } > > This snippet is showing Download Progress in bytes, but I'm > unsure how to save the > downloaded file into filesystem after download is completed. You just need to save data in onReceive callback
Re: Downloading a file and showing progress via curl.
On Tue, Aug 20, 2019 at 1:46 PM Daniel Kozak wrote: > > On Tue, Aug 20, 2019 at 1:40 PM BoQsc via Digitalmars-d-learn > wrote: > > > > Hello everyone, > > I found this snippet on > > https://dlang.org/phobos/std_net_curl.html#.HTTP > > > > > import std.net.curl : HTTP; > > > import std.stdio : writeln; > > > > > > void main() > > > { > > > auto http = HTTP(); > > > // Track progress > > > http.method = HTTP.Method.get; > > > http.url = > > > "https://upload.wikimedia.org/wikipedia/commons/5/53/Wikipedia-logo-en-big.png;; > > > http.onReceive = (ubyte[] data) { return data.length; }; > > > http.onProgress = (size_t dltotal, size_t dlnow, size_t > > > ultotal, size_t ulnow) { > > > writeln("Progress ", dltotal, ", ", dlnow, ", ", > > > ultotal, ", ", ulnow); > > > return 0; > > > }; > > > http.perform(); > > > } > > > > This snippet is showing Download Progress in bytes, but I'm > > unsure how to save the > > downloaded file into filesystem after download is completed. > > You just need to save data in onReceive callback For that you can use https://dlang.org/phobos/std_file#append
Downloading a file and showing progress via curl.
Hello everyone, I found this snippet on https://dlang.org/phobos/std_net_curl.html#.HTTP import std.net.curl : HTTP; import std.stdio : writeln; void main() { auto http = HTTP(); // Track progress http.method = HTTP.Method.get; http.url = "https://upload.wikimedia.org/wikipedia/commons/5/53/Wikipedia-logo-en-big.png;; http.onReceive = (ubyte[] data) { return data.length; }; http.onProgress = (size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow) { writeln("Progress ", dltotal, ", ", dlnow, ", ", ultotal, ", ", ulnow); return 0; }; http.perform(); } This snippet is showing Download Progress in bytes, but I'm unsure how to save the downloaded file into filesystem after download is completed.
How do I execute a sql-file inside D code
I'm creating an application that connect to a database and write data from another application. Now when I start the application I want it to check if the database exists and if not create the database and it's tables. I have everything working IF the database and tables exist. Use this code to check conn.exec("CREATE DATABASE IF NOT EXISTS boxweb;"); however haven't found a way to run the sql file that create the tables. The file is in the source folder Any ideas ?
Blog Post #63 - Saving Images with Cairo
Today we look at how to save images using Cairo with examples for JPeg, PNG, BMP, and TIFF. https://gtkdcoding.com/2019/08/20/0063-cairo-vii-draw-save-images.html
Re: Can't add a const ubyte to a dynamic array of ubyte?
On Tuesday, 20 August 2019 at 09:49:21 UTC, Daniel Kozak wrote: On Tue, Aug 20, 2019 at 11:30 AM ads via Digitalmars-d-learn wrote: you do not allow a person to think about a problem (and it’s easy here). you carried him through a puddle now, but when he dives into Sea D, you will not be there :)
Re: Can't add a const ubyte to a dynamic array of ubyte?
On Tuesday, August 20, 2019 3:27:36 AM MDT ads via Digitalmars-d-learn wrote: > import std.stdio; > > ubyte[] extend(in uint[] arr) > { > ubyte[] result; > foreach (n; arr) > { > if (n < 10) > { > result ~= n; > // source/app.d(10,11): Error: cannot > append type const(uint) to type ubyte[] > } > else > { > import std.conv : to; > > foreach (digit; n.to!string) > { > result ~= digit.to!ubyte; > } > } > } > return result; > } > > unittest > { > import std.algorithm : equal; > > assert(extend([1, 25, 70, 0]).equal([1, 2, 5, 7, 0, 0])); > } > > > How can I get around this? I want to ensure that the array is not > mutated in the function in the signature too. arr contains uints, not ubytes, so n is a uint, and you're trying to append a uint to result, which is an array of ubytes. If you want to append n to result, then you need to convert it to a ubyte - either by casting or by using to!uint (the difference being that to will throw a ConvException if the value of n doesn't fit in a ubyte). D does not allow implicit narrowing conversions (because there's no guarantee that the value will fit in the target type), so you can't assign a uint to a ubyte without an explicit conversion - and that includes appending to an array of ubytes. - Jonathan M Davis
Re: Can't add a const ubyte to a dynamic array of ubyte?
On Tuesday, 20 August 2019 at 09:27:36 UTC, ads wrote: import std.stdio; ubyte[] extend(in uint[] arr) { ubyte[] result; foreach (n; arr) { if (n < 10) result ~= n; else { import std.conv : to; foreach (digit; n.to!string) result ~= digit.to!ubyte; } } return result; } unittest { import std.algorithm : equal; assert(extend([1, 25, 70, 0]).equal([1, 2, 5, 7, 0, 0])); } How can I get around this? I want to ensure that the array is not mutated in the function in the signature too. what u using here? result ~= digit.to!ubyte; why not to do same in line? result ~= n; 2) digit is '0'+(0..9) so u need subtract '0' ('0' is \x30)
Re: Can't add a const ubyte to a dynamic array of ubyte?
On Tue, Aug 20, 2019 at 11:30 AM ads via Digitalmars-d-learn wrote: > > > How can I get around this? I want to ensure that the array is not > mutated in the function in the signature too. > https://run.dlang.io/is/tehp3j import std.stdio; ubyte[] extend(in uint[] arr) { ubyte[] result; foreach (n; arr) { if (n < 10) { result ~= cast(ubyte)n; // source/app.d(10,11): Error: cannot append type const(uint) to type ubyte[] } else { import std.conv : to; foreach (digit; n.to!string) { result ~= cast(ubyte)(digit - '0'); } } } return result; } unittest { import std.algorithm : equal; assert(extend([1, 25, 70, 0]).equal([1, 2, 5, 7, 0, 0])); }
Exercism, call for mentors
Hello, I've recently decided to pick up D, and have started doing some exercises on https://exercism.io/ (a non-profit programming exercise platform), which I think is an excellent way to pick up the basics in a new language. While doing the exercises on my own is rewarding already, I would greatly appreciate if someone would want to pick up the mantle of mentor in D over there. Evidently someone liked the idea at one point enough to contribute D versions of a lot of the exercises, but based on progress of the queue, nobody is checking it frequently at the moment. I've been doing some mentoring there myself, for Python and Bash, and I think it's quite fun, and I learn a lot that way. It forces me to regularly think hard about the basics, trying to give considered advice to beginners. Anyway, if someone would be willing to give it a go, you can go to https://exercism.io/become-a-mentor and follow the instructions there. Thanks, Björn
Can't add a const ubyte to a dynamic array of ubyte?
import std.stdio; ubyte[] extend(in uint[] arr) { ubyte[] result; foreach (n; arr) { if (n < 10) { result ~= n; // source/app.d(10,11): Error: cannot append type const(uint) to type ubyte[] } else { import std.conv : to; foreach (digit; n.to!string) { result ~= digit.to!ubyte; } } } return result; } unittest { import std.algorithm : equal; assert(extend([1, 25, 70, 0]).equal([1, 2, 5, 7, 0, 0])); } How can I get around this? I want to ensure that the array is not mutated in the function in the signature too.