Re: How to assign and compare arrays to SumType?
On Tuesday, 11 June 2024 at 18:26:50 UTC, confuzzled wrote: On Tuesday, 11 June 2024 at 16:41:46 UTC, confuzzled wrote: Comparison between a Variant and an array is straightforward. How does one accomplish the same between a SumType and an array? Okay, this is what I came up with. Just a sanity check please. Did I do this correctly? Is there something I'm overlooking? It's enough to just make the whole array another `SumType!(double[])`. ```d void main() { Variant v = [1.7, 2.7, 3.7, 4.7, 5.7]; assert(v == [1.7, 2.7, 3.7, 4.7, 5.7]); S s; s.data = [1.7, 2.7, 3.7, 4.7, 5.7]; // {2} assert(s.data == SumType!(double[])([1.7, 2.7, 3.7, 4.7, 5.7])); } ``` Or better yet, to avoid redundantly spelling out the type; ```d assert(s.data == typeof(s.data)([1.7, 2.7, 3.7, 4.7, 5.7])); ```
Re: Weird std.path API?
On Sunday, 7 July 2024 at 14:41:31 UTC, Andrey Zherikov wrote: ```d import std.path; // Error: no property `asNormaliedPath` for `dirName("/sandbox/onlineapp.d")` of type `string` auto p = __FILE_FULL_PATH__.dirName.asNormaliedPath; ``` `asNormalizedPath` is misspelled.
Named template arguments
I've so far been using `std.typecons.Flag` *heavily* to work around there not being named arguments in D. As soon as I wanted to pass something a bool, I made it a `Flag` instead to make it a bit more self-documenting. (Also in general just to idiot-proof it a bit, since I don't trust myself not to confuse parameter orders, like in `doThing(false, false, true, false)`.) But now we have named arguments! And as I'm going through my code to replace all those `Yes.throwOnFailure` and `No.recursing` and the such, I quickly noticed it didn't work with template arguments. ```d void foo(bool bar)(bool baz) {} void main() { foo!(bar: true)(baz: false); } /* onlineapp.d(5): Error: found `:` when expecting `)` following template argument list onlineapp.d(5): Error: found `true` when expecting `;` following expression onlineapp.d(5):expression: `foo!(bar)` onlineapp.d(5): Error: found `)` instead of statement */ ``` Is there a reason why we can't have named template arguments too? I don't particularly mind it if we'd have to limit the ordering so that variadics have to be placed last. I just want to avoid having to resort to `Flag!"bar" bar` parameters.
Re: Named template arguments
On Thursday, 8 August 2024 at 10:51:29 UTC, IchorDev wrote: Named template parameters were mentioned in [the DIP](https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1030.md), they just haven’t been implemented yet. Thanks! Will just wait then.
Re: Install D lang on Windows 10 : an installation step by step tutorial made by a beginner who loves D !
On Monday, 18 April 2022 at 09:04:24 UTC, Dennis wrote: What went wrong when you used the DMD installer? Installing Visual Studio should not be necessary, since DMD ships with the lld linker and MinGW Windows import libraries. If it doesn't work out of the box, it should be fixed. "Download and install Visual Studio 2019" is preselected in the installer, so you have to know to pick "Install VC2010 redistributables to use it with the MinGW Platform libraries" to opt out. I guess it's not *necessary* but it certainly encourages new users to install it. (I'd subjectively argue the VC2010/MinGW option should be the default, the whole of VS2019 is a very hefty download and not my IDE of choice.)
Re: DMD failed with exit code -1073741819
On Tuesday, 3 May 2022 at 18:22:49 UTC, jmh530 wrote: I was leaning towards it being something related to running out of memory or something, but I'm using dub and I've tried turning on and off "lowmem". Note that dub cannot pass -lowmem to dmd. https://issues.dlang.org/show_bug.cgi?id=20699
Re: Exercises
On Thursday, 12 May 2022 at 13:04:51 UTC, Alain De Vos wrote: Is there a link to a webpage with some dlang exercises in order to see if i master the language, from simple to diffucult ? [Rosetta Code](https://www.rosettacode.org) has a bunch, with [many](https://www.rosettacode.org/wiki/Category:D) examples/answers in D.
Re: What are (were) the most difficult parts of D?
On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote: What are you stuck at? What was the most difficult features to understand? etc. I came from shell scripts. They grew too large and overly complex when I wanted to do non-trivial things in a neat way, so I looked to proper programming languages and arbitrarily settled on D over python and similar. So for me the norm is D, and everything else is "other languages". That said, one thing I cannot seem to firmly wrap my head around is `is` expressions. `is` does so many things. There's probably more intricate examples of how it's confusing, but I don't know it well enough to construe one: ``` alias AA = long*[string]; static if (is(AA whatEvenGoesHere : VP[K], VP, K)) { static if(is(VP : V*, V)) { assert(is(V)); } } ``` The one thing that has caused me most anguish and woe is hands-down https://issues.dlang.org/show_bug.cgi?id=18026 though. It hasn't bit me for a while now, but the feeling of uncertainty, that the compiler might just suddenly after an innocent change no longer compile your project, seemingly outside of your control, is just... disheartening when it happens.
Re: What are (were) the most difficult parts of D?
On Thursday, 12 May 2022 at 16:48:05 UTC, H. S. Teoh wrote: static foreach isn't meant to handle large loops. Writing `static foreach (i; 0 .. 6)` is generally a bad idea; my suspicion is that the compiler ran out of stack space). It's more for unfolding groups of statements or declarations like cases in a switch-statement. I understand, but I don't think I had any static foreaches in my code at the time. My case was more comment #10.
Re: What are (were) the most difficult parts of D?
On Thursday, 12 May 2022 at 15:17:10 UTC, Adam D Ruppe wrote: It is simpler than it looks, I wrote about it in my book and in a post here: https://forum.dlang.org/post/xklcgjaqggihvhctc...@forum.dlang.org "Then commas separate the definitions of each placeholder variable, just as if they were template argument definitions [...]" That... makes sense, I didn't think of them like that.
FTP LS
Before I go on duplicating effort, does anyone have anything that can access FTP beyond PUT and GET? I need to read file information from a NAS so I know if I should upload a file or not. `dlang-requests` has `Request.post` and `Request.get`, but seemingly no way to LS.
Re: FTP LS
On Sunday, 15 May 2022 at 19:13:10 UTC, ikod wrote: Added LIST command in v2.0.8 Thanks!
Closures over temporary variables
What is the correct way of making this output `0 1 2`? ```d void delegate()[] dgs; foreach (immutable i; 0..3) { dgs ~= () => writeln(i); } foreach (dg; dgs) { dg(); // outputs: `2 2 2` } ```
How to obtain Variant underlying type?
std.variant; Variant v = [[1], [2], [3]]; writeln(v.type); // int[][] typeof(v.type); // TypeInfo assert(v.type == typeid(int[][]); As demonstrated by the assert statement, .type returns the typeid of the underlying type. How would I obtain the actual type such that: auto vb = v.base; // what should I put here to achieve the following: typeof(vb); // int[][] assert(vb == [[1], [2], [3]]); --anonymouse
Re: How to obtain Variant underlying type?
On Saturday, 9 July 2022 at 14:46:36 UTC, Adam D Ruppe wrote: Impossible; Variant's type is only known at runtime, and this would require compile time knowledge. Hmmm. Okay, thanks. What I really need to know is how many dimensions an array has and the total elements per dimension so that I can create temporary storage for it later. this(T)(T a) in(imported!"std.traits".isDynamic!T) { data = a; // data is of type Variant shape = [a.length, {?, ...}]; // what's the best way to deterine? } Thanks, --anonymouse
Re: How to obtain Variant underlying type?
On Sunday, 10 July 2022 at 06:26:37 UTC, jfondren wrote: ```d import std.variant : Variant; size_t[] shape(Variant v) { import std.variant : VariantException; size_t[] s; try { while (true) { Variant elem = v[0]; s ~= v.length; v = elem; } } catch (VariantException e) { return s; } } ``` Thank you very much.
Re: How to obtain Variant underlying type?
On Sunday, 10 July 2022 at 18:31:46 UTC, drug007 wrote: I'd like to say that using of exception to break loop is really bad. Exception is exceptional thing but in the case above the exception is ordinary completion of the loop happens on regular basis. Don't do that. Thanks for the advice. Lesson learned. --anonymouse
Re: How to obtain Variant underlying type?
On Sunday, 10 July 2022 at 19:14:34 UTC, Paul Backus wrote: For reference, this is the more correct way: ```d while (cast(TypeInfo_Array) v.type !is null) { Variant elem = v[0]; // etc. } ``` Hard to blame anyone for not coming up with that on their first try, especially since `TypeInfo_Array` is not even documented--you have to read the source of `object.d` to find out about it. I honestly cannot say why but I was having a problem using this earlier. After several hours of frustration, I rebooted the computer, went for a run, came back, and tried again. It works!!! Thank you very much. --anonymouse
Re: How to obtain Variant underlying type?
On Monday, 11 July 2022 at 05:41:40 UTC, jfondren wrote: Oh, sorry. I didn't defend the code in any way because I assumed that the exceptional design would be seen as obviously bad (and that someone else would dig harder in order to find a better solution). And you were right. I did search for a better solution and came across [1]. Although I was having some issues adapting it for my use case, Paul Backus' follow-up clarified the issue. This is what my naive brain led to before reading this response. ```d size_t[] shape(Variant v) { typeof(return) dims; while(cast(TypeInfo_Array) v.type !is null) { dims ~= v.length; v = v[0]; } if(!dims.length && v.length) { dims ~= v.length; dims ~= 0; } return dims; } ``` Didn't see the bugs that would occur when a scalar or empty array was passed because I hadn't tested for them. if (!v.length) break; Pure gold! Bugs are eliminated, and the code is shorter. Thank you. --anonymouse [1] https://tastyminerals.github.io/tasty-blog/dlang/2020/03/22/multidimensional_arrays_in_d.html
Re: How to dynamically calculate an index?
On Tuesday, 12 July 2022 at 14:17:36 UTC, ananymouse wrote: Been racking my brain on this for hours. Please point me in the right direction. Thanks, --anonymouse My current implementation: ``` d // Allow for indexing to read a value, e.g a[0,0,0] T opIndex(A...)(A a) { static if(a.length == 3) { int index = a[0] * dims[1] * dims[2] + a[2]; return data[index]; } else static if(a.length == 2) { return data[a[0] * dims[1] + a[1]; } else static if (a.length == 1) { return data[0] } assert(0); } ``` This does not scale well. Therefore, I'd like to change the first if statement to work with any array.length > 2 and dynamically generate the code. I've tried using a foreach loop to achieve this but failed miserably. --anonymouse
Re: How to dynamically calculate an index?
On Tuesday, 12 July 2022 at 14:55:47 UTC, anonymouse wrote: I've tried using a foreach loop to achieve this but failed miserably. --anonymouse Wait, I think I've got it. This little snippet does the trick: int index; foreach(i, v; a) { int t = v; foreach(d; dims[i+1 .. a.length]) tmp *= d; index += tmp; } Thanks, everyone. --anonymouse
Working with arrays (flatten, transpose, verfify rectangular)
Given an array of arbitrary dimensions, I would like to accomplish three things: 1) verify that it is rectangular (e.g. all elements have the same length, all sub-elements have the same length, etc.) 2) flatten and return the flattened copy 3) transpose and return the transposed copy Here is my naive attempt to accomplish the first task: d auto isRectangular(A)(A a) if (isArray!A) { bool result; size_t length = a[0].length; foreach (e; a) { result = e.length == length; } return result; } This only works if a is a 2D array, how do I extend this to support arrays with larger dimensions (3D, 4D, 5D, etc.)? For task 3, I can visit each element of the array, but I have no idea how to compose the flattened (1D) version: d import std.range.primitives: ElementType; auto flatten(A)(A a) if (isArray!A) { //ElementType!(A)[] result; //[1] foreach (i; a) { static if (isArray!(typeof(i))) flatten(i); else { writeln(i); // result ~= i; //[2] } } //return result; // [3] } The thought I had was to get the BaseType of the array (int, double, etc.) and use it to create a dynamic array [1]. I could then concatenate each element [2], and return the result once completed [3]. This approach has two major problems and probably many other's I'm not yet experienced enough to see. The first is that there's no way to get the BaseType of an array. ElementType in the example assumes that array is 2D, therefore anything else passed in will result in a multi-dimensional array being created to which individual elements cannot be concatenated. The second issue is that each call to flatten will have it's own result which will be discarded when the function exits, so the final result will be an empty array. As for task 3, while I understand the concept of transposing a matrix, I'm not sure how to even begin. These tasks are all self assigned and not associated with any high school or college course. Just trying get a better understanding of how arrays and matrices/tensors work while reading up on linear algebra. This is purely self study and I would really appreciate some assistance. Thanks, ---anonymouse
Re: Working with arrays (flatten, transpose, verfify rectangular)
On Wednesday, 20 July 2022 at 20:47:28 UTC, ag0aep6g wrote: (Aside: You don't need that many backticks to mark code fragments.) Thought I was following the instructions but it looks like I got a bit carried away. lol. You've got a bug there. This should pass, but fails with your version: assert(!isRectangular([[1, 2], [], [3, 4]])); Once `result` becomes false, you cannot let it switch to true again. Yeah, I noticed that. I actually fixed it at one point but since I was having problems scaling whole thing beyond 2D, I thought I got it wrong. As for generalizing the function, instead of comparing the lengths of the elements, you want to compare their "shapes". The shape of a `Foo[] a1;` is `[a1.length]`. The shape of a rectangular `Foo[][] a2;` is `[a2.length, a2[0].length]`. And so on. [...] Thank you so much. That was super helpful. I'm sure the function can be improved further, but I'm not going to get into that. For task 3, I can visit each element of the array, but I have no idea how to compose the flattened (1D) version: You've got the right idea there with `flatten` calling itself on each element. You only need to apply that idea when getting the element type, too (and actually append the result of the recursive call to `result`): import std.range.primitives: ElementType; template FlatElementType(A) if (isArray!A) { alias E = ElementType!A; static if (isArray!E) { alias FlatElementType = FlatElementType!E; } else { alias FlatElementType = E; } } This is pure gold. Thank you. result ~= flatten(i); Wow. That simple. I actually printed out the contents of result and saw the entire thing got was flattened during the recursion, but for the life of me I couldn't figure out why the final output always be empty. [...] As for task 3, while I understand the concept of transposing a matrix, I'm not sure how to even begin. I'm gonna leave that one for someone else. Thanks again. I really appreciate the assistance. --anonymouse
Re: Working with arrays (flatten, transpose, verfify rectangular)
On Wednesday, 20 July 2022 at 16:15:33 UTC, Salih Dincer wrote: On Wednesday, 20 July 2022 at 09:18:29 UTC, anonymouse wrote: Given an array of arbitrary dimensions, I would like to accomplish three things: 1) verify that it is rectangular (e.g. all elements have the same length, all sub-elements have the same length, etc.) 2) flatten and return the flattened copy 3) transpose and return the transposed copy Yesterday, I published an example of a lesson we developed with Ali. It's same `transpose()` when I add extra `swap()` for you. I hope it works for you. Hello Salih, thanks for responding. I'm not seeing the transpose function here. What I meant by transpose is, given the following: ```d auto array = [ [111, 112, 113, 114], [121, 122, 123, 124], [131, 132, 133, 134], [141, 142, 143, 144] ] ``` after applying transpose(), you'd get back the following in return: [ [111, 121, 131, 141], [112, 122, 132, 142], [113, 123, 133, 143], [114, 124, 134, 144] ] This should scale to arrays of all dimensions, so the row vector (1D array): [100, 200, 300, 4000] would transpose to: [[100], [200], [300], [400]] In general, the transpose of any array yields an array with its shape reversed. For example, the following array of shape [2, 4, 5]: ```d auto array = [[ [111, 112, 113, 114, 115], [121, 122, 123, 124, 125], [131, 132, 133, 134, 135], [141, 142, 143, 144, 145] ], [ [211, 212, 213, 214, 125], [221, 222, 223, 224, 225], [231, 232, 233, 234, 235], [241, 242, 243, 244, 245] ]] ``` would become this array of shape [5, 4, 2] after transpose, with its columns becoming its rows and its rows becoming its columns: ```d [[[111, 211], [121, 221], [131, 231], [141, 241]], [[112, 212], [122, 222], [132, 232], [142, 242]], [[113, 213], [123, 223], [133, 233], [143, 243]], [[114, 214], [124, 224], [134, 234], [144, 244]], [[115, 215], [125, 225], [135, 235], [145, 245]]] ``` Thanks, --anonymouse
Re: Working with arrays (flatten, transpose, verfify rectangular)
On Wednesday, 20 July 2022 at 09:18:29 UTC, anonymouse wrote: As for task 3, while I understand the concept of transposing a matrix, I'm not sure how to even begin. By not knowing how to begin, I mean that I don't know how to generalize the algorithm so that it applies to an array of arbitrary dimension/shape. If I already know the dimensions, I can hardcode that information and get it to work just fine. In the example below, since I know that ```a``` has a shape of [3, 5, 7], I use that information to transpose the array: ```d import std.traits; auto transpose(A)(A a) if (isArray!A) { auto tmp = new FlatElementType!A[3][5][7]; // [1] foreach(n0, i; a) foreach(n1, j; i) foreach(n2, k; j) tmp[n2][n1][n0] = k; return tmp; } void main() { auto a = [ [ [111,112,113,114,115,116,117], [121,122,123,124,125,126,127], [131,132,133,134,135,136,137], [141,142,143,144,145,136,147], [151,152,153,154,155,156,137] ], [ [211,212,213,214,215,216,217], [221,222,223,224,225,226,227], [231,232,233,234,235,236,237], [241,242,243,244,245,236,247], [251,252,253,254,255,256,237] ], [ [311,312,313,314,315,316,317], [321,322,323,324,325,326,327], [331,332,333,334,335,336,337], [341,342,343,344,345,336,347], [351,352,353,354,355,356,337] ] ]; a.transpose.writeln; } ``` Output reformatted for visual presentation: ``` [ [ [111, 211, 311], [121, 221, 321], [131, 231, 331], [141, 241, 341], [151, 251, 351] ], [ [112, 212, 312], [122, 222, 322], [132, 232, 332], [142, 242, 342], [152, 252, 352] ], [ [113, 213, 313], [123, 223, 323], [133, 233, 333], [143, 243, 343], [153, 253, 353] ], [ [114, 214, 314], [124, 224, 324], [134, 234, 334], [144, 244, 344], [154, 254, 354] ], [ [115, 215, 315], [125, 225, 325], [135, 235, 335], [145, 245, 345], [155, 255, 355] ], [ [116, 216, 316], [126, 226, 326], [136, 236, 336], [136, 236, 336], [156, 256, 356] ], [ [117, 217, 317], [127, 227, 327], [137, 237, 337], [147, 247, 347], [137, 237, 337] ] ] ``` As the example demonstrates, by knowing beforehand that it is a 3D array of shape [3, 5, 7] , I can hardcode that information into the temp array and use the correct amount of nested loops to unwind and reassigned the values. I would like to accomplish this without knowing the shape before hand. Any pointers would be appreciated. Thanks, --anonymouse [1] Contributed by [ag0aep6g](https://forum.dlang.org/post/tb9pl1$gc1$1...@digitalmars.com)
Re: Working with arrays (flatten, transpose, verfify rectangular)
On Friday, 22 July 2022 at 05:17:49 UTC, anonymouse wrote: On Wednesday, 20 July 2022 at 09:18:29 UTC, anonymouse wrote: As for task 3, while I understand the concept of transposing a matrix, I'm not sure how to even begin. By not knowing how to begin, I mean that I don't know how to generalize the algorithm so that it applies to an array of arbitrary dimension/shape. If figure if I could do something like this, it would work: ```d static string s; s ~= FlatElementType!T.stringof; static foreach (i; a) s ~= "[" ~ to!string(i) ~ "]"; mixin(s) var; ``` Here, I'm receiving the shape of the array (```a```), composing a string of the actual type, then mixing it in to declare a variable of that type. Of course the compiler barfs at the idea as coded, but is there a way to accomplish this? Note that if you comment out the foreach loop, the variable gets created. Thanks, --anonymouse
Request assistance resolving linker error: Undefined symbol(s) for architecture x86_64
How do I go about tracking down what's causing the following error: ``` Undefined symbols for architecture x86_64: "__D3std8internal6memory12__ModuleInfoZ", referenced from: __D3loxQe12__ModuleInfoZ in dlux.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) ``` I'm not explicitly calling anything in std.internal.memory so not sure how to resolve. Thanks. --anonymouse
Re: Request assistance resolving linker error: Undefined symbol(s) for architecture x86_64
On Wednesday, 3 August 2022 at 05:04:08 UTC, H. S. Teoh wrote: On Wed, Aug 03, 2022 at 04:28:57AM +, anonymouse via Digitalmars-d-learn wrote: How do I go about tracking down what's causing the following error: ``` Undefined symbols for architecture x86_64: "__D3std8internal6memory12__ModuleInfoZ", referenced from: __D3loxQe12__ModuleInfoZ in dlux.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) ``` I'm not explicitly calling anything in std.internal.memory so not sure how to resolve. Thanks. [...] This is often a sign of version mismatch between libraries and compiler. Did you recently upgrade your compiler? Did you accidentally install two versions of the standard library and the new compiler is mistakenly picking up the old library? Interesting... no I only have one version of DMD installed on this computer (v2.100.0) and it's never been updated. Maybe try also recompiling your project from clean slate just in case your build process is picking up stale binaries for whatever reason. If you have object files compiled with the old version of the compiler still lying around, and they get picked up when compiling with the new compiler, it would cause link errors like the above. This project aims at learning how compilers work. I'm simply adapting Robert Nystrom's code from his book [Crafting Compiler](http://www.craftinginterpreters.com/scanning.html). The source tree currently looks like this: ``` lox | + lox.d | + main.d | + scanner.d | + token.d | + tokentype.d ``` My entire build process comprises issuing the command: ``` dmd -of=dlux lox/* ``` I've tried using -J, -I, and moving main to the current working directory but all these result in the same error. --anonymouse
Re: Request assistance resolving linker error: Undefined symbol(s) for architecture x86_64
On Wednesday, 3 August 2022 at 09:39:36 UTC, ryuukk_ wrote: Does adding ```-m64``` work I'm using macOS so I don't think that applies. But no, it doesn't do anything for me. Thanks, --anonymouse
Comparing slices with std.variant.Algebraic
Observe the [implementation](https://github.com/Kriyszig/magpie/blob/master/source/magpie/axis.d) of ```d stuct Axis(U...){} ``` More specifically, observe its usage in the unittests for [Binary Ops on Variant Axis](https://github.com/Kriyszig/magpie/blob/master/source/magpie/axis.d#L410-L437) and [Binary Ops on Variant + Other DataType](https://github.com/Kriyszig/magpie/blob/master/source/magpie/axis.d#L440-L467) Note that both tests fail due to asserts on lines 422 and 452. Note also that commenting out these two lines results in successful compilation of all other tests. Inspecting c.data, one will find that it holds the array [1.7, 3.7, 5.7, 7.7, 9.7] in both cases, which is what is being asserted by those two lines. So the question is, what is the proper way to compare a slice (array literal?) and an Algebraic in current D? I assume that this code worked back in 2019, however, I am unable to detect when it stopped working because no DMD compiler prior to v2.100.0 works properly on my system. On a related note, std.variant.Algebraic has been deprecated and the suggested replacement is std.sumtype.SumType. What is the proper way to make this conversion? Attempting to do a drop-in replacement results in the following errors: ``` axis.d(400): Error: incompatible types for array comparison: `SumType!(bool, int, long, float, double, string, DateTime)[]` and `double[]` axis.d(86): Error: incompatible types for `(this.data[i]) + (rhs.data[i])`: both operands are of type `SumType!(bool, int, long, float, double, string, DateTime)` axis.d(414): Error: template instance `axis.Axis!void.Axis.opBinary!("+", void)` error instantiating axis.d(86): Error: incompatible types for `(this.data[i]) + (rhs.data[i])`: `SumType!(bool, int, long, float, double, string, DateTime)` and `int` axis.d(445): Error: template instance `axis.Axis!void.Axis.opBinary!("+", int[])` error instantiating axis.d(43): Error: none of the overloads of template `object.get` are callable using argument types `!(int)(const(SumType!(bool, int, long, float, double, string, DateTime)))` /Users/anonymouse/dlang/dmd-2.100.0/osx/bin/../../src/druntime/import/object.d(3409): Candidates are: `get(K, V)(inout(V[K]) aa, K key, lazy inout(V) defaultValue)` /Users/anonymouse/dlang/dmd-2.100.0/osx/bin/../../src/druntime/import/object.d(3416): `get(K, V)(inout(V[K])* aa, K key, lazy inout(V) defaultValue)` axis.d(47): Error: none of the overloads of template `object.get` are callable using argument types `!(double)(const(SumType!(bool, int, long, float, double, string, DateTime)))` /Users/anonymouse/dlang/dmd-2.100.0/osx/bin/../../src/druntime/import/object.d(3409): Candidates are: `get(K, V)(inout(V[K]) aa, K key, lazy inout(V) defaultValue)` /Users/anonymouse/dlang/dmd-2.100.0/osx/bin/../../src/druntime/import/object.d(3416): `get(K, V)(inout(V[K])* aa, K key, lazy inout(V) defaultValue)` axis.d(474): Error: template instance `axis.Axis!void.Axis.convertTo!(int[])` error instantiating axis.d(43): Error: none of the overloads of template `object.get` are callable using argument types `!(double)(const(SumType!(bool, int, long, float, double, string, DateTime)))` /Users/anonymouse/dlang/dmd-2.100.0/osx/bin/../../src/druntime/import/object.d(3409): Candidates are: `get(K, V)(inout(V[K]) aa, K key, lazy inout(V) defaultValue)` /Users/anonymouse/dlang/dmd-2.100.0/osx/bin/../../src/druntime/import/object.d(3416): `get(K, V)(inout(V[K])* aa, K key, lazy inout(V) defaultValue)` axis.d(47): Error: none of the overloads of template `object.get` are callable using argument types `!(double)(const(SumType!(bool, int, long, float, double, string, DateTime)))` /Users/anonymouse/dlang/dmd-2.100.0/osx/bin/../../src/druntime/import/object.d(3409): Candidates are: `get(K, V)(inout(V[K]) aa, K key, lazy inout(V) defaultValue)` /Users/anonymouse/dlang/dmd-2.100.0/osx/bin/../../src/druntime/import/object.d(3416): `get(K, V)(inout(V[K])* aa, K key, lazy inout(V) defaultValue)` axis.d(478): Error: template instance `axis.Axis!void.Axis.convertTo!(double[])` error instantiating ``` Thanks, --anonymouse
Re: Comparing slices with std.variant.Algebraic
On Monday, 5 September 2022 at 10:30:32 UTC, Ali Çehreli wrote: On 9/5/22 01:58, anonymouse wrote: > array [1.7, 3.7, 5.7, 7.7, 9.7] in both cases, which is what is being > asserted by those two lines. None of those values can be represented precisely in a floating point type. Without looking at the code, I wonder whether the tests will pass if you can manage to use the following values instead, which can be represented precisely: [1.5, 3.5, 5.5, 7.5, 9.5] Ali It will not. --anonymouse
Re: Comparing slices with std.variant.Algebraic
Thanks Paul. Gotta wrap my head around this well enough to update that module. However, this is a great start. Thank you very much. --anonymouse
Explicit cast to @system?
I have some nested templated code that takes function pointers. In many cases I pass it functions of identical signatures, except some are `@safe` and others are `@system`. In those cases the templates end up getting instantiated twice. I don't care about the `@safe`-ness and I'd really like to just have them all treated as `@system`, with one instantiation per unique signature. To illustrate: ``` void foo(F)(F fun) { pragma(msg, F.stringof); } void bar() @safe {} void baz() @system {} void main() { foo(&bar); foo(&baz); } ``` Outputs: ``` void function() @safe void function() ``` I *can* do this by explicitly passing the type as a template parameter; ``` void main() { foo!(void function() @system)(&bar); foo(&baz); } ``` ...but there are a lot of different signatures and I need a general approach. There doesn't seem to be such a thing as `cast(@system)fp`. My current solution involves some very gnarly string mixins. ``` static if (F.stringof.indexOf("@safe") != -1) { mixin("alias SystemF = " ~ F.stringof.replace("@safe", "@system") ~ ";"); } else { alias SystemF = F; } ``` ...where `F` is `void function()`, `@safe` or `@system`. Then I can explicitly pass `SystemF` as a compile-time parameter, and I get my decreased instantiations. But surely there has to be a better way?
Re: Explicit cast to @system?
On Sunday, 9 October 2022 at 16:25:22 UTC, tsbockman wrote: You might be templating more information than necessary. In your example `foo` doesn't need to be a template at all: ```D void foo(void function() @system fun) { pragma(msg, typeof(fun).stringof); } ``` Yes, it was a toy example. It's complicated and I need crayons to explain it well, but the real code is a nested function in a main function in a template mixin, mixed into a class in a module dedicated to it. When invoked the main function introspects module-level functions annotated with particular UDAs and calls them -- or doesn't, depending on other factors. Several modules (grep says 23) then each have their own class types that mix in this mixin, and each module's module-level functions take that module's class as parameter. Like the hello world example does [here](https://github.com/zorael/kameloso/blob/a471a33/source/kameloso/plugins/hello.d#L17-L25). So the `__FUNCTION__` string of one instance of the nested function could be (and note the `@safe`): ``` kameloso.plugins.notes.NotesPlugin.IRCPluginImpl!(Flag.no, "kameloso.plugins.notes").onEventImpl.process!(false, false, void function(NotesPlugin, ref const(IRCEvent)) @safe).process ``` Even if I somehow manage to change the nested `process` to not be a template I still need to instantiate the housing `IRCPluginImpl` mixin once per class (and module), so I'm not sure. I could just annotate everything `@system` too.
Re: Explicit cast to @system?
On Sunday, 9 October 2022 at 17:42:57 UTC, user1234 wrote: But surely there has to be a better way? No. Darn. Okay, thanks.
Static executable (ldc, linux)
I'm having problems compiling my thing into an executable that doesn't require ldc's phobos/druntime .so's. I want to distribute it in a form where it's okay if `/usr/lib/libphobos2-ldc-shared.so.100` and friends don't exist. `--static` seems to do the trick in that the compiled file is no longer a dynamic executable, but then it doesn't work and just segfaults upon trying to use OpenSSL (via `arsd.http2`). The only other flag I specifically pass to ldc is `-linkonce-templates`. ``` Linking... /usr/bin/ld: ../../.dub/packages/arsd-official-10.9.2/arsd-official/.dub/build/with_openssl-debug-linux.posix-x86_64-ldc_v1.30.0-328F22C7CA122C28C3639482CB724003/libarsd-official_http.a(arsd.http2.o): in function `_D4arsd5http211loadOpenSslFZv': /home/wob/src/kameloso/../../.dub/packages/arsd-official-10.9.2/arsd-official/http2.d:3679: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/bin/ld: /usr/lib/libphobos2-ldc.a(path.o): in function `_D3std4path11expandTildeFNbNfAyaZ18expandFromDatabaseFNbNfQBdZQBh': path.d:(.text._D3std4path11expandTildeFNbNfAyaZ18expandFromDatabaseFNbNfQBdZQBh+0x147): warning: Using 'getpwnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/bin/ld: /usr/lib/libphobos2-ldc.a(socket.o): in function `_D3std6socket25_sharedStaticCtor_L282_C1FZv': socket.d:(.text._D3std6socket25_sharedStaticCtor_L282_C1FZv+0x14): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/bin/ld: /usr/lib/libphobos2-ldc.a(socket.o): in function `_D3std6socket12InternetHost__T7getHostVAyaa118_0a2020202020202020202020206175746f2078203d2068746f6e6c28706172616d293b0a2020202020202020202020206175746f206865203d20676574686f73746279616464722826782c20342c206361737428696e7429204164647265737346616d696c792e494e4554293b0a2020202020202020TkZQJwMFkZb': socket.d:(.text._D3std6socket12InternetHost__T7getHostVAyaa118_0a2020202020202020202020206175746f2078203d2068746f6e6c28706172616d293b0a2020202020202020202020206175746f206865203d20676574686f73746279616464722826782c20342c206361737428696e7429204164647265737346616d696c792e494e4554293b0a2020202020202020TkZQJwMFkZb+0x37): warning: Using 'gethostbyaddr' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/bin/ld: /usr/lib/libphobos2-ldc.a(socket.o): in function `_D3std6socket12InternetHost__T7getHostVAyaa75_0a202020202020202020202020202020206175746f206865203d20676574686f737462796e616d6528706172616d2e74656d7043537472696e672829293b0a202020202020202020202020TAxaZQGpMFQjZb': socket.d:(.text._D3std6socket12InternetHost__T7getHostVAyaa75_0a202020202020202020202020202020206175746f206865203d20676574686f737462796e616d6528706172616d2e74656d7043537472696e672829293b0a202020202020202020202020TAxaZQGpMFQjZb+0x43): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/bin/ld: /usr/lib/libphobos2-ldc.a(socket.o): in function `_D3std6socket8Protocol17getProtocolByTypeMFNbNeEQBuQBt12ProtocolTypeZb': socket.d:(.text._D3std6socket8Protocol17getProtocolByTypeMFNbNeEQBuQBt12ProtocolTypeZb+0xa): warning: Using 'getprotobynumber' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/bin/ld: /usr/lib/libphobos2-ldc.a(socket.o): in function `_D3std6socket8Protocol17getProtocolByNameMFNbNeMAxaZb': socket.d:(.text._D3std6socket8Protocol17getProtocolByNameMFNbNeMAxaZb+0x26): warning: Using 'getprotobyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/bin/ld: /usr/lib/libphobos2-ldc.a(socket.o): in function `_D3std6socket7Service16getServiceByNameMFNbNeMAxaMQeZb': socket.d:(.text._D3std6socket7Service16getServiceByNameMFNbNeMAxaMQeZb+0x57): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/bin/ld: /usr/lib/libphobos2-ldc.a(socket.o): in function `_D3std6socket7Service16getServiceByPortMFNbNetMAxaZb': socket.d:(.text._D3std6socket7Service16getServiceByPortMFNbNetMAxaZb+0x30): warning: Using 'getservbyport' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking ``` ``` Thread 10 "twitchworker" received signal SIGSEGV, Segmentation fault. [Switching to LWP 965536] 0x77bd7ec0 in CONF_parse_list () from /opt/dell/dcc/libcrypto.so.3 (gdb) bt #0 0x77bd7ec0 in CONF_parse_list () from /opt/dell/dcc/libcrypto.so.3 #1 0x77f3f152 in SSL_CTX_set_ciphersuites () from /opt/dell/dcc/libssl.so.3 #2 0x77f4c9df in SSL_CTX_new_ex () from /op
Re: Static executable (ldc, linux)
On Tuesday, 25 October 2022 at 10:55:33 UTC, Kagamin wrote: ldc2 -link-defaultlib-shared=false or something like that Thanks.
Re: dub ldc2 static linking
On Thursday, 27 October 2022 at 08:08:38 UTC, Yura wrote: What am I doing wrong? Any way to fix it? https://forum.dlang.org/thread/gghcyaapjwfcpnvks...@forum.dlang.org worked for me.
Makefiles and dub
[#20699](https://issues.dlang.org/show_bug.cgi?id=20699) must be non-trivial to fix, so I'm exploring makefiles. If possible I'd like to keep dub for dependency management though, just not for actual compilation. Is it at all possible (or even desireable) to construct a makefile that builds dependencies from outside of the source tree (namely `$HOME/.dub/packages/package_with_unknown_version-1.2.[0-9]+/`)? Does anyone have an example `Makefile` I could dissect? Thanks.
/usr/bin/ld: [...] undefined reference to _D3std6format6internal6write...
I'm trying to build my thing with gdc. It (now) compiles, but fails to link on this Manjaro/Arch laptop with gdc 12.2.0. ``` /usr/bin/ld: /tmp/ccstWTAS.o: in function `_D3std6format8internal5write__T8getWidthTAyaZQoFNaNfQlZl': /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include/d/std/format/internal/write.d:3819: undefined reference to `_D3std9algorithm9searching__T3allSQBg6format8internal5write__T8getWidthTAyaZQoFQhZ9__lambda2Z__TQCpTQBcZQCxMFNaNfQBpZb' /usr/bin/ld: /tmp/ccstWTAS.o: in function `_D3std6format8internal5write__T8getWidthTAaZQnFNaNfQkZl': /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include/d/std/format/internal/write.d:3819: undefined reference to `_D3std9algorithm9searching__T3allSQBg6format8internal5write__T8getWidthTAaZQnFQgZ9__lambda2Z__TQCoTQBbZQCwMFNaNfQBoZb' [...] ``` A few lines like those covering half a screen, all of it of phobos. What conventional wisdom I've picked up somewhere along the way says to use `-allinst` in cases like these, and after asking around on the Discord and finding out about gdc's equivalent `-fall-instantiations`, it now links on a different Ubuntu machine with gdc 12.1.0. No luck still with the laptop and its 12.2.0, although the linker outputs fewer errors now. What does `-allinst` even do and why does it seem to be insufficient here?
Re: /usr/bin/ld: [...] undefined reference to _D3std6format6internal6write...
On Tuesday, 20 December 2022 at 20:55:08 UTC, Paul Backus wrote: Apologies for the late reply. On Tuesday, 20 December 2022 at 20:01:04 UTC, Anonymouse wrote: What does `-allinst` even do `-allinst` tells the compiler to generate code for all instantiated templates, even if it thinks that code has already been generated in a different object file. [...] I see. That makes sense. When things fail (requiring `-allinst`), is that a bug I should report or a fact of life to lament? and why does it seem to be insufficient here? Hard to say without more information. Are you compiling with `-preview=dip1000`? If not, does adding that flag fix the error? I'm not compiling with `dip1000`. Adding it just adds some extra lines to the top of the linker errors. Full demangled non-`dip1000` error, slightly formatted for readability; ``` /usr/bin/ld: ../../.dub/packages/requests-2.0.9/requests/.dub/build/[...]/librequests.a: in function `pure @safe void std.format.internal.write.formatValueImpl!(void delegate(scope const(char)[]) pure nothrow @safe, ulong, char).formatValueImpl(ref void delegate(scope const(char)[]) pure nothrow @safe, const(ulong), scope ref const(std.format.spec.FormatSpec!(char).FormatSpec))': /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include/d/std/format/internal/write.d:171: undefined reference to `pure nothrow @nogc @trusted const(char)[] std.format.internal.write.formatValueImpl!(void delegate(scope const(char)[]) pure nothrow @safe, ulong, char).formatValueImpl(ref void delegate(scope const(char)[]) pure nothrow @safe, const(ulong), scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)).__lambda5!(ulong).__lambda5(ref ulong)' /usr/bin/ld: ../../.dub/packages/requests-2.0.9/requests/.dub/build/[...]/librequests.a: in function `pure @safe immutable(char)[] std.algorithm.searching.find!(std.algorithm.mutation.stripLeft!(immutable(char)[], char).stripLeft(immutable(char)[], char).__lambda3, immutable(char)[]).find(immutable(char)[])': /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include/d/std/algorithm/searching.d:1858: undefined reference to `pure nothrow @nogc @safe bool std.algorithm.mutation.stripLeft!(immutable(char)[], char).stripLeft(immutable(char)[], char).__lambda3!(dchar).__lambda3(dchar)' collect2: error: ld returned 1 exit status Error gdc failed with exit code 1. ``` In this case it's even in an external dependency (`requests`), which compiles by itself but not when dub builds my thing with it. I'm not sure what to do.
hasUDA alternatives?
I use `hasUDA`, `getUDAs` and `getSymbolsByUDA` fairly heavily in my project. dmd requires some 3.2Gb to compile it, a dub recompilation taking somewhere around 8-14 seconds, depending on the phase of the moon. It's not too bad, admittedly. Stuff like this, naturally taken out of all context: ``` static if (isSerialisable!member) { import std.path : buildNormalizedPath; static if (hasUDA!(this.tupleof[i], Resource)) { member = buildNormalizedPath(state.settings.resourceDirectory, member); } else static if (hasUDA!(this.tupleof[i], Configuration)) { member = buildNormalizedPath(state.settings.configDirectory, member); } } ``` ``` private alias allEventHandlerFunctionsInModule = Filter!(isSomeFunction, getSymbolsByUDA!(thisModule, IRCEventHandler)); ``` ``` enum isSetupFun(alias T) = (getUDAs!(T, IRCEventHandler)[0]._when == Timing.setup); enum isEarlyFun(alias T) = (getUDAs!(T, IRCEventHandler)[0]._when == Timing.early); enum isLateFun(alias T) = (getUDAs!(T, IRCEventHandler)[0]._when == Timing.late); enum isCleanupFun(alias T) = (getUDAs!(T, IRCEventHandler)[0]._when == Timing.cleanup); alias hasSpecialTiming = templateOr!(isSetupFun, isEarlyFun, isLateFun, isCleanupFun); alias isNormalEventHandler = templateNot!hasSpecialTiming; alias setupFuns = Filter!(isSetupFun, this.allEventHandlerFunctionsInModule); alias earlyFuns = Filter!(isEarlyFun, this.allEventHandlerFunctionsInModule); alias lateFuns = Filter!(isLateFun, this.allEventHandlerFunctionsInModule); alias cleanupFuns = Filter!(isCleanupFun, this.allEventHandlerFunctionsInModule); alias pluginFuns = Filter!(isNormalEventHandler, this.allEventHandlerFunctionsInModule); ``` If `hasUDA` and friends are so bad[1] [2] [3], what can I use instead? I need them to work at compile-time. `hasUDA` just needs to evaluate to true or false, but for `getUDAs` and `getSymbolsByUDA` I need them to resolve to symbols (and not string names of symbols). Do I have any alternatives? [1]: https://forum.dlang.org/post/bwekufskjmknllapz...@forum.dlang.org [2]: https://forum.dlang.org/post/tm02a6$nk3$1...@digitalmars.com [3]: https://forum.dlang.org/post/nzlnwbcezwyopjfia...@forum.dlang.org
Re: hasUDA alternatives?
On Saturday, 28 January 2023 at 17:16:07 UTC, Hipreme wrote: [...] Thank you. I incorporated some of these ideas and looked up how to profile the compilation with tracy, and now dmd memory requirements are down to ~2100 Mb. It's still a far cry from your 250 Mb, however. I changed it to only call `getSymbolsByUDA` once (per plugin module) and then filtered it by use of arrays of indices, like you suggested. This reduced memory needed by some 150 Mb; less than I had hoped but still a step in the right direction. I then went through the compilation with tracy and removed, replaced or versioned out parts that the compiler seemed to spend a long time on in semantic analysis. I lost some functionality but the returns were considerable. The remaining big offender seems to be `std.concurrency.send`. I consolidated some unique instantiations, but it's pretty core to how the thing works and I'm not sure what I can neatly do about that.
Re: Comparison of multidimensional associative arrays
On Wednesday, 8 February 2023 at 17:55:03 UTC, Alexander Zhirov wrote: Not an easy task for me, maybe you can advise your compact solution. There are two associative arrays of type `string[string][int]`. It is necessary to find the differences and return them when comparing: Can you explain how you determine how/if two entries are different?
Re: Comparison of multidimensional associative arrays
On Wednesday, 8 February 2023 at 19:04:15 UTC, Alexander Zhirov wrote: [...] I would write a data structure and use struct members to reason about things, but that's probably just preference. ``` import std; struct DatabaseEntry { int id = -1; string deleted; string name; this(string[string] aa) { this.id = aa["id"].to!int; this.deleted = aa["deleted"]; this.name = aa["name"]; } auto opEquals(typeof(this) that) const { return (this.id == that.id) && (this.deleted == that.deleted) && (this.name == that.name); } } auto buildSortedEntryRange(string[string][int] aa) { return aa .byValue .map!(entry => DatabaseEntry(entry)) .array .sort!((a,b) => a.id < b.id); } void main() { auto arrayA = [ 4:["id":"4", "deleted":"f", "name":"6.2"], 3:["id":"3", "deleted":"f", "name":"5.6_hwlister"], 2:["id":"2", "deleted":"t", "name":"6.2"], 1:["id":"1", "deleted":"f", "name":"5.6"] ]; auto arrayB = [ 6:["id":"6", "deleted":"f", "name":"6.2_test"], 5:["id":"5", "deleted":"f", "name":"5.6_test"], 4:["id":"4", "deleted":"f", "name":"6.2_hwlister"], 3:["id":"3", "deleted":"f", "name":"5.6_hwlister"], 2:["id":"2", "deleted":"f", "name":"6.2"], 1:["id":"1", "deleted":"f", "name":"5.6"] ]; auto entriesFromA = buildSortedEntryRange(arrayA); auto entriesFromB = buildSortedEntryRange(arrayB); auto range = zip(StoppingPolicy.longest, entriesFromA, entriesFromB); foreach (entryA, entryB; range) { if (entryA != entryB) { writeln(entryB); // ... } } } ``` Output is: ``` DatabaseEntry(2, "f", "6.2") DatabaseEntry(4, "f", "6.2_hwlister") DatabaseEntry(5, "f", "5.6_test") DatabaseEntry(6, "f", "6.2_test") ```
Re: Formatted date
On Wednesday, 22 March 2023 at 14:02:53 UTC, Alexander Zhirov wrote: So that i can get a more readable look: `2023-Mar-22 16:53:42.2507395` => `2023.03.22 16:53:42` Maybe there's a better way but I just do this. ``` import std; void main() { const now = Clock.currTime(); enum pattern = "%d.%02d.%02d %02d:%02d:%02d"; writefln(pattern, now.year, now.month, now.day, now.hour, now.minute, now.second); } ``` https://run.dlang.io/is/mhvzN2
Re: Formatted date
On Wednesday, 22 March 2023 at 14:02:53 UTC, Alexander Zhirov wrote: Convert date from received time ``` Clock.currTime().toSimpleString() ``` I missed the part about receiving the time, so ignore my previous post.
Prevent console line advancing on user input
Wondering if this is possible? Ask a user at input and wait for response: write("Is the sky blue? "); readf!" %s\n"(response); If the user's response is correct, I'd like to change the color of provided response to indicate it was correct then advance to the next line and ask a different question. If the user's response is incorrect, I'd like to clear the line and repeat the question without advancing down the screen vertically. I'm assuming it can be done by intercepting all input before the console processes them and outputting a '\r', a blank line the length of the screen, and another '\r' to get back to the beginning before reprinting the question. But I have no idea how to intercept the raw input. Would appreciate any pointers. Thanks --anonymouse
Re: Prevent console line advancing on user input
On Thursday, 6 April 2023 at 14:51:43 UTC, Steven Schveighoffer wrote: On 4/6/23 4:01 AM, anonymouse wrote: Wondering if this is possible? [snip] You need to use a terminal-control library, such as `arsd.terminal` https://github.com/adamdruppe/arsd/blob/master/terminal.d -Steve That works perfectly. Thanks.
request assistance resolving a std.net.curl sementation fault
What am I doing wrong here? ```D import std.net.curl: Curl, CurlOption, CurlException; import std.file: exists; import std.stdio: File, writefln; import core.thread: Thread; void downloadFile(string url, string filename) { while (true) { try { File fp; if (filename.exists()) fp.open(filename, "a"); else fp.open(filename, "w"); Curl curl; curl.initialize(); curl.onProgress = delegate int(size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow) { writefln("Progress: %s of %s", dlnow, dltotal); return 0; }; curl.set(CurlOption.url, url~filename); curl.set(CurlOption.resume_from_large, fp.size()); // Start the download curl.set(CurlOption.writedata, &fp); curl.perform(); // Close the file fp.close(); writefln("Download as %s complete.", filename); break; } catch (CurlException e) { writefln("Error while downloading: %s", e.msg); // Wait for a bit before retrying Thread.sleep(imported!"core.time".seconds(10)); } } } void main() { string url = "https://downloads.dlang.org/releases/2.x/2.103.1/";; string filename = "dmd.2.103.1.dmg"; downloadFile(url, filename); } ``` Output: ``` ./download_file Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 zsh: segmentation fault ./download_file ``` Thanks. --anonymouse
request assistance resolving a std.net.curl segmentation fault
What am I doing wrong here? ```D import std.net.curl: Curl, CurlOption, CurlException; import std.file: exists; import std.stdio: File, writefln; import core.thread: Thread; void downloadFile(string url, string filename) { while (true) { try { File fp; if (filename.exists()) fp.open(filename, "a"); else fp.open(filename, "w"); Curl curl; curl.initialize(); curl.onProgress = delegate int(size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow) { writefln("Progress: %s of %s", dlnow, dltotal); return 0; }; curl.set(CurlOption.url, url~filename); curl.set(CurlOption.resume_from_large, fp.size()); // Start the download curl.set(CurlOption.writedata, &fp); curl.perform(); // Close the file fp.close(); writefln("Download as %s complete.", filename); break; } catch (CurlException e) { writefln("Error while downloading: %s", e.msg); // Wait for a bit before retrying Thread.sleep(imported!"core.time".seconds(10)); } } } void main() { string url = "https://downloads.dlang.org/releases/2.x/2.103.1/";; string filename = "dmd.2.103.1.dmg"; downloadFile(url, filename); } ``` Output: ``` ./download_file Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 Progress: 0 of 0 zsh: segmentation fault ./download_file ``` Thanks. --anonymouse
Re: request assistance resolving a std.net.curl segmentation fault
On Friday, 19 May 2023 at 12:28:20 UTC, kdevel wrote: On Friday, 19 May 2023 at 11:07:01 UTC, anonymouse wrote: What am I doing wrong here? [...] curl.set(CurlOption.writedata, &fp); According to [1] this line must read ``` curl.set(CurlOption.writedata, cast (void *) fp.getFP()); ``` [1] https://curl.se/libcurl/c/CURLOPT_WRITEDATA.html Thank you so much.
Re: request assistance resolving a std.net.curl segmentation fault
On Friday, 19 May 2023 at 12:28:20 UTC, kdevel wrote: On Friday, 19 May 2023 at 11:07:01 UTC, anonymouse wrote: What am I doing wrong here? [...] curl.set(CurlOption.writedata, &fp); According to [1] this line must read ``` curl.set(CurlOption.writedata, cast (void *) fp.getFP()); ``` [1] https://curl.se/libcurl/c/CURLOPT_WRITEDATA.html Thank you so much.
Re: request assistance resolving a std.net.curl segmentation fault
On Friday, 19 May 2023 at 12:40:29 UTC, Danny Arends wrote: On Friday, 19 May 2023 at 11:07:01 UTC, anonymouse wrote: What am I doing wrong here? [SNIP] You're running the whole thing in a while(TRUE) loop, recreating the curl object re-initiating the transfer and file pointer, etc. The reason I used a while loop was to detect loss of internet connection and resume the process once the connection is re-established. What would have been a better approach? furthermore, the curl.set(CurlOption.writedata, &fp); doesn't work as you expect.. The idea was to detect an incomplete download and continue from where it left off. I'm sometimes downloading files 15Gb or greater. Reaching 80% and having to restart the process is a nogo. As I understand it, `CurlOption.writedata` allows me to achieve that goal. Is there a better option to accomplish the same? After fiddling a bit, this works: curl.onReceive = (ubyte[] data) { fp.rawWrite(data); return data.length;}; Thank you for your assistance thus far. --anonymouse
Re: iota where step is a function
On Wednesday, 24 May 2023 at 16:39:36 UTC, Ben Jones wrote: Is there a range like iota in phobos where step is a function? I want to specify begin/end and have the "step" be next = fun(prev). Should be easy to write, but don't want to reinvent the wheel. D import std.stdio; import std.range: iota; void main() { iota(10, 0, -1).writeln; }
Re: request assistance resolving a std.net.curl segmentation fault
On Saturday, 20 May 2023 at 09:20:54 UTC, kdevel wrote: What if the internet connection is not re-established within an reasonable amount of time? What if the resource is no longer available on the server (HTTP eror 404 [1])? If there is an interactive user: Wouldn't it be better have the user restart the download at his discretion? I am the interactive user but I'm usually not on site to monitor it while this is happening. What would have been a better approach? That depends on where you want to use that download function. If it is intended to download a full software update of a modern e-vehicle I would suggest not to use such an endless loop. I would limit the retries to a low single-digit number greater than one and of log the event. Noted. ``` ubyte [] buf; curl.set (CurlOption.errorbuffer, buf.ptr); ``` to store that result. Okay. Got it. Thank you.
Re: iota where step is a function
On Thursday, 25 May 2023 at 00:18:44 UTC, anonymouse wrote: On Wednesday, 24 May 2023 at 16:39:36 UTC, Ben Jones wrote: Is there a range like iota in phobos where step is a function? I want to specify begin/end and have the "step" be next = fun(prev). Should be easy to write, but don't want to reinvent the wheel. D import std.stdio; import std.range: iota; void main() { iota(10, 0, -1).writeln; } I think I misunderstood what was being asked here.
Re: looking for work-around: _d_assocarrayliteralTX segfault assigning a shared associative array an AA literal
On Tuesday, 13 June 2023 at 17:06:55 UTC, mw wrote: Does anyone know how to fix it? or any work-around? Thanks. I don't know if it's *correct* or not, but I think I did this at the time to work around it. ``` shared string[string] aa; void main() { auto aaTemp = [ "abc" : "123" ]; aa = cast(shared)aaTemp; } ```
Re: Private nested class instance accessed via outer class public interface
On Friday, 16 June 2023 at 07:47:50 UTC, Murloc wrote: And since classes can be declared locally inside methods, you can also do something similar this way: ```d import std.stdio; import std.conv; Object getB() { class B { private int field = 30; override string toString() => to!string(field); } return cast(Object)new B(); } void main() { auto b = getB(); writeln(b); // 30 } ``` This isn't fully playing to its strengths either, there's no need to cast it to Object if you declare the return type to be `auto`. ``` import std.stdio; import std.conv; auto getB() { class B { private int field = 30; override string toString() => to!string(field); } return new B(); } void main() { auto b = getB(); writeln(b); // 30 } ``` I use it a lot like so: ``` import std; auto getThing() { struct Thing { int x, y; double weight; int fluffiness; } Thing thing; thing.x = 42; thing.y = 128; thing.weight = 99.9; thing.fluffiness = 9001; return thing; } void main() { //Thing thing; // Unidentified identifier Thing auto thing = getThing(); writeln(typeof(thing).stringof); // Thing writeln(thing); // Thing(42, 128, 99.9, 9001) } ``` https://wiki.dlang.org/Voldemort_types
Re: GC doesn't collect where expected
On Monday, 19 June 2023 at 16:43:30 UTC, Steven Schveighoffer wrote: In this specific case, most likely it's a stale register or stack reference. One way I usually use to ensure such things is to call a function that destroys the existing stack: ```d void clobber() { int[2048] x; } ``` Calling this function will clear out 2048x4 bytes of data to 0 on the stack. -Steve Could you elaborate on how you use this? When do you call it? Just, ever so often, or is there thought behind it?
Graphing
How would I go about graphing time series data (specifically, candles, moving averages, etc) in D and dynamically updating such charts? Thanks, --anonymouse
Re: Public visible entities published by a module
On Friday, 7 July 2023 at 17:46:09 UTC, Cecil Ward wrote: A bit of a weird question, and I’m not sure how to word it. Say I have a module, and I’d like to list / enumerate all the public visible things that the module exports / publishes ‘ makes visible. Is there a way of doing that ? Of getting that kind of listing? I’m wondering about information leaking when things should be encapsulated. I did this. It's super ugly and even has `__traits(compiles)` in there, but as a quick and dirty solution it served well enough. ```d void printPublicMembersOfModule(string module_)() { mixin("import thisModule = " ~ module_ ~ ";"); foreach (symstring; __traits(allMembers, thisModule)) { alias symbol = __traits(getMember, thisModule, symstring); static if ( __traits(compiles, __traits(getVisibility, symbol)) && __traits(getVisibility, symbol) == "public") { pragma(msg, symstring); } } } void main() { printPublicMembersOfModule!"std.stdio"(); } ``` https://run.dlang.io/is/tvNDdp
Re: Recommendation on plotting library
On Thursday, 20 July 2023 at 04:41:48 UTC, Chris Piker wrote: On Thursday, 20 July 2023 at 03:58:05 UTC, Andrew wrote: I just tried ggplotd and it was easy to make it work on Linux, only one external apt command needed, but on Windows, even that is a deal breaker. Package management on Windows seems to be wild-west/nonexistent. Have you tried https://github.com/koji-kojiro/matplotlib-d? There is a slightly more updated fork out there but I can't remember exactly who maintains it. Side musing... Since I've seen many people use anaconda on Windows, I wonder how hard it would be to make a conda package that provided dmd+dub? Have you tried chocolatey.org? It's similar to homebrew for macOS but for Windows.
Re: aarch64 plans for D lang ?
On Monday, 28 August 2023 at 15:14:52 UTC, BrianLinuxing wrote: Thank you that looks good :) But is it the full installer and all of the bits? The official [`install.sh`](https://dlang.org/install.html) script will download ldc on ARM too, just as well as on x86. I use it on my Pi400.
Re: Meaning of the dot-function syntax
On Sunday, 1 October 2023 at 08:22:48 UTC, dhs wrote: Hi, What's the meaning of the dot in the call to writeln() below? ```d .writeln("Hello there!"); ``` I haven't found this in the spec or anywhere else. This is used very often in the source code for Phobos. Thanks, dhs Quote https://dlang.org/spec/module.html#module_scope_operators; A leading dot (`.`) causes the identifier to be looked up in the module scope. ```d int x; int foo(int x) { if (y) return x; // returns foo.x, not global x else return .x; // returns global x } ```
Re: Checking path name
On Thursday, 14 December 2023 at 03:58:37 UTC, Joel wrote: If I get user input, for example, how do I check to see if it's a valid path, like, file name. ```d // something like this: if (getUserInput.isValidPath) { ... } ``` Is that not how it works? https://dlang.org/phobos/std_path.html#isValidPath https://dlang.org/phobos/std_path.html#.isValidFilename
Synchronisation help
I have a `shared string[int]` AA that I access from two different threads. The function I spawn to start the second thread takes the AA as an argument. ```d class Foo { shared string[int] bucket; Tid worker; } void workerFn(shared string[int] bucket) { while (true) { // occasionally reads, occasionally modifies bucket } } void main() { auto foo = new Foo; foo.bucket[0] = string.init; foo.bucket.remove(0); foo.worker = spawn(&workerFn, foo.bucket); while (true) { // occasionally reads, occasionally modifies bucket } } ``` (`run.dlang.io` shortening seems broken again, but I made a [gist](https://gist.github.com/zorael/17b042c424cfea5ebb5f1f3120f983f4) of a more complete example.) Reading the specs on `synchronized` statements, it seems I need to provide an `Object` to base synchronisation on when two *different* places in the code needs synchronising, whereas if it's in the same place an expressionless `synchronize { }` will do. The worker function can't see `Foo foo` inside `main`, so it can't share synchronisation on that. What is the common solution here? Do I add a module-level `Object thing` and move everything accessing the AA into `synchronized(.thing)` statements? Or maybe add a `shared static` something to `Foo` and synchronise with `synchronize(Foo.thing)`?
Re: Synchronisation help
On Monday, 1 January 2024 at 19:49:28 UTC, Jonathan M Davis wrote: [...] Thank you. Yes, `Foo` is a class for the purposes of inheritance -- I left that out of the example. So a completely valid solution is to write a struct wrapper around an AA of the type I need, overload the required operators, and then just drop-in replace the current AA? All array operations would then transparently be between lock and unlock statements. ```d struct MutexedAA(AA : V[K], V, K) { import core.sync.mutex : Mutex; shared Mutex mutex; shared AA aa; void setup() nothrow { mutex = new shared Mutex; mutex.lock_nothrow(); if (K.init !in (cast()aa)) { (cast()aa)[K.init] = V.init; (cast()aa).remove(K.init); } mutex.unlock_nothrow(); } auto opIndexAssign(V value, K key) in (mutex, typeof(this).stringof ~ " has null Mutex") { mutex.lock_nothrow(); (cast()aa)[key] = value; mutex.unlock_nothrow(); return value; } auto opIndex(K key) in (mutex, typeof(this).stringof ~ " has null Mutex") { mutex.lock_nothrow(); auto value = (cast()aa)[key]; mutex.unlock_nothrow(); return value; } auto opBinaryRight(string op : "in")(K key) in (mutex, typeof(this).stringof ~ " has null Mutex") { mutex.lock_nothrow(); auto value = key in cast()aa; mutex.unlock_nothrow(); return value; } auto remove(K key) in (mutex, typeof(this).stringof ~ " has null Mutex") { mutex.lock_nothrow(); auto value = (cast()aa).remove(key); mutex.unlock_nothrow(); return value; } auto opEquals()(auto ref typeof(this) other) in (mutex, typeof(this).stringof ~ " has null Mutex") { mutex.lock_nothrow(); auto isEqual = (cast()aa == cast()(other.aa)); mutex.unlock_nothrow(); return isEqual; } auto opEquals()(auto ref AA other) in (mutex, typeof(this).stringof ~ " has null Mutex") { mutex.lock_nothrow(); auto isEqual = (cast()aa == other); mutex.unlock_nothrow(); return isEqual; } } ``` (https://gist.github.com/zorael/433c50f238b21b9bb68d076d8a495045) I tried this and it seems to work. Is it glaringly incorrect somehow, or am I free to roll with this? You mention passing a `shared Foo*`. In the gist I pass the instance of the `MutexedAA!(string[int])` to the worker thread *by value* instead of as something `shared`, since I couldn't get operator overloading to work when `shared`. (Calling `sharedAA.opIndexAssign("hello", 42)` worked, but `sharedAA[42] = "hello"` wouldn't compile.) I guess this can break synchronisation between the two if I replace the `Mutex` in either thread. Are there any other obvious caveats?
Re: Synchronisation help
On Tuesday, 2 January 2024 at 11:05:33 UTC, user1234 wrote: Do not use `shared` AA. Use `__gshared` + sync primitives. `shared` AA will lead to all sort of bugs: - https://issues.dlang.org/show_bug.cgi?id=20484#c1 - https://issues.dlang.org/show_bug.cgi?id=17088 - https://issues.dlang.org/show_bug.cgi?id=16597 - etc. Hmm, I see. Is `shared` safe to use with AAs *provided* I use sync primitives, or should I favour `__gshared` over `shared`? I was under the impression `__gshared` was only really meant for interfacing with C.
Re: Synchronisation help
On Tuesday, 2 January 2024 at 18:01:55 UTC, Jonathan M Davis wrote: [...] That clarifies a lot. If nothing else, I realise now I can't have `opBinaryRight(string op : "in")` the way I had hoped. What I have now probably doesn't cover 100% of every use-case, but it should do for my scope. I'm much more confident using this compared to the naked `shared` AA I started with. Thanks everyone for the help.
Re: Help optimize D solution to phone encoding problem: extremely slow performace.
On Saturday, 13 January 2024 at 12:55:27 UTC, Renato wrote: [...] Not a great profiling experience :). Anyone has a better suggestion to "parse" the trace file? As a drive-by suggestion and I hope it doesn't derail anything, but if you have the opportunity to run it on linux, have you tried profiling with callgrind instead, with {Q,K}Cachegrind to visualise things? Your repositories probably have them. (callgrind is a part of valgrind.) The wiki only mentions callgrind in passing, but it has worked well for me. [(example)](https://i.imgur.com/WWZAwy3.png)
Re: Help optimize D solution to phone encoding problem: extremely slow performace.
On Saturday, 13 January 2024 at 23:20:32 UTC, Sergey wrote: I would suggest to rewrite in the same way as Rust implemented. Probably you would like to try: [...] I would strongly argue for profiling first instead of optimising based on conjecture. If you profile you have solid evidence on what is actually slow. If you're very good at analysing D, well-educated hypotheses *may* be enough, until they suddenly aren't and you will have spent a lot of time on the wrong problem.
Nested delegates and closure allocations
I'm increasingly using nested delegates to partition code. ```d void foo(Thing thing) { void sendThing(const string where, int i) { send(thing, where, i); } sendThing("bar", 42); } ``` ...where the nested `sendThing` sometimes returns something, sometimes doesn't. `Thing` may be a class or a value type, `thing` may be a parameter to the parent function, may be a variable previously declared in the parent function, may be mutable or immutable, may be modified inside `sendThing`; any combination of things. If `sendThing` doesn't need to access the scope of `foo` I mark it `static` to enforce that, but mostly it does. From the spec: ### `19.19.2` Delegates & Closures 3. Those referenced stack variables that make up the closure are allocated on the GC heap, unless: * The closure is passed to a scope parameter. * The closure is an initializer for a scope variable. * The closure is assigned to a scope variable. I'm generally not storing the delegates or passing them around as values, so I don't think the thing about scope variables and parameters *directly* applies. Am I safe as long as I don't do something like, pass `&sendThing` as an argument to `std.concurrency.receive`?
Re: Nested delegates and closure allocations
On Tuesday, 16 January 2024 at 13:45:22 UTC, FeepingCreature wrote: Am I safe as long as I don't do something like, pass `&sendThing` as an argument to `std.concurrency.receive`? Yes. Thank you. And to make sure I don't misunderstand the spec; in the case I *do* have a delegate I want to pass elsewhere, and `scope dg = &myFun;` *does* compile, passing that `dg` around won't allocate a closure? ```d void foo(Thing thing) @nogc { void sendThing(const string where, int i) { send(thing, where, i); } receiveTimeout(Duration.zero, &sendThing); } ``` The above naturally won't compile because `std.concurrency.receiveTimeout` requires the garbage collector, but notably in the error message, this is included; ``` onlineapp.d(10): Error: function `onlineapp.foo` is `@nogc` yet allocates closure for `foo()` with the GC onlineapp.d(12):`onlineapp.foo.sendThing` closes over variable `thing` at onlineapp.d(10) ``` If I make a `scope` variable of the delegate and pass *it* to `receiveTimeout`, there no longer seems to be any mention of the closure in the error (given 2.092 or later). ```d void foo(Thing thing) @nogc { void sendThing(const string where, int i) { send(thing, where, i); } scope scopeSendThing = &sendThing; receiveTimeout(Duration.zero, scopeSendThing); } ``` Ignoring that it doesn't compile for other reasons; provided `scope scopeSendThing = &sendThing;` compiles -- as in, `&sendThing` is eligible for `scope` -- is this a valid workaround?
Re: Nested delegates and closure allocations
On Tuesday, 16 January 2024 at 17:21:12 UTC, FeepingCreature wrote: Correct. [...] Thanks, I think I understand.
Re: Delegates and values captured inside loops
On Saturday, 20 January 2024 at 16:32:42 UTC, FeepingCreature wrote: ``` foreach (name; names) { dgs ~= ((name) => () => writeln(name))(name); } ``` lol Thanks, I'll try that.
Re: Setting field of struct object
On Monday, 22 January 2024 at 08:27:36 UTC, Joel wrote: ```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joel...@gmail.com").withAge(44); writeln(p); } ``` I had reason to need this to work a while ago and `opDispatch` came in very handy. I was able to cook up one that forwarded calls to other members in a struct, while returning `this` by ref, allowing for chaining calls. I use it with UDAs. (Scroll to the unit tests for examples.) ```d /++ Mixin template generating an `opDispatch` redirecting calls to members whose names match the passed variable string but with an underscore prepended. +/ mixin template UnderscoreOpDispatcher() { ref auto opDispatch(string var, T)(T value) { import std.traits : isArray, isAssociativeArray, isSomeString; enum realVar = '_' ~ var; alias V = typeof(mixin(realVar)); static if (isAssociativeArray!V) { // Doesn't work with AAs without library solutions } else static if (isArray!V && !isSomeString!V) { mixin(realVar) ~= value; } else { mixin(realVar) = value; } return this; } auto opDispatch(string var)() inout { enum realVar = '_' ~ var; return mixin(realVar); } } /// unittest { struct Foo { int _i; string _s; bool _b; string[] _add; alias wordList = _add; mixin UnderscoreOpDispatcher; } Foo f; f.i = 42; // f.opDispatch!"i"(42); f.s = "hello";// f.opDispatch!"s"("hello"); f.b = true; // f.opDispatch!"b"(true); f.add("hello"); // f.opDispatch!"add"("hello"); f.add("world"); // f.opDispatch!"add"("world"); assert(f.i == 42); assert(f.s == "hello"); assert(f.b); assert(f.wordList == [ "hello", "world" ]); auto f2 = Foo() .i(9001) .s("world") .b(false) .add("hello") .add("world"); assert(f2.i == 9001); assert(f2.s == "world"); assert(!f2.b); assert(f2.wordList == [ "hello", "world" ]); } ``` You could trivially adapt it to use a `withName`, `withEmail` calling scheme instead of the underscore thing.
Re: Scripting with Variant from std.variant: parameter passing
On Friday, 2 February 2024 at 08:22:42 UTC, Carl Sturtivant wrote: It seems I cannot pass e.g. an int argument to a Variant function parameter. What's the simplest way to work around this restriction? The easiest thing would be to actually pass it a `Variant` with `someFunction(Variant(myInt))`. The more-involved thing would be to write a template constrained to non-`Variants` that does the above for you. ```d auto someFunction(T)(T t) if (!is(T : Variant)) { return someFunction(Variant(t)); } auto someFunction(Variant v) { // ... } void main() { someFunction(42); someFunction("hello"); someFunction(3.14f); someFunction(true); someFunction(Variant(9001)); } ```
Re: Scripting with Variant from std.variant: parameter passing
On Saturday, 3 February 2024 at 08:04:40 UTC, Danilo wrote: To be honest, this doesn't make sense. `if (!is(T : Variant))` returns true for inputs like 42, "hello", 3.14f, but the input is not a Variant but a random type. Yes, it's nice that it works in this case. It's just not logical, it doesn't make sense because 42 just simply isn't a Variant, it's an `int`. I read it several times but I don't think I understand what you mean. The constraint `if (!is(T : Variant))` is true for every input that is not a `Variant`, yes. The point of it is to let calls to `someFunction(myVariant)` resolve to the non-templated `auto someFunction(Variant)`. Is your argument that it's wrong to assume an `int` *can be* wrapped in a `Variant`, because it isn't one? That in turn doesn't make sense -- your example does the same, just explicitly. ```d void main() { f( Variant(42)); f( Variant(2.5) ); f( Variant("Hi!") ); } ``` How is this different from the following? ```d void main() { (v){ f(Variant(v)); }(42); (v){ f(Variant(v)); }(2.5); (v){ f(Variant(v)); }("Hi!"); } ``` And how is that different from the following? ```d void main() { auto g(T)(T t) { f(Variant(t)); } g(42); g(2.5); g("Hi!"); } ``` Which is in what way different from the following? ```d auto g(T)(T t) if (!is(T : Variant)) { return f(Variant(t)); } auto f(Variant v) { // ... } void main() { g(42); g("hello"); g(3.14f); g(true); } ``` And how is that not the same as my original example?
Re: OPTLINK : Warning 9: Unknown Option : OUT
On Tuesday, 16 July 2019 at 11:20:49 UTC, Boris Carvajal wrote: The debugger exposes a crash in memchr from C runtime. In file messaging.d line 216 called from the unittest just below if (emoteTarget.beginsWithOneOf(state.client.server.chantypes)) chantypes.ptr is null. However chantypes.length is 1 so you are assigning something invalid to it. grep -nr "chantypes = " kameloso/ shows this place as something to care about kameloso/source/kameloso/irc/parsing.d:1983: chantypes = value; Again, thank you for your immense help! This is weird, chantypes should refer to a slice of immutables (a string). Simplified: void onISUPPORT(ref IRCParser parser, ref string slice) { import std.algorithm.iteration : splitter; foreach (string value; slice.splitter(' ')) { // ... parser.client.server.chantypes = value; } } IRCParser.init.chantypes even has a default value of "#". I get the same error even if I try to work around it with .idup. The only thing that does seem to help is checking for .ptr !is null at the unittest location you mention. if (state.client.server.chantypes.ptr && emoteTarget.beginsWithOneOf(state.client.server.chantypes)) I started a dustmite process, with some luck it should produce something smaller by tonight or tomorrow.
Re: OPTLINK : Warning 9: Unknown Option : OUT
On Tuesday, 16 July 2019 at 13:33:01 UTC, Anonymouse wrote: IRCParser.init.chantypes even has a default value of "#". IRCParser.init.client.server.chantypes.
Re: OPTLINK : Warning 9: Unknown Option : OUT
On Tuesday, 16 July 2019 at 13:33:01 UTC, Anonymouse wrote: I started a dustmite process, with some luck it should produce something smaller by tonight or tomorrow. Reduced: import std.experimental.logger : Logger; void main() { Logger logger; logger.error(); } git clone https://github.com/zorael/tests -b loggererror $ dub run Performing "debug" build using C:\D\dmd2\windows\bin\dmd.exe for x86_64. tests ~loggererror: building configuration "application"... Linking... Running .\tests.exe Program exited with code -1073741819 $ dmd -oftests.exe source/app.d && ./tests.exe object.Error@(0): Access Violation 0x00402381 0x00402357 0x00409055 0x00408EF0 0x004075A7 0x76358494 in BaseThreadInitThunk 0x775341C8 in RtlAreBitsSet 0x77534198 in RtlAreBitsSet
Re: OPTLINK : Warning 9: Unknown Option : OUT
On Wednesday, 17 July 2019 at 17:43:53 UTC, Anonymouse wrote: [...] Ignore this, Logger is a class and the error is to be expected. Will retry dustmite.
Re: How to check that import module will succeed?
On Friday, 26 July 2019 at 06:24:18 UTC, evilrat wrote: On Friday, 26 July 2019 at 03:42:58 UTC, Andrey Zherikov wrote: bool isModuleAvailable(alias modName)() { mixin("import " ~ modName ~ ";"); static if (__traits(compiles, mixin(modName).stringof)) return true; else return false; } // use like this static if (__traits(compiles, isModuleAvailable!"mymod" )) import mymod; I forgot the exact details but I ran into troubles with this where __traits(compiles, moduleName) would evaluate to false even if the module was available, if there were top-level errors in it. I use __traits(compiles, __traits(identifier, moduleName)) now instead and it seems to work.
Re: Use std.string.lineSplitter with std.array.Appender!string
On Wednesday, 28 August 2019 at 15:52:18 UTC, NonNull wrote: Disambiguate how ? ``` import std.string, std.array; auto s = appender!string; // ... auto a = s.lineSplitter; ``` auto a = s.data.lineSplitter; On mobile, can't test.
Interdependent dub subpackages
I have a project where the source is mixed library, mixed application, and I'd like to separate the two. The code is fairly decoupled as is, but the files are all next to each other in the same namespace. I moved out the library parts and made a new dub package, and it alone compiles fine. Ideally I'd like to separate it further into subpackages in a tree-like structure where some depend on others (but not the other way around). /dub.sdl --- name "lu" targetType "none" dependency "lu:base" version="*" dependency "lu:utils" version="*" subPackage { name "base" targetType "library" sourcePaths "base" } subPackage { name "utils" targetType "library" sourcePaths "utils" } --- /base/dub.sdl --- name "base" targetType "library" sourcePaths "source" --- /utils/dub.sdl --- name "utils" targetType "library" sourcePaths "source" dependency "lu:base" version="*" --- $ dub build Performing "debug" build using /usr/bin/dmd for x86_64. lu:base ~master: building configuration "library"... lu:utils ~master: building configuration "library"... utils/source/config.d(35,12): Error: module `common` is in file 'lu/base/common.d' which cannot be read import path[0] = /usr/include/dlang/dmd /usr/bin/dmd failed with exit code 1. The offending line is naturally `import lu.base.common;`. Is what I'm trying to do not possible? I thought lu:utils would just use the generated liblu_base.a. Am I not understanding it right? I tried adding importPaths "." to the subPackages section in /dub.sdl in hope it would see it but it did nothing. importPaths "base" does nothing either. Do I need to add the source paths for "upstream" subpackages after all? Is that kind of downward dependency tree not possible?
Re: Deprecation message sources
On Tuesday, 17 September 2019 at 19:31:53 UTC, Steven Schveighoffer wrote: I'd hate to say the answer is to special case Nullable for so many functions, but what other alternative is there? -Steve Nullable isn't alone, std.json.JSONType causes a literal wall of text of deprecation warnings. import std.stdio; import std.json; void main() { writeln(JSONValue.init.type); } https://run.dlang.io/is/J0UDay
Inspecting __traits(isDeprecated) and deprecation warnings
I want to write a piece of code that reflects on the names of members of a passed struct, where some are depreacted. https://run.dlang.io/is/P9EtRG struct Foo { string s; int ii; bool bbb; deprecated("Use `s`") string ; } template longestMemberLength(T) { enum longestMemberLength = () { size_t maxLength; foreach (immutable i, immutable name; __traits(allMembers, T)) { static if (!__traits(isDeprecated, __traits(getMember, T, name))) { maxLength = max(maxLength, name.length); } } return maxLength; }(); } static assert (longestMemberLength!Foo == "bbb".length); onlineapp.d(23): Deprecation: variable `onlineapp.Foo.` is deprecated - Use s Is there any way to inspect the deprecated-ness of a member this way? I only have what __traits(allMembers) gives me.
Re: Inspecting __traits(isDeprecated) and deprecation warnings
On Wednesday, 25 September 2019 at 05:57:19 UTC, Tobias Pankrath wrote: Does your code work or does it not? I don't seem to unterstand neither what the question here is nor what the desired result is. Is the problem that the static reflections triggers the deprecation warning? I added some deprecations in my project and am going through my templates trying to silence the warnings that suddenly popped up. This template works, but it triggers deprecation warnings when I am actively trying to avoid them. getMember in _traits(isDeprecated, __traits(getMember, T, name)) causes a warning on deprecated symbols, which I wanted to avoid with isDeprecated, but I couldn't without first calling getMember to get the symbol to evaluate it. There's no way to combine isDeprecated with getMember without getting a warning. I worked around the issue by using .tupleof instead of getMember, which breaks it for classes (.tupleof needs a `this` and SomeClass.init can't be it) but silences warnings for structs. https://run.dlang.io/is/TVR8Cb import std; void main() { static assert(longestMemberName!Foo == "bbb".length); } struct Foo { string s; int ii; bool bbb; deprecated("Use `s`") string ; } template longestMemberName(T) if (is(T == struct)) { enum longestMemberName = () { size_t maxLength; T thing; // need a `this` foreach (immutable i, member; thing.tupleof) { static if (!__traits(isDeprecated, thing.tupleof[i]) && !isType!(thing.tupleof[i])) { enum name = __traits(identifier, thing.tupleof[i]); maxLength = max(maxLength, name.length); } } return maxLength; }(); }
Re: Inspecting __traits(isDeprecated) and deprecation warnings
On Wednesday, 25 September 2019 at 20:35:55 UTC, Boris Carvajal wrote: On Wednesday, 25 September 2019 at 14:20:00 UTC, Anonymouse wrote: I added some deprecations in my project and am going through my templates trying to silence the warnings that suddenly popped up. This template works, but it triggers deprecation warnings when I am actively trying to avoid them. This code seems to work for classes too and even with DMD "-de" compiler switch. template isMemberDeprecated(T, string name) { enum isMemberDeprecated = mixin(q{__traits(isDeprecated, }, T, ".", name, q{)}); } https://run.dlang.io/is/iQbxOC I think I can work with this, thanks!
Re: How to Unqual an array?
On Saturday, 16 November 2019 at 15:20:26 UTC, James Blachly wrote: On 11/16/19 9:48 AM, James Blachly wrote: I am trying to write templated code that will take a character array -- mutable, const, or immutable (string). I am aware of isSomeString, but I am still curious about Unqual array from a learning perspective. https://pastebin.com/f2FUAYQT is what I use, assuming I understand what you want. (run.dlang.io shortening seems to be down.)
Re: list of all defined items in a D file
On Thursday, 23 January 2020 at 17:10:29 UTC, berni44 wrote: I'd like to get a list of all items (public, package, private) that are defined in a D file. Is there a simple way, to get them? __traits(allMembers, mixin(__MODULE__))? Replace with a full module name if not the current one. You'll only get their string names with that though, not aliases to the symbols themselves (as you would have with .tupleof). I imagine you could get those with __traits(getMember, moduleName, stringName).
digger: Failed to spawn new process (The system cannot find the file specified.)
I'm trying to bisect a dmd compilation error on Windows 10 and I can't get digger to do more than one initial test. When preparing to compile the next dmd build (the BAD revision) it errors out. This is in a normal cmd console. The bisect ini has nothing weird in it: ``` bad = v2.088.1 good = v2.087.1 reverse = false tester = cd C:\Temp\init2 && C:\D\dmd2\windows\bin\dub.exe build 2>&1 | findstr /C:"Memory allocation failed" ``` Console log excerpt: ``` [...] digger: -- Running test command... --- core.exception.OutOfMemoryError@src\core\exception.d(647): Memory allocation failed digger: - Test command exited with status 0 (GOOD). -- digger: Sanity-check, testing BAD revision b7a303005afce50f317c768311b71bc21d47090d... digger: Testing revision: b7a303005afce50f317c768311b71bc21d47090d digger: Starting at meta repository commit b7a303005afce50f317c768311b71bc21d47090d digger: Building components dmd, druntime, phobos-includes, phobos, rdmd digger: needInstalled: dmd-8a2067c4bd9c720098c8acb5429f189b12b32ab6-07d4846ed48eb28d158e52488e305015 digger: Cache miss. digger: needBuild: dmd-8a2067c4bd9c720098c8acb5429f189b12b32ab6-07d4846ed48eb28d158e52488e305015 digger: Cleaning repository dmd... HEAD is now at 758722e42 bump VERSION to v2.087.1 digger: Checking out dmd commit 8a2067c4bd9c720098c8acb5429f189b12b32ab6... Previous HEAD position was 758722e42 bump VERSION to v2.087.1 HEAD is now at 8a2067c4b bump VERSION to v2.088.1 digger: Building dmd-8a2067c4bd9c720098c8acb5429f189b12b32ab6-07d4846ed48eb28d158e52488e305015 digger: DMC=C:\Temp\work\dl\dm857-snn2074-optlink80017\bin digger: Preparing DMD v2.079.0 digger: hostDC=C:\Temp\work\dl\dmd-2.079.0\dmd2/windows/bin\dmd.exe digger: Cleaning repository dmd... HEAD is now at 8a2067c4b bump VERSION to v2.088.1 digger: Environment: SystemDrive=C: digger: Environment: TMPDIR=C:\Temp\work\tmp digger: Environment: HOME=C:\Temp\work\home digger: Environment: SystemRoot=C:\WINDOWS digger: Environment: PATH=C:\Temp\work\dl\dm857-snn2074-optlink80017\bin;C:\WINDOWS\system32;C:\WINDOWS digger: Environment: TEMP=C:\Temp\work\tmp digger: Environment: TMP=C:\Temp\work\tmp digger: Environment: DMC=C:\Temp\work\dl\dm857-snn2074-optlink80017\bin digger: Working directory: C:\Temp\work\repo\dmd\src digger: Running: "make" -f win32.mak ^"MODEL=32^" HOST_DC=C:\Temp\work\dl\dmd-2.079.0\dmd2/windows/bin\dmd.exe dmd if not exist "..\generated\windows\release\32" mkdir ..\generated\windows\release\32 make -fwin32.mak C=dmd\backend ROOT=dmd\root MAKE="make" HOST_DC="C:\Temp\work\dl\dmd-2.079.0\dmd2/windows/bin\dmd.exe" MODEL=32 CC="" LIB="lib" OBJ_MSVC="" "OPT=-o" "DEBUG=" "DDEBUG=" "DOPT=-O -release -inline" "LFLAGS=-L/delexe/la" ..\generated\windows\release\32\dmd.exe [...] Digital Mars Librarian Version 8.02n Copyright (C) Digital Mars 2000-2007 All Rights Reserved http://www.digitalmars.com/ctg/lib.html Digital Mars Librarian complete. C:\Temp\work\dl\dmd-2.079.0\dmd2/windows/bin\dmd.exe -of..\generated\build.exe -debug build.d ..\generated\build.exe --called-from-make OS=windows BUILD=release MODEL=32 HOST_DMD= HOST_DC=C:\Temp\work\dl\dmd-2.079.0\dmd2/windows/bin\dmd.exe ..\generated\windows\release\32\lexer.lib std.process.ProcessException@std\process.d(752): Failed to spawn new process (The system cannot find the file specified.) [...] --- errorlevel 1 --- errorlevel 1 digger: Saving to cache. digger: Clearing temporary cache digger: Build failed: object.Exception@C:\Users\zorael\AppData\Local\dub\packages\ae-0.0.2413\ae\sys\d\manager.d(850): Command ["make", "-f", "win32.mak", "MODEL=32", "HOST_DC=C:\\Temp\\work\\dl\\dmd-2.079.0\\dmd2/windows/bin\\dmd.exe", "dmd"] failed with status 1 [...] object.Exception@C:\Users\zorael\AppData\Local\dub\packages\digger-3.0.0-alpha-8\digger\bisect.d(89): BAD revision b7a303005afce50f317c768311b71bc21d47090d is not testable [...] Program exited with code 1 ``` It does a `dmd.exe -of..\generated\build.exe`, but then the immediately following call to `..\generated\build.exe` fails? What am I doing wrong?
Re: digger: Failed to spawn new process (The system cannot find the file specified.)
On Monday, 3 February 2020 at 20:09:43 UTC, MoonlightSentinel wrote: On Monday, 3 February 2020 at 16:54:20 UTC, Anonymouse wrote: It does a `dmd.exe -of..\generated\build.exe`, but then the immediately following call to `..\generated\build.exe` fails? What am I doing wrong? The executable was launched because make would yield a different error message otherwise. This seems to be an error during the environment processing of build.d, could you provide the full stack trace for this exception? std.process.ProcessException@std\process.d(752): Failed to spawn new process (The system cannot find the file specified.) It doesn't seem to include debugging symbols. Does digger not build its dmds with -g? ``` std.process.ProcessException@std\process.d(752): Failed to spawn new process (The system cannot find the file specified.) 0x004386D0 0x00441132 0x00454B5C 0x00444994 0x0042C808 0x004039BD 0x0040257D 0x004353FB 0x0043537D 0x00435218 0x0042948B 0x76C96359 in BaseThreadInitThunk 0x77457B74 in RtlGetAppContainerNamedObjectPath 0x77457B44 in RtlGetAppContainerNamedObjectPath ``` Here's the full log: https://pastebin.com/raw/6MyVDFPc
Re: digger: Failed to spawn new process (The system cannot find the file specified.)
On Monday, 3 February 2020 at 20:54:46 UTC, Vladimir Panteleev wrote: On Monday, 3 February 2020 at 20:41:00 UTC, Anonymouse wrote: It doesn't seem to include debugging symbols. Is your Digger version up-to-date? https://github.com/CyberShadow/ae/commit/48ee31a3b0d47e52769ee87b0e673034abe4add5 I was on beta 8. I forced dub to download the latest now (3.0.0-alpha-9), wiped the work directory and retried, but to similar results. https://pastebin.com/raw/zF39VKzc
Re: digger: Failed to spawn new process (The system cannot find the file specified.)
On Monday, 3 February 2020 at 21:33:09 UTC, Vladimir Panteleev wrote: On Monday, 3 February 2020 at 21:30:57 UTC, Anonymouse wrote: I was on beta 8. I forced dub to download the latest now (3.0.0-alpha-9), wiped the work directory and retried, but to similar results. The latest is v3.0.0-alpha-11. Oh, I guess that's not how semantic versioning works. Probably I should make a normal stable release. For now you can clone and build from source. New log: https://pastebin.com/raw/uUMNQjEN ``` ..\generated\build.exe --called-from-make OS=windows BUILD=release MODEL=32 HOST_DMD= HOST_DC=C:\Temp\work\dl\dmd-2.079.0\dmd2/windows/bin\dmd.exe ..\generated\windows\release\32\lexer.lib (TX) VERSION std.process.ProcessException@std\process.d(752): Failed to spawn new process (The system cannot find the file specified.) 0x00448EDC in @trusted std.process.Pid std.process.spawnProcessImpl(const(char[]), std.stdio.File, std.stdio.File, std.stdio.File, const(immutable(char)[][immutable(char)[]]), std.process.Config, const(char[])) 0x0044D6AA in @trusted std.process.Pid std.process.spawnProcess(const(char[][]), std.stdio.File, std.stdio.File, std.stdio.File, const(immutable(char)[][immutable(char)[]]), std.process.Config, const(char[])) 0x0046E114 in @trusted std.process.ProcessPipes std.process.pipeProcessImpl!(std.process.spawnProcess, const(char[])[]).pipeProcessImpl(const(char[])[], std.process.Redirect, const(immutable(char)[][immutable(char)[]]), std.process.Config, const(char[])) 0x004555A4 in @safe std.process.ProcessPipes std.process.pipeProcess(const(char[][]), std.process.Redirect, const(immutable(char)[][immutable(char)[]]), std.process.Config, const(char[])) 0x0043B160 in @trusted std.typecons.Tuple!(int, "status", immutable(char)[], "output").Tuple std.process.execute(const(char[][]), const(immutable(char)[][immutable(char)[]]), std.process.Config, uint, const(char[])) 0x0041DEAF in void build.__funcliteral51().__lambda1() at C:\Temp\work\repo\dmd\src\build.d(278) 0x00406D0B in void build.DependencyRef.runSynchronized() at C:\Temp\work\repo\dmd\src\build.d(1092) 0x0040347F in void build.DependencyRef.run() at C:\Temp\work\repo\dmd\src\build.d(1065) 0x00406C1D in void build.DependencyRef.runSynchronized() at C:\Temp\work\repo\dmd\src\build.d(1078) 0x0040347F in void build.DependencyRef.run() at C:\Temp\work\repo\dmd\src\build.d(1065) 0x00402783 in _Dmain at C:\Temp\work\repo\dmd\src\build.d(138) 0x004375B3 in void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll().__lambda1() 0x00437535 in void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() 0x004373D0 in _d_run_main 0x004371C8 in main at C:\Temp\work\repo\dmd\src\build.d(7) 0x004B4B91 in mainCRTStartup 0x74D36359 in BaseThreadInitThunk 0x77337B74 in RtlGetAppContainerNamedObjectPath 0x77337B44 in RtlGetAppContainerNamedObjectPath ```
Re: digger: Failed to spawn new process (The system cannot find the file specified.)
On Monday, 3 February 2020 at 21:58:31 UTC, Vladimir Panteleev wrote: On Monday, 3 February 2020 at 21:44:20 UTC, Anonymouse wrote: New log: https://pastebin.com/raw/uUMNQjEN It looks like it fails to execute git (to get the current version for the build). I don't know why that fails, as I see C:\Temp\work\dl\git\cmd is in PATH in the environment that build.exe is invoked with. I assume that that directory does contain a git.exe? You may have some luck further debugging the cause of the error with a strace-like tool such as Process Monitor. No, C:\Temp\work\dl\git does not exist. :o ``` Directory of C:\Temp\work\dl 03/02/2020 22:20 . 03/02/2020 22:20 .. 03/02/2020 22:20 7z 03/02/2020 22:20 384,846 7za920.zip 03/02/2020 22:20 dm857-snn2074-optlink80017 03/02/2020 22:19 3,057,337 dm857c.zip 03/02/2020 22:20 dmd-2.079.0 03/02/2020 22:2020,614,650 dmd.2.074.0.windows.7z 03/02/2020 22:2041,903,965 dmd.2.079.0.windows.zip 4 File(s) 65,960,798 bytes 5 Dir(s) 42,867,355,648 bytes free ```
Re: digger: Failed to spawn new process (The system cannot find the file specified.)
On Monday, 3 February 2020 at 22:08:50 UTC, Vladimir Panteleev wrote: On Monday, 3 February 2020 at 22:01:18 UTC, Anonymouse wrote: No, C:\Temp\work\dl\git does not exist. :o OK, that makes sense. Please try the latest Digger version (24cd4168956dad382d05984b4b8d37d9e8ebe3ae). Works great. Thanks for your help!
Re: Some impressions/notes from a new D programmer
On Wednesday, 12 February 2020 at 13:36:13 UTC, mark wrote: Some cargo packages are applications. If I do 'cargo install someapp' it will be installed in $HOME/.cargo/bin. So by simply adding that to my PATH, I can easily use all installed rust apps. But dub doesn't appear to have an equivalent of this. There is 'dub run someapp', which is good enough for some cases, like digger[1]. But no 'dub install someapp', no. Maybe there are some hard design decisions again $HOME/.dub/bin, unsure. It might be difficult to globally pull off if programs expect the binary to be placed in the source tree (for resources). [1]: https://github.com/CyberShadow/Digger
Re: Overfflow in Assert error messages
On Thursday, 13 February 2020 at 07:49:13 UTC, Adnan wrote: However my test fails saying something like: source/binary_search.d(33): [unittest] 18446744073709551615 != 1 core.exception.AssertError@source/binary_search.d(33): 18446744073709551615 != 1 What's causing this underflow? It's ulong -1, which is the type idx is of on 64-bit systems. On 32-bit systems it will be uint -1 and say "4294967295 != 0". indexOf is probably not doing what you think it's doing. int indexOf(T)(const T[] list, const T key) { return -1; } void main() { int[] arr = [ 0 ]; foreach (idx, i; arr) assert(indexOf(arr, i) == idx); // 18446744073709551615 != 0 }