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.
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: 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.
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: 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: 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: 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: 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: Nested delegates and closure allocations
On Tuesday, 16 January 2024 at 17:21:12 UTC, FeepingCreature wrote: Correct. [...] Thanks, I think I understand.
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?
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: 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.
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: 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: 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 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?
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: 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
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: 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: 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: 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
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: 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?
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: 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: 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: 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 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 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: 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.
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
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
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.
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: 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.
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: 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: 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: 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.
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: /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.
/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?
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.
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.
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.
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: 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.
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.
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: 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
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
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: 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
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
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: 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
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 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 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
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: 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
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 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 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 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 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 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
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
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` } ```
Re: FTP LS
On Sunday, 15 May 2022 at 19:13:10 UTC, ikod wrote: Added LIST command in v2.0.8 Thanks!
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: 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.
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 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: 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: 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: 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: Windows Msys terminal not flushing on newlines
On Sunday, 27 March 2022 at 18:09:30 UTC, Adam D Ruppe wrote: Normally the IOLBF thing does help there - that means line buffering - but my recommentation is to explicitly call `stdout.flush()` any time it is important in your code. Then you aren't depending on the relatively hidden config value. All right, thanks.
Windows Msys terminal not flushing on newlines
I installed Git for Windows which comes with the Msys terminal, and I noticed writeln lines aren't being flushed on linebreaks. I had this a long time ago and thought I fixed it with the following, but I guess I never confirmed that it actually worked. I'm not sure where I copied it from, a TWiD perhaps? ```d import std.stdio : stdout; import core.stdc.stdio : _IOLBF; stdout.setvbuf(4096, _IOLBF); // arbitrary number ``` Is this not the right way to go about things? At least for Msys it seemingly does nothing.
Example of Windows SSL with Secure Channel?
Does anyone have an example snippet code connecting to, reading from and writing to a server using SSL under Windows with Secure Channel? Something in a personal project you wouldn't mind sharing a part of to let me dissect? My project (IRC bot) supports connecting to a server using SSL, for which I'm currently using OpenSSL with [requests.ssl_adapter](https://github.com/ikod/dlang-requests/blob/master/source/requests/ssl_adapter.d). It's a simple thing that just sets up an SSL context, connects using the normal `Socket.connect`, establishes SSL, and then uses OpenSSL functions to read and write instead of Phobos' `Socket.{receive,send}`. It works, but unlike in Linux where OpenSSL is ubiquitous, on Windows you have to manually download and install OpenSSL from a third-party site. It still works, but it's not ideal. Frustratingly there is no `std.socket.ssl`. I'm helplessly a Linux creature and I don't know where to start. Does anyone have anything I could look at?
Re: dmd 2.099 regression: unittest -checkaction=context and import std.regex cause lots of undefined references
On Thursday, 17 March 2022 at 14:00:45 UTC, kdevel wrote: If ```import std.regex;``` is commented out or if ```-checkaction=context``` is removed from the cmd line the unittest passes. Can anybody reproduce this? https://run.dlang.io/is/GYDUBz File an issue, I'd say. The worst thing that can happen is that someone flags it as a duplicate.
Re: Detecting manifest contants
On Saturday, 12 March 2022 at 19:01:06 UTC, Paul Backus wrote: Typo: `.tupleof` I use `.tupleof` otherwise, but this is old stuff from when I didn't know of it. I'll have to refactor it some day, I had hoped for it to be just... not yet.
Detecting manifest contants
I'm introspecting structs, and I ran into an issue where `__traits(derivedMembers)` includes manifest constant enums in the returned tuple. What is the correct way to statically detect these? The immediate thing that springs to mind is `is(symbol == enum)`, but it's not it. Currently I'm testing if a function that takes the address of the member compiles, and I think it works, but like with everything `__traits(compiles)` it strikes me as it might not be the right way to go about things. ```d struct Foo { int i; enum k = 42; } void main() { foreach (memberstring; __traits(derivedMembers, Foo)) { static if (__traits(compiles, { Foo f; auto ptr = &__traits(getMember, f, memberstring); })) { // ... } } } ``` What else can I try?
Re: How to exclude function from being imported in D language?
On Tuesday, 8 March 2022 at 22:28:27 UTC, bauss wrote: On Tuesday, 8 March 2022 at 20:12:40 UTC, BoQsc wrote: I think D Language needs and lacks conditional compilation condition and attribute of "exclude". The exclude keyword or code block in the exclude, would be made sure to not be imported by any means. Now it seems all to be only workarounds. What D just needs is a way to specify the entry point, in which it just defaults to the first main function found, but could be any function given. I just place `main` in a separate skeletal `entrypoint.d` file that contains only it (and an import to the "main" `main.d`/`app.d`/whatever), so dub can safely exclude it in unittest builds without skipping any other tests I might have in the main file. ``` mainSourceFile "source/myproject/entrypoint.d" ``` ```d module myproject.entrypoint; int main(string[] args) { import myproject.main : run; return run(args); } ```
Re: How do I create a package?
On Saturday, 5 March 2022 at 15:30:19 UTC, M wrote: On Saturday, 5 March 2022 at 15:12:35 UTC, M wrote: THE DOCS ARE INADEQUATE TO THE TASK. I've created a directory bcm2835. Then within source/bcm2835 I have bcm2835.d. I run dub build, and file called libbcm2835.a gets built. I type dub list and it reports Packages present in the system and known to dub: ... bcm2835 ~master: /home/pi/repos/cerbo/dsp/dlang/bcm2835/ So, some kind of success, presumably. So then, in the app I want to build, I type dub add bcm2835 but it says Could not find package 'bcm2835'. So, dunno, any ideas? So I tried and I agree it's not intuitive. Once you've created a package `bcm2835` with `dub init`, you can add it to the local registry with `dub add-local /path/to/bcm2835`. ``` Registered package: bcm2835 (version: ~master) ``` This you already did, presumably, or something to the same effect. ``` Packages present in the system and known to dub: [...] bcm2835 ~master: /home/wob/src/test/bcm2835/ ``` Then you can add it to your `dub.sdl`/`dub.json` as a dependency with `dub add` *if and only if* you also specify a version. Else it will look it up in the online registry, find nothing, and fail. The help text in `dub add --help` briefly mentions it. ``` $ dub add bcm2835@"*" Adding dependency bcm2835 >=0.0.0 $ dub build Performing "debug" build using /usr/bin/dmd for x86_64. bcm2835 ~master: target for configuration "library" is up to date. test ~master: building configuration "application"... Linking... To force a rebuild of up-to-date targets, run again with --force. ```
Re: How do I create a package?
On Wednesday, 2 March 2022 at 16:38:58 UTC, M wrote: There doesn't seem to be any docs on how to actually create packages. Is there a description anywhere? https://dub.pm/getting_started.html is it, I think. It should get you started on creating a package, and then you have https://dub.pm/publish.html on how to register it.
Re: gcopt=fork:1
On Tuesday, 1 March 2022 at 21:32:07 UTC, Ali Çehreli wrote: Have you tried this new GC option which seems to solve the stop-the-world issue: https://dlang.org/changelog/2.098.0.html#forkgc Any experience? Ali It didn't work well for me; the process hung in `__memcpy_avx_unaligned_erms` when profiling under valgrind/callgrind, during the first collection. I tried and failed to reproduce it with a minimal example, so I didn't file an issue.
Re: curl error msg
On Saturday, 19 February 2022 at 13:12:32 UTC, MichaelBi wrote: when running the example in the std.net.curl on my windows, got following msg: std.net.curl.CurlException@std\net\curl.d(4239): Failed to load curl, tried "libcurl.dll", "curl.dll" does it mean i don't have those dll files? thx. Are you running it from a WSL session? I get libcurl.dll errors (although a graphical popup) when I run my thing from in there, but it works well from a normal command console and/or Powershell.
Re: Filling an array at compile time
On Wednesday, 9 February 2022 at 08:12:52 UTC, Vindex wrote: Will the loop (foreach) run at compile time? How can I make it work at compile time? ``` import std.csv, std.stdio; alias Record = Tuple!(string, string, string); immutable string[][] table; shared static this() { string csvText = import("file.csv"); foreach (record; csvReader!Record(csvText)) { table ~= [record[0], record[1], record[2]]; } } void main() { writeln(table): } ``` I would do this. ``` import std; alias Record = Tuple!(string, string, string); static immutable string[][] table = () { string[][] table; string csvText = import("file.csv"); foreach (record; csvReader!Record(csvText)) { table ~= [record[0], record[1], record[2]]; } return table; }(); pragma(msg, table); // Available at compile-time void main() { writeln(table); } ``` And then `-J{path}` to tell the compiler where to find `file.csv`. ``` dmd -J. csv.d ```
dustmite and Windows file access errors
This is maybe more a Windows (11) question than it is a dustmite one. Semi-OT. I'm trying to reduce https://forum.dlang.org/thread/muehtdyjabmjxosmj...@forum.dlang.org, and it's Windows so I don't know what I'm doing. After multiple attempts at piecing together a batch tester script that both checks for compiler stderr/stdout *and* the errorlevel of the process, I resigned and wrote a quick thing in D to do it instead. Off the top of my head; ```d import std; static immutable command = `ldc2.exe -flags and stuff copy/pasted from dub build -v output` .replace('\\', '/') .split(' '); int main() { immutable result = execute(command); return ((result.code == 5) && !result.output.length) ? 0 : 1; } ``` Once compiled it seems to work when called manually, and dustmite accepts it as a tester, but there are a lot of errors output to the console during actual reduction. Error while attempting to delete init.lookahead.3203: init.lookahead.3203\source\somefile.d: The process cannot access the file because it is being used by another process. Error while attempting to rename init.reduced.inprogress to init.reduced: Attempting to rename file init.reduced.inprogress to init.reduced: Access is denied. They occur *constantly*, and dustmite halts and waits a full second each time before retrying, sometimes with the same message repeated some 5 times. (Meaning access to the file was blocked for the same 5 seconds.) Indexing is off for the parent directory. What else can I do?
Re: ldc2 failed with exit code -1073741819.
On Tuesday, 18 January 2022 at 17:37:27 UTC, H. S. Teoh wrote: Bypassing dub and calling the raw ldc command gives no output. What else can I do? What does `echo $?` print immediately after you run the raw ldc command? T It exits with 5. I could look for that, certainly.
Re: ldc2 failed with exit code -1073741819.
On Tuesday, 18 January 2022 at 16:43:52 UTC, H. S. Teoh wrote: What's the dustmite command you used? In such cases, it's useful to check for this specific error message in your dustmite command, so that it doesn't reduce it past the actual problem case. T Yes, but the only thing I have to go on is dub reporting `-1073741819`, so I just made a script that grepped for that. ``` #!/bin/sh dub.exe build --compiler=ldc2 2>&1 | grep "ldc2 failed with exit code -1073741819" ``` It was not unique enough an error and I ended up with some empty files that didn't import each other correctly. ``` source\kameloso\plugins\twitchbot\keygen.d(1,8): Error: module `kameloso.plugins.twitchbot` from file source\kameloso\plugins\twitchbot\base.d must be imported with 'import kameloso.plugins.twitchbot;' [...] ldc2 failed with exit code -1073741819. ``` Bypassing dub and calling the raw ldc command gives no output. What else can I do?
ldc2 failed with exit code -1073741819.
I did a big sweep through my project and changed all `writefln`s and `format`s and the such to take their format patterns as compile-time parameters, and now ldc can no longer build it on Windows. It works on linux, and dmd has no problems with it. There is no error message beyond "failed with exit code -1073741819", which is not unique enough to be able to dustmite on. (It reduced it to a practically empty set with a different error.) Manually running the command listed by `dub build -v` fails with no output at all and simply returns a shell exit code of 5. ``` git clone https://github.com/zorael/kameloso.git -b ctpatterns cd kameloso dub build --compiler=ldc2 ``` What can I *reasonably* do here? Do I *have* to compile LDC from source, to get debug symbols? How else can I reduce it when it doesn't say what goes wrong?
Re: How to properly use variadic templates (functions)?
On Tuesday, 21 December 2021 at 06:44:36 UTC, rempas wrote: This will not do for me because I want to do formatted output and I need the index. But thanks a lot for tying to help! I'm not certain I understand, but won't `foreach (i, a; args) { /* ... */ }` in his example do that? As in, if you necessarily must index `args` instead of using a foreach variable, ```d import core.stdc.stdio : putc, stdout; void print(T...)(string prompt, T args) { foreach (i, a; args) { alias A = typeof(args[i]); static if (is(A : string)) { for (int j = 0; j < args[i].length; j++) { putc(args[i][j], stdout); } } else { // handle your other types print("", A.stringof); } } } void main() { print("Prompt (ignored)", "Hello", " world!\n", 123); } ```
Re: String "dequote" in phobos?
On Thursday, 13 May 2021 at 14:10:08 UTC, cc wrote: Does something to dequote (unquote? or what would you call it?) a string exist in the standard library? I didn't see one in std.string, just wondering before reinventing the wheel. Something like: ```d assert(dequote(`"foo"`) == "foo"); assert(dequote(`'foo'`) == "foo"); assert(dequote(`"foo's"`) == "foo's"); assert(dequote(`'foo "bar"'`) == `foo "bar"`); assert(dequote(`"fo\"o"`) == `fo"o`); dequote(`"fo"o"`); // bad quoting, maybe throw an exception here or something? ``` I called mine `unquoted`[1] and `unsinglequoted`. Not very imaginative, I concede. I also assumed ASCII and fearlessly sliced `line[1..$-1]`, which you may or may not be able to do. ```d private T unenclosed(char token = '"', T)(const T line) pure nothrow @nogc if (isSomeString!T) { enum escaped = "\\" ~ token; if (line.length < 2) { return line; } else if ((line[0] == token) && (line[$-1] == token)) { if ((line.length >= 3) && (line[$-2..$] == escaped)) { // End quote is escaped return line; } return line[1..$-1].unenclosed!token; } else { return line; } } pragma(inline, true) T unquoted(T)(const T line) pure nothrow @nogc { return unenclosed!'"'(line); } unittest { assert(`"Lorem ipsum sit amet"`.unquoted == "Lorem ipsum sit amet"); assert(`"Lorem ipsum sit amet"`.unquoted == "Lorem ipsum sit amet"); // Unbalanced quotes are left untouched assert(`"Lorem ipsum sit amet`.unquoted == `"Lorem ipsum sit amet`); assert(`"Lorem \"`.unquoted == `"Lorem \"`); assert("\"Lorem \\\"".unquoted == "\"Lorem \\\""); assert(`"\"`.unquoted == `"\"`); } pragma(inline, true) T unsinglequoted(T)(const T line) pure nothrow @nogc { return unenclosed!'\''(line); } // ... ``` I'm not sure it's quite correct for all valid inputs but it worked well enough for my purposes. [1]: http://lu.dpldocs.info/lu.string.unquoted.html
Re: Creating std.format.format warpper
On Saturday, 1 May 2021 at 09:10:09 UTC, novice2 wrote: Hello. Can please anybody help me create template format2 like std.format.format, so it can access to format string (change it for example) then instantiate std.format.format template in compile-time-checkable way Since `std.format.format` already does this, just create templates that simply pass on their arguments to it and let it validate them. "Prefixing" the format pattern is trivially done (in a separate template) before deferring to `format`. https://run.dlang.io/is/QsYCkq If you're not familiar with templates and the difference between compile-time and runtime parameters, there are several good write-ups, such as the template chapter of Ali Çehreli's book (which is available online at http://ddili.org/ders/d.en/templates.html).
Re: is it posible to compile individual module separately?
On Tuesday, 16 February 2021 at 18:54:08 UTC, Paul Backus wrote: I stand corrected. Shouldn't have trusted the documentation so much, I guess. It makes perfect sense to intuit that --single should be related to --build-mode=singleFile. As it is the build modes aren't explained in the documentation at all[1], so there's no way of knowing, short of running it to see what happens. Not ideal, perhaps. --build-mode= Specifies the way the compiler and linker are invoked. Valid values: separate (default), allAtOnce, singleFile (Nothing about what they do.) [1]: https://dub.pm/commandline
Re: is it posible to compile individual module separately?
On Tuesday, 16 February 2021 at 17:26:06 UTC, Paul Backus wrote: On Tuesday, 16 February 2021 at 17:15:25 UTC, Anonymouse wrote: You can also use dub build --build-mode=singleFile, and it will compile one file at a time. It'll be slow but slow is better than OOM. singleFile is for single-file packages [1]. The option you're thinking of is --build-mode=separate. [1] https://dub.pm/advanced_usage.html#single-file No, I do mean singleFile. $ dub build --build-mode=singleFile --force Performing "debug" build using /usr/local/bin/ldc2 for x86_64. arsd-official:characterencodings 9.1.2: building configuration "library"... Compiling ../../.dub/packages/arsd-official-9.1.2/arsd-official/characterencodings.d... Linking... arsd-official:dom 9.1.2: building configuration "library"... Compiling ../../.dub/packages/arsd-official-9.1.2/arsd-official/dom.d... Linking... lu 1.1.2: building configuration "library"... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/common.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/container.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/conv.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/deltastrings.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/json.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/meld.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/numeric.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/objmanip.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/package.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/semver.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/serialisation.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/string.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/traits.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/typecons.d... Compiling ../../.dub/packages/lu-1.1.2/lu/source/lu/uda.d... Linking... dialect 1.1.1: building configuration "library"... Compiling ../../.dub/packages/dialect-1.1.1/dialect/source/dialect/common.d... Compiling ../../.dub/packages/dialect-1.1.1/dialect/source/dialect/defs.d... Compiling ../../.dub/packages/dialect-1.1.1/dialect/source/dialect/package.d... Compiling ../../.dub/packages/dialect-1.1.1/dialect/source/dialect/parsing.d... Compiling ../../.dub/packages/dialect-1.1.1/dialect/source/dialect/postprocessors/package.d... Compiling ../../.dub/packages/dialect-1.1.1/dialect/source/dialect/postprocessors/twitch.d... Compiling ../../.dub/packages/dialect-1.1.1/dialect/source/dialect/semver.d... Linking... cachetools 0.3.1: building configuration "library"... Compiling ../../.dub/packages/cachetools-0.3.1/cachetools/source/cachetools/cache.d... Compiling ../../.dub/packages/cachetools-0.3.1/cachetools/source/cachetools/cache2q.d... Compiling ../../.dub/packages/cachetools-0.3.1/cachetools/source/cachetools/cachelru.d... Compiling ../../.dub/packages/cachetools-0.3.1/cachetools/source/cachetools/containers/hashmap.d... ^C