Re: How to get element type of a slice?
On Saturday, 21 August 2021 at 02:59:39 UTC, Jesse Phillips wrote: On Thursday, 19 August 2021 at 04:03:31 UTC, jfondren wrote: On Thursday, 19 August 2021 at 03:32:47 UTC, Jesse Phillips wrote: On Tuesday, 17 August 2021 at 12:33:03 UTC, Ferhat Kurtulmuş wrote: Hey, thank you again but, I don't want an instance of Point[] I need: alias T = Point[]; alias ElementOfPointSlice = // element type of T so, what's the problem? This passes tests: ```d import std.range : ElementType; struct Point { int x, y; } alias T = Point[]; alias ElementOfPointSlice = ElementType!(T); unittest { assert(is(ElementOfPointSlice == Point)); } ``` No issue just trying to give Ferhat a final answer to his question. Thank you. I appreciate it.
Re: compile time compression for associatve array literal
On 23.08.21 08:14, Brian Tiffin wrote: From ~~a~~ little reading, it seems associative array literal initialization is still pending for global scope, but allowed in a module constructor? *If I understood the skimming surface reading so far*. ```d immutable string[string] things; static (this) { things = ["key1": "value 1", "key2": "value 2"]; } ``` (Typo: It's `static this()`.) Is there a magic incantation that could convert the values to a `std.zlib.compress`ed ubyte array, at compile time? So the object code gets keys:compvals instead of the full string value? There's a big roadblock: std.zlib.compress cannot go through CTFE, because the source code of zlib isn't available to the compiler; it's not even D code. Maybe there's a CTFE-able compression library on dub. If not, you can write your own function and run that through CTFE. Example with simple run-length encoding: uint[] my_compress(string s) { import std.algorithm: group; import std.string: representation; uint[] compressed; foreach (c_n; group(s.representation)) { compressed ~= [c_n[0], c_n[1]]; } return compressed; } string my_uncompress(const(uint)[] compressed) { import std.conv: to; string uncompressed = ""; for (; compressed.length >= 2; compressed = compressed[2 .. $]) { foreach (i; 0 .. compressed[1]) { uncompressed ~= compressed[0].to!char; } } return uncompressed; } import std.array: replicate; /* CTFE compression: */ enum compressed = my_compress("f" ~ "o".replicate(100_000) ~ "bar"); immutable string[string] things; shared static this() { /* Runtime decompression: */ things = ["key1": my_uncompress(compressed)]; } If you compile that, the object file should be far smaller than 100,000 bytes, thanks to the compression. [...] I'm not sure about a) if code in a module constructor is even a candidate for CTFE? The word "candidate" might indicate a common misunderstanding of CTFE. CTFE doesn't look for candidates. It's not an optimization. The language dictates which values go through CTFE. In a way, static constructors are the opposite of CTFE. Initializers in module scope do go through CTFE. When you have code that you cannot (or don't want to) put through CTFE, you put it in a static constructor. You can still trigger CTFE within a static constructor by other means (e.g., `enum`), but the static constructor itself is just another function as far as CTFE is concerned. b) what a cast might look like to get a `q"DELIM ... DELIM"` delimited string for use as input to std.zlib.compress? A cast to get a string literal? That doesn't make sense. You might be looking for `import("some_file")`. That gives you the contents of a file as a string. You can then run that string through your compression function in CTFE, put the resulting compressed data into the object file, and decompress it at runtime (like the example above does).
Unexpected result comparing to null
Hi The code below compiles and runs producing 'Not null'. ``` void main() { import std.stdio; int Var1; int* ptrVar; ptrVar = &Var1; if (ptrVar == null) { writeln("Null"); } else { writeln("Not null"); } } ``` However, should it not fail to compile, as '==' used instead of 'is'? Best regards
Re: Unexpected result comparing to null
On Monday, 23 August 2021 at 13:00:36 UTC, DLearner wrote: Hi The code below compiles and runs producing 'Not null'. ``` void main() { import std.stdio; int Var1; int* ptrVar; ptrVar = &Var1; if (ptrVar == null) { writeln("Null"); } else { writeln("Not null"); } } ``` However, should it not fail to compile, as '==' used instead of 'is'? Best regards Perhaps you're thinking of note 12 in https://dlang.org/spec/expression.html#equality_expressions ? Which ends: "Comparing against null is invalid, as null has no contents. Use the is and !is operators instead." But also begins: "**For class objects**, the == and != operators are intended to compare the contents of the objects, however an appropriate opEquals override must be defined for this to work. The default opEquals provided by the root Object class is equivalent to the is operator." ptrVal is just an int*, and == against it implies no attempt look for a opEquals. Contrast: ```d class S { int* p; this(int* p) { this.p = p; } } void main() { import std.stdio; int Var1; auto ptrVar = new S(&Var1); if (ptrVar == null) { writeln("Null"); } else { writeln("Not null"); } } ``` Which fails to compile with ``` Error: use `is` instead of `==` when comparing with `null` ```
Re: compile time compression for associatve array literal
On Monday, 23 August 2021 at 11:53:46 UTC, ag0aep6g wrote: On 23.08.21 08:14, Brian Tiffin wrote: From ~~a~~ little reading, it seems associative array literal initialization is still pending for global scope, but allowed in a module constructor? *If I understood the skimming surface reading so far*. ```d immutable string[string] things; static (this) { things = ["key1": "value 1", "key2": "value 2"]; } ``` (Typo: It's `static this()`.) Yep, that's a typo. Is there a magic incantation that could convert the values to a `std.zlib.compress`ed ubyte array, at compile time? So the object code gets keys:compvals instead of the full string value? There's a big roadblock: std.zlib.compress cannot go through CTFE, because the source code of zlib isn't available to the compiler; it's not even D code. Maybe there's a CTFE-able compression library on dub. If not, you can write your own function and run that through CTFE. Example with simple run-length encoding: uint[] my_compress(string s) { import std.algorithm: group; import std.string: representation; uint[] compressed; foreach (c_n; group(s.representation)) { compressed ~= [c_n[0], c_n[1]]; } return compressed; } string my_uncompress(const(uint)[] compressed) { import std.conv: to; string uncompressed = ""; for (; compressed.length >= 2; compressed = compressed[2 .. $]) { foreach (i; 0 .. compressed[1]) { uncompressed ~= compressed[0].to!char; } } return uncompressed; } import std.array: replicate; /* CTFE compression: */ enum compressed = my_compress("f" ~ "o".replicate(100_000) ~ "bar"); immutable string[string] things; shared static this() { /* Runtime decompression: */ things = ["key1": my_uncompress(compressed)]; } If you compile that, the object file should be far smaller than 100,000 bytes, thanks to the compression. Cool. So, is might not be obvious, but there is a path to this little nicety. [...] I'm not sure about a) if code in a module constructor is even a candidate for CTFE? The word "candidate" might indicate a common misunderstanding of CTFE. CTFE doesn't look for candidates. It's not an optimization. The language dictates which values go through CTFE. In a way, static constructors are the opposite of CTFE. Initializers in module scope do go through CTFE. When you have code that you cannot (or don't want to) put through CTFE, you put it in a static constructor. You can still trigger CTFE within a static constructor by other means (e.g., `enum`), but the static constructor itself is just another function as far as CTFE is concerned. Ok. I'm hoping this gets easier to reason with once I get further up the D curve. b) what a cast might look like to get a `q"DELIM ... DELIM"` delimited string for use as input to std.zlib.compress? A cast to get a string literal? That doesn't make sense. No, no it doesn't. And it didn't help that I had the order of AA key and value syntax backwards in my head when I was typing in the question. I was thinking it was `key[value]`, not the proper `value[key]`. So in this case, `(ubyte[])[string]` was what I *think* I'd be aiming for as the AA type spec. The inputs to compress are `const(void)[]`, so I figured I needed to cast the type inferred literal delimited string for use in compress. More things to learn. ;-) I cannot claim to be on solid ground of understanding when it comes to some areas of D syntax yet. You might be looking for `import("some_file")`. That gives you the contents of a file as a string. You can then run that string through your compression function in CTFE, put the resulting compressed data into the object file, and decompress it at runtime (like the example above does). That's the goal. It's an optional goal at this point. I'm not *really* worried about size of object code, yet, but figured this would be a neat way to shrink the compiled code generated from some large COBOL source fragments embedded in D source. COBOL programmer me might have planned to run the fragments through a compressor, then copy those outputs to the D source by hand, but that would be a maintenance headache and make for far less grokkable code. Thanks for the hints, ag0aep6g. You've given me some more paths to explore. Have good.
Re: compile time compression for associatve array literal
On Monday, 23 August 2021 at 14:04:05 UTC, Brian Tiffin wrote: That's the goal. It's an optional goal at this point. I'm not *really* worried about size of object code, yet, but figured this would be a neat way to shrink the compiled code generated from some large COBOL source fragments embedded in D source. The decompression needs to happen at runtime, where these libraries are still useful. The compression could happen through CTFE once some suitable compression code is written in D, but that's not actually required to get the results of 1. your object file contains compressed strings 2. your program decompresses them at runtime You can still achieve this end by having your build system compress external files that D then includes. Manually setting this up: ``` $ dd if=/dev/zero bs=$((1024*1024)) count=1024 of=gigabyte.data 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.3655 s, 786 MB/s $ time zip giga.zip gigabyte.data adding: gigabyte.data (deflated 100%) real0m5.645s user0m5.470s sys 0m0.160s $ du -sh giga.zip 1020K giga.zip $ dmd -J. -O zeroes.d $ du -sh zeroes 3.3Mzeroes $ time ./zeroes > out.data real0m3.310s user0m1.486s sys 0m1.167s $ diff -s gigabyte.data out.data Files gigabyte.data and out.data are identical ``` From this zeroes.d: ```d import std.stdio : write; import std.zip; enum zeroes = import("giga.zip"); void main() { auto zip = new ZipArchive(cast(char[]) zeroes); ArchiveMember am = zip.directory.values[0]; zip.expand(am); write(cast(char[]) am.expandedData); } ```
Re: Vibe.d error
On Friday, 20 August 2021 at 17:39:29 UTC, JG wrote: On Friday, 20 August 2021 at 10:50:12 UTC, WebFreak001 wrote: On Wednesday, 18 August 2021 at 19:51:00 UTC, JG wrote: [...] There might be incompatibilities with how openssl is used and the installed openssl version or config. If you are getting this from having https enabled on the server, I would recommend instead switching to HTTP-only and using a reverse proxy such as with nginx or caddy to serve it with HTTPS. Thank you very much for your reply. Yes, we are getting this with HTTPS enabled. May I ask why you suggest not to use HTTPS? I think you might need to restart the server whenever you update the SSL certificates + in every app you need to pass in your SSL certificate location somehow or hardcode it, which if you make all your apps yourself you can do consistently, but otherwise creates inconsistencies which can be hard to maintain. On the other hand if you use a single reverse proxy like with nginx or caddy for all the HTTPS services it can reload them all at once and use the same config for everything. Additionally the are better supported by ACME services like LetsEncrypt or ZeroSSL through built-in plugins, etc. But most importantly: these services have undergone much more testing for security than vibe.d, so you can generally expect it to be less likely to have critical bugs in API usage.
Emacs AutoComplete Tutorial Video for D Language
I made this video for people asking how to configure Dlang in Emacs environment:) : https://peertube.linuxrocks.online/w/62pWpmw2r4Se1XvmYiWm75
Re: compile time compression for associatve array literal
On Monday, 23 August 2021 at 14:49:17 UTC, jfondren wrote: On Monday, 23 August 2021 at 14:04:05 UTC, Brian Tiffin wrote: That's the goal. It's an optional goal at this point. I'm not *really* worried about size of object code, yet, but figured this would be a neat way to shrink the compiled code generated from some large COBOL source fragments embedded in D source. The decompression needs to happen at runtime, where these libraries are still useful. The compression could happen through CTFE once some suitable compression code is written in D, but that's not actually required to get the results of 1. your object file contains compressed strings 2. your program decompresses them at runtime You can still achieve this end by having your build system compress external files that D then includes. Manually setting this up: ``` $ dd if=/dev/zero bs=$((1024*1024)) count=1024 of=gigabyte.data 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.3655 s, 786 MB/s $ time zip giga.zip gigabyte.data adding: gigabyte.data (deflated 100%) real0m5.645s user0m5.470s sys 0m0.160s $ du -sh giga.zip 1020K giga.zip $ dmd -J. -O zeroes.d $ du -sh zeroes 3.3Mzeroes $ time ./zeroes > out.data real0m3.310s user0m1.486s sys 0m1.167s $ diff -s gigabyte.data out.data Files gigabyte.data and out.data are identical ``` From this zeroes.d: ```d import std.stdio : write; import std.zip; enum zeroes = import("giga.zip"); void main() { auto zip = new ZipArchive(cast(char[]) zeroes); ArchiveMember am = zip.directory.values[0]; zip.expand(am); write(cast(char[]) am.expandedData); } ``` Yep, pondered external tooling, but that's not a goal either really. Want people, well me actually, looking at the source file to be able to quickly scan over the fragments from the single D source. I'm still ok with high-school level D at this point, and will just compile in the heredoc strings, as-is. And thanks, jfondren. Making another bookmark for later visiting once further up the D curve. Cheers
Possible to overload assignment of struct field ??
Greetings, With a struct, there are many overload possibilities available. However, I haven't been able to find how to overload assignment of **selected fields** of a struct. For example, suppose: struct Foo{ int a; int b; ... } void main(){ auto x = Foo( 1, 2); // so x now instantiates x.a = 100; // suppose I wish to enforce that a<5?? ... } (I understand this is basically a field "setter" idea that is most often associated with classes. So, another way to state the quesion might be: "How can a field setter be done on a **already instantiated** struct?) Best Regards, James
Re: Possible to overload assignment of struct field ??
On 8/23/21 10:25 PM, james.p.leblanc wrote: So, you need a "property". Easy... :) 1) Rename the member e.g. as a_. 2) Write setter and getter functions named 'a'. struct Foo{ int a_; int a() const { return a_; } void a(int value) { a_ = value; } } void main(){ auto x = Foo(1); x.a = 100; assert(x.a == 100); } Ali
Re: Possible to overload assignment of struct field ??
On Tuesday, 24 August 2021 at 05:34:08 UTC, Ali Çehreli wrote: On 8/23/21 10:25 PM, james.p.leblanc wrote: So, you need a "property". Easy... :) 1) Rename the member e.g. as a_. 2) Write setter and getter functions named 'a'. struct Foo{ int a_; int a() const { return a_; } void a(int value) { a_ = value; } } void main(){ auto x = Foo(1); x.a = 100; assert(x.a == 100); } Ali Ali, Thank you ... yes! This is exactly what I needed, I have done something similar as you have shown for the "getter", but had a "brain-lock-up" when thinking about the setter. A bit embarassing for my, I admit. But, on the positive side ... the solution is now burned into my brain. Thanks again and Kind Regards, James