Re: Setting field of struct object
On Monday, 22 January 2024 at 08:54:21 UTC, Danilo wrote: On Monday, 22 January 2024 at 08:35:01 UTC, Joel wrote: [...] Nonetheless, this usually used with Objects (new class/struct instances), like so: ```d import std; [...] Fluent Interface
Re: FIFO
On Monday, 13 May 2024 at 15:07:39 UTC, Andy Valencia wrote: On Sunday, 12 May 2024 at 22:03:21 UTC, Ferhat Kurtulmuş wrote: https://dlang.org/phobos/std_container_slist.html This is a stack, isn't it? LIFO? Ahh yes. Then use dlist Thank you. I read its source, and was curious so I wrote a small performance measurement: put 10,000 things in a FIFO, pull them back out, and loop around that 10,000 times. My FIFO resulted in: Also try the code I gave in this thread: https://forum.dlang.org/post/fgzvdhkdyevtzznya...@forum.dlang.org In fact, please use this facility in the standard library: https://dlang.org/phobos/std_datetime_stopwatch.html#benchmark SDB@79
Re: FIFO
On Monday, 13 May 2024 at 15:07:39 UTC, Andy Valencia wrote: On Sunday, 12 May 2024 at 22:03:21 UTC, Ferhat Kurtulmuş wrote: https://dlang.org/phobos/std_container_slist.html This is a stack, isn't it? LIFO? Ahh yes. Then use dlist Thank you. I read its source, and was curious so I wrote a small performance measurement: put 10,000 things in a FIFO, pull them back out, and loop around that 10,000 times. My FIFO resulted in: real0m1.589s user0m1.585s sys 0m0.004s And the dlist based one: real0m4.731s user0m5.211s sys 0m0.308s Representing the FIFO as a linked list clearly has its cost, but I found the increased system time interesting. OS memory allocations maybe? The code is spaghetti, fifo/dlist, but it seemed the easiest way to see the two API's being used side by side: version(fifo) { import tiny.fifo : FIFO; } else { import std.container.dlist : DList; } const uint ITERS = 10_000; const uint DEPTH = 10_000; void main() { version(fifo) { auto d = FIFO!uint(); } else { auto d = DList!uint(); } foreach(_; 0 .. ITERS) { foreach(x; 0 .. DEPTH) { version(fifo) { d.add(x); } else { d.insertBack(x); } } foreach(x; 0 .. DEPTH) { version(fifo) { assert(x == d.next()); } else { assert(x == d.front()); d.removeFront(); } } } } thank you for sharing the results. Everything I read about queues recommends doublylinked lists. With your array based implementatio if you are consuming the elements faster than pushing new elements, your array buffer never resize which is costly. This should explain why your array based queue is more performant.
Re: FIFO
On Monday, 13 May 2024 at 15:07:39 UTC, Andy Valencia wrote: Representing the FIFO as a linked list clearly has its cost, but I found the increased system time interesting. OS memory allocations maybe? I know you want FIFO, I usually keep this on hand for fixed size LIFO; It can easily convert to FIFO and doesn't use LinkedList: ```d class LIFO(T) { T * element; size_t length, size; this(size_t s) { element = cast(T*)new T[s]; length = s; } auto rewind() => size = length; bool empty() => !size; auto front() => element[size - 1]; auto popFront() => --size; auto pop() => empty ? T(0) : element[--size]; alias push = insertFront; auto insertFront(T value) in(size < length, "Stack is overflow!") => element[size++] = value; auto ref opDollar() => length; auto ref opIndex(size_t i) => element[i]; auto ref opSlice(size_t first, size_t last) => element[first..last]; } unittest { enum test = 7; auto stack = new LIFO!size_t(test); assert(!stack.size); foreach (prime; 1..test + 1) { stack.insertFront(prime); } assert(stack.size == test); // == 7 stack.writeln(": ", stack.length); // [7, 6, 5, 4, 3, 2, 1]: 7 stack[$/2].writeln("-", stack[0]); // 4-1 stack.rewind(); stack.size.write(": ["); // 10: while (auto next = stack.pop) { if (next == 1) next.writeln("]"); else next.write(", "); } stack.size.writeln; // 0 stack.rewind(); assert(stack.size == test); } SDB@79
Re: FIFO
On Sunday, 12 May 2024 at 22:03:21 UTC, Ferhat Kurtulmuş wrote: https://dlang.org/phobos/std_container_slist.html This is a stack, isn't it? LIFO? Ahh yes. Then use dlist Thank you. I read its source, and was curious so I wrote a small performance measurement: put 10,000 things in a FIFO, pull them back out, and loop around that 10,000 times. My FIFO resulted in: real0m1.589s user0m1.585s sys 0m0.004s And the dlist based one: real0m4.731s user0m5.211s sys 0m0.308s Representing the FIFO as a linked list clearly has its cost, but I found the increased system time interesting. OS memory allocations maybe? The code is spaghetti, fifo/dlist, but it seemed the easiest way to see the two API's being used side by side: version(fifo) { import tiny.fifo : FIFO; } else { import std.container.dlist : DList; } const uint ITERS = 10_000; const uint DEPTH = 10_000; void main() { version(fifo) { auto d = FIFO!uint(); } else { auto d = DList!uint(); } foreach(_; 0 .. ITERS) { foreach(x; 0 .. DEPTH) { version(fifo) { d.add(x); } else { d.insertBack(x); } } foreach(x; 0 .. DEPTH) { version(fifo) { assert(x == d.next()); } else { assert(x == d.front()); d.removeFront(); } } } }
Re: What prevents ImportC from using .h directly?
On Sunday, 12 May 2024 at 21:34:30 UTC, Chris Piker wrote: So, why does ImportC need *.c files exclusively? I'm sure it solves a problem, but I don't know what that problem is. Support for headers has been worked on, but had to be reverted: https://issues.dlang.org/show_bug.cgi?id=23479
Re: Find homography in D?
On Sunday, 21 April 2024 at 14:57:33 UTC, Paolo Invernizzi wrote: Hi, Someone can point me to a D implementation of the classical OpenCV find homography matrix? Thank you, Paolo Now, we can do image stitching using DCV. It needs improvements though. https://github.com/libmir/dcv/tree/master/examples/imagestitchinghomography
Re: FIFO
On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote: I need a FIFO for a work scheduler, and nothing suitable jumped out at me. I wrote the following, but as a newbie, would be happy to receive any suggestions or observations. TIA! [...] I don't know your use case, maybe you have a similar problem I had to solve years ago. https://forum.dlang.org/post/xktftztisodpngcow...@forum.dlang.org
Re: FIFO
On Sunday, 12 May 2024 at 21:08:24 UTC, Andy Valencia wrote: On Sunday, 12 May 2024 at 19:45:44 UTC, Ferhat Kurtulmuş wrote: On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote: I need a FIFO for a work scheduler, and nothing suitable jumped out at me. ... https://dlang.org/phobos/std_container_slist.html This is a stack, isn't it? LIFO? Andy Ahh yes. Then use dlist
What prevents ImportC from using .h directly?
Hi D Import D is working quite well so far. One limitation is that module definitions require a tiny *.c file which is often just: ```C #include ``` Creating this file is trivial and has almost no knock-on effects, except when dealing with single file programs. I have quite a few small utilities with dub headers. It would be handy if I could set an import path and use ImportC on the header file directly, skipping the small C file all together. A specific example in my case follows. Given a C-lib interface defined in the header file: ``` /usr/include/cspice/SpiceUsr.h ``` it would be neat if a dub header similar to the following worked: ```d #!/usr/bin/env dub /+ dub.sdl: name "some_app" cImportPaths "/usr/local/include/cspice" +/ import SpiceUsr; // ... source continues ``` So, why does ImportC need *.c files exclusively? I'm sure it solves a problem, but I don't know what that problem is.
Re: FIFO
On Sunday, 12 May 2024 at 19:45:44 UTC, Ferhat Kurtulmuş wrote: On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote: I need a FIFO for a work scheduler, and nothing suitable jumped out at me. ... https://dlang.org/phobos/std_container_slist.html This is a stack, isn't it? LIFO? Andy
Anybody know about SDL and particularly SDL_TTF initialization?
This should be trivial, right? I've been looking at existing D repo code for hours. Can't figure why TTF_Init doesn't work? It would help if I could figure out how to use SDL_GetError() INFO: SDL loaded v2.30.2 INFO: SDL initialized: 0 INFO: TTF loaded: v2.0.14 Error Program exited with code -1073741819 loadSDL(); SDL_version v; SDL_GetVersion(); toStdout("SDL loaded v%d.%d.%d", v.major, v.minor, v.patch); auto initSDL = SDL_Init(SDL_INIT_EVERYTHING); // returns 0 on success toStdout("SDL initialized: %d", initSDL); auto loadTTF = loadSDLTTF(); SDL_TTF_VERSION(); toStdout("TTF loaded: v%d.%d.%d", v.major, v.minor, v.patch); auto initTTF = TTF_Init(); // SDL must be initialized before calls to this library
Re: FIFO
On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote: I need a FIFO for a work scheduler, and nothing suitable jumped out at me. I wrote the following, but as a newbie, would be happy to receive any suggestions or observations. TIA! [...] "next" is not a usual range primitive word in dlang. Why not just using slist.
Re: FIFO
On Saturday, 11 May 2024 at 23:44:28 UTC, Andy Valencia wrote: I need a FIFO for a work scheduler, and nothing suitable jumped out at me. I wrote the following, but as a newbie, would be happy to receive any suggestions or observations. TIA! [...] https://dlang.org/phobos/std_container_slist.html
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
A horrible alternative would be to use `alias` on `size_t` to make up a new pseudo-type that is more aligned with the code logic. ``` alias integer = size_t; import std.stdio : writefln; void main() { auto arr = [ [5, 15], // 20 [2, 3, 2, 3], // 10 [3, 6, 2, 9], // 20 ]; foreach (integer i, row; arr) { double total = 0.0; foreach (e; row) total += e; auto avg = total / row.length; writefln("AVG [row=%d]: %.2f", i, avg); } } ```
FIFO
I need a FIFO for a work scheduler, and nothing suitable jumped out at me. I wrote the following, but as a newbie, would be happy to receive any suggestions or observations. TIA! /* * fifo.d * FIFO data structure */ module tiny.fifo; import std.exception : enforce; const uint GROWBY = 16; /* * This is a FIFO, with "hd" walking forward and "tl" trailing * behind: *tl hd /Add here next *v v * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 * * Mildly complicated by a module-size indexing. */ struct FIFO(T) { T[] items; ulong hd, tl, length; void add(T t) { // Make more room when needed if (this.items.length == this.length) { assert(this.hd == this.tl); // Add room and shuffle current contents auto olen = this.items.length; auto newlen = olen + GROWBY; this.items.length = newlen; this.tl = (this.tl + GROWBY) % newlen; // Shuffle what we're butted up against to their // new position at the top of this.items[] ulong moved = olen - this.hd; this.items[$ - moved .. $] = this.items[this.hd .. this.hd + moved]; } // Add item at next position this.items[hd] = t; this.hd = (this.hd + 1) % this.items.length; this.length += 1; } // Give back next T next() { enforce(this.length > 0, "next() from empty FIFO"); this.length -= 1; auto res = this.items[this.tl]; this.tl = (this.tl + 1) % this.items.length; return res; } } unittest { auto f = FIFO!uint(); f.add(1); f.add(2); f.add(3); assert(f.next() == 1); assert(f.next() == 2); assert(f.next() == 3); assert(f.length == 0); // Now overflow several times f = FIFO!uint(); foreach(x; 0 .. GROWBY * 3 + GROWBY/2) { f.add(x); } foreach(x; 0 .. GROWBY * 3 + GROWBY/2) { assert(f.next() == x); } assert(f.length == 0); } version(unittest) { void main() { } }
Re: How to load a DLL file in D?
On Saturday, 11 May 2024 at 20:04:38 UTC, Lance Bachmeier wrote: On Saturday, 11 May 2024 at 19:33:03 UTC, solidstate1991 wrote: I know that BindBC exists and otherwise would use it, but the bigger the library, the more extra hurdle it'll have. When I did a few bindings with it, I had to order the functions the right way, so I could do things much quicker with the Ctrl+Alt+Shift trick under VSCode, and even then having to write both a statically linked and dynamically linked version (the latter which required the functions to be loaded individually into function pointers). Maybe I should write some automation tool... You might find this package useful https://code.dlang.org/packages/dynamic Also relevant if they're C functions: https://forum.dlang.org/post/qxctappnigkwvaqak...@forum.dlang.org And this if you want to convert C headers to D code: https://forum.dlang.org/post/ugvc3o$5t3$1...@digitalmars.com
Re: How to load a DLL file in D?
On Saturday, 11 May 2024 at 19:33:03 UTC, solidstate1991 wrote: I know that BindBC exists and otherwise would use it, but the bigger the library, the more extra hurdle it'll have. When I did a few bindings with it, I had to order the functions the right way, so I could do things much quicker with the Ctrl+Alt+Shift trick under VSCode, and even then having to write both a statically linked and dynamically linked version (the latter which required the functions to be loaded individually into function pointers). Maybe I should write some automation tool... You might find this package useful https://code.dlang.org/packages/dynamic
Re: Why is Phobos `Flag` so overthought ?
On Thursday, 9 May 2024 at 18:48:12 UTC, Nick Treleaven wrote: We have a tool in our box already called `true` and that solves the problem. If we had to type out the full name of every argument passed to every function ever written we may as well just adopt ObjC Cocoa style and call it StopWatchWithAutoStartBool(). Strawman. Not at all. I mean exactly that. Why do you believe this function is so important it needs to have its argument type explicitly stated, when most functions don't? Either that, or you believe all functions should. It's arbitrary and pointless.
Re: "in" operator gives a pointer result from a test against an Associative Array?
On Friday, 10 May 2024 at 16:33:53 UTC, Nick Treleaven wrote: Arrays evaluate to true in boolean conditions if their `.ptr` field is non-null. This is bug-prone and I hope we can remove this in the next edition. ... A string literal's `.ptr` field is always non-null, because it is null-terminated. Thank you! Andy
Re: "in" operator gives a pointer result from a test against an Associative Array?
On Friday, 10 May 2024 at 15:23:39 UTC, Andy Valencia wrote: On Friday, 10 May 2024 at 03:07:43 UTC, Steven Schveighoffer wrote: Yes, we say that a type has "truthiness" if it can be used in a condition (`while`, `if`, `assert`, etc). So if I may ask for one more small clarification... WRT "truthiness", I've observed that empty arrays are treated as false, non-empty as true. Arrays evaluate to true in boolean conditions if their `.ptr` field is non-null. This is bug-prone and I hope we can remove this in the next edition. However, although I thought a string was basically an immutable array of characters, "" is treated as true, not false? A string literal's `.ptr` field is always non-null, because it is null-terminated.
Re: "in" operator gives a pointer result from a test against an Associative Array?
On Friday, 10 May 2024 at 03:07:43 UTC, Steven Schveighoffer wrote: Yes, we say that a type has "truthiness" if it can be used in a condition (`while`, `if`, `assert`, etc). So if I may ask for one more small clarification... WRT "truthiness", I've observed that empty arrays are treated as false, non-empty as true. However, although I thought a string was basically an immutable array of characters, "" is treated as true, not false? Thanks again, Andy
Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?
On Friday, 10 May 2024 at 13:27:40 UTC, Dukc wrote: Steven Schveighoffer kirjoitti 10.5.2024 klo 16.01: On Friday, 10 May 2024 at 11:05:28 UTC, Dukc wrote: This also gets inferred as `pure` - meaning that if you use it twice for the same `WeakRef`, the compiler may reuse the result of the first dereference for the second call, without checking whether the referred value has changed! This would be weak pure since the reference is mutable. This cannot be memoized. The difference is the type. With a pointer parameter (both a bare one and one in a struct), the compiler can cache the result only when the pointed data is similar. However, here we have an integer parameter. It can be cached if it itself is similar to the one in the other function call. The compiler doesn't have to know, nor can know, when a `size_t` is a pointer in disguise. This why I would just use ref counting if I were the topic author, trying to be smart will often comes back when one doesn't expect. And as stated by previous author if the goal is to have self-clearable weak reference it will need some infrastructure anyway, so tbh this will greatly outweight any possible benefits of having weak refs.
Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?
Steven Schveighoffer kirjoitti 10.5.2024 klo 16.01: On Friday, 10 May 2024 at 11:05:28 UTC, Dukc wrote: This also gets inferred as `pure` - meaning that if you use it twice for the same `WeakRef`, the compiler may reuse the result of the first dereference for the second call, without checking whether the referred value has changed! This would be weak pure since the reference is mutable. This cannot be memoized. The difference is the type. With a pointer parameter (both a bare one and one in a struct), the compiler can cache the result only when the pointed data is similar. However, here we have an integer parameter. It can be cached if it itself is similar to the one in the other function call. The compiler doesn't have to know, nor can know, when a `size_t` is a pointer in disguise.
Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?
On Friday, 10 May 2024 at 11:05:28 UTC, Dukc wrote: This also gets inferred as `pure` - meaning that if you use it twice for the same `WeakRef`, the compiler may reuse the result of the first dereference for the second call, without checking whether the referred value has changed! This would be weak pure since the reference is mutable. This cannot be memoized. -Steve
Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?
evilrat kirjoitti 9.5.2024 klo 18.19: ```d struct WeakRef(T) { private size_t _handle; // same size as a pointer this(T* ptr) { _handle = cast(size_t) ptr; } T* getRef() { return cast(T*) _handle; } // do the rest ... } ``` [1] https://code.dlang.org/packages/automem There is a hidden danger with using this struct. Since `getRef` is a template, it will be inferred as `pure`. Now, consider a function using it: ```D auto derefer(WeakrefT)(WeakrefT wr) => *wr.getRef; ``` This also gets inferred as `pure` - meaning that if you use it twice for the same `WeakRef`, the compiler may reuse the result of the first dereference for the second call, without checking whether the referred value has changed! You probably should add some never-executed dummy operation to `getRef` that prevents it from becoming `pure` if you go with this design.
Re: moving from classical lex/yacc to pegged parser
Dmitry Ponyatov kirjoitti 9.5.2024 klo 11.30: > And I also can't figure out how to inherit `ParseTree` with all my script language objects to get AST right from pegged parser. Should I use some superloop with lot of matches to process parsed `pt` tree into something I need myself, to drop all unneeded parsing meta info and get clean semantic AST? Pegged can help you with that filtering part, at least to some extent. Remember you can use : and ; prefix operators in the grammar spec, and Pegged will drop the needless nodes for you. Or do the reverse, use ^ prefix operator (or write a new rule) to make a node out of Pegged builtins.
Re: "in" operator gives a pointer result from a test against an Associative Array?
On Friday, 10 May 2024 at 01:00:09 UTC, Andy Valencia wrote: On Friday, 10 May 2024 at 00:40:01 UTC, Meta wrote: Yes. The reason for this is that it avoids having to essentially do the same check twice. If `in` returned a bool instead of a pointer, after checking for whether the element exists (which requires searching for the element in the associative array), you'd then have to actually *get* it from the array, which would require searching again. Returning a pointer to the element if it exists (or `null` if it doesn't) cuts this down to 1 operation. Looking at Programming in D section 28.5, I'm guessing that pointer versus null is treated as the appropriate boolean value when consumed by an "if" test. So that example is getting a pointer to a string, or null, but the example looks exactly as the same as if it had directly gotten a bool. Yes, we say that a type has "truthiness" if it can be used in a condition (`while`, `if`, `assert`, etc). For a pointer, `null` is considered "false", whereas any other value is considered "true". So you can use statements like `if(key in aa)` to test for membership. A very nice idiom is to check if a key is in an associative array, and if so, use the value that it maps to: ```d if(auto v = key in aa) { // use *v as the value here } ``` You can change your code to `return (e in this.members) !is null;` -Steve
Re: "in" operator gives a pointer result from a test against an Associative Array?
On Friday, 10 May 2024 at 00:40:01 UTC, Meta wrote: Yes. The reason for this is that it avoids having to essentially do the same check twice. If `in` returned a bool instead of a pointer, after checking for whether the element exists (which requires searching for the element in the associative array), you'd then have to actually *get* it from the array, which would require searching again. Returning a pointer to the element if it exists (or `null` if it doesn't) cuts this down to 1 operation. Looking at Programming in D section 28.5, I'm guessing that pointer versus null is treated as the appropriate boolean value when consumed by an "if" test. So that example is getting a pointer to a string, or null, but the example looks exactly as the same as if it had directly gotten a bool. Thank you! Andy
Re: "in" operator gives a pointer result from a test against an Associative Array?
On Friday, 10 May 2024 at 00:18:16 UTC, Andy Valencia wrote: tst7.d(6): Error: cannot implicitly convert expression `e in this.members` of type `bool*` to `bool` tst7.d(15): Error: template instance `tst7.Foo!uint` error instantiating I'm getting this for this bit of source (trimmed from the bigger code). I switched to this.members.get(e, false) and that works fine, but I'm still curious: struct Foo(T) { bool[T] members; bool has(T e) { return (e in this.members); } } void main() { import std.stdio : writeln; auto t = Foo!uint(); writeln(t.has(123)); } Yes. The reason for this is that it avoids having to essentially do the same check twice. If `in` returned a bool instead of a pointer, after checking for whether the element exists (which requires searching for the element in the associative array), you'd then have to actually *get* it from the array, which would require searching again. Returning a pointer to the element if it exists (or `null` if it doesn't) cuts this down to 1 operation.
"in" operator gives a pointer result from a test against an Associative Array?
tst7.d(6): Error: cannot implicitly convert expression `e in this.members` of type `bool*` to `bool` tst7.d(15): Error: template instance `tst7.Foo!uint` error instantiating I'm getting this for this bit of source (trimmed from the bigger code). I switched to this.members.get(e, false) and that works fine, but I'm still curious: struct Foo(T) { bool[T] members; bool has(T e) { return (e in this.members); } } void main() { import std.stdio : writeln; auto t = Foo!uint(); writeln(t.has(123)); }
Re: Why is Phobos `Flag` so overthought ?
On Wednesday, 8 May 2024 at 10:24:07 UTC, Nick Treleaven wrote: Named arguments are optional, so I don't see how they could make Flag redundant. Actually, an external tool could detect when a bool is passed as an argument to a function and warn when not done with a named argument. This would free library APIs from having to use Flag when some users don't care about it. The cost would come in a bit more build system complexity/build time, which might mean a lot less enforcement due to inertia. Though maybe a reasonable trade-off.
Re: Why is Phobos `Flag` so overthought ?
On Thursday, 9 May 2024 at 13:40:56 UTC, cc wrote: It's pointless mandatory verbosity. StopWatch ctor only takes one boolean argument. It doesn't *need* to specify what it relates to. You either already know, or you have to look it up anyway. Flags made sense when you might get the order of multiple bools confused, but if there's only one, *or* if you can use named arguments to avoid ambiguity, So you have justified Flag. there's no point in demanding every parameter be a unique type. It's easy to remember I can pass a bool to a StopWatch to autostart it. But perhaps true means manual start? Remembering can also be used to justify dynamic typing outside of hot loops, I'd rather not rely on remembering with a big team of programmers working on a project. It's less easy to remember that a specific unique type needs to be used, and remembering whether the name/casing of that type was Start, StartNow, StartAuto, Autostart, AutoStart, autostart, autoStart, etc. So just pass it true, and run the compiler. The compiler will tell you what the correct type is. We have a tool in our box already called `true` and that solves the problem. If we had to type out the full name of every argument passed to every function ever written we may as well just adopt ObjC Cocoa style and call it StopWatchWithAutoStartBool(). Strawman.
Re: D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?
On Thursday, 9 May 2024 at 00:39:49 UTC, Liam McGillivray wrote: What's a good way I can achieve what I'm trying to do, using either reference counting or a garbage-collected object? There is libraries like `automem`[1] that implements refcounting and more. Without showing your code for ref counted struct we can't help you. As for weak references, maybe you could "trick" the GC by using the fact that simple types are not scanned, i.e. do something like this but I have no idea if this is going to work at all, alternatively you can also try using `ubyte[size_t.sizeof]`. Keep in mind that classes is already references so you don't need that extra pointer for classes, can be versioned with template specialization. ```d struct WeakRef(T) { private size_t _handle; // same size as a pointer this(T* ptr) { _handle = cast(size_t) ptr; } T* getRef() { return cast(T*) _handle; } // do the rest ... } ``` [1] https://code.dlang.org/packages/automem
Re: Why is Phobos `Flag` so overthought ?
On Wednesday, 8 May 2024 at 10:24:07 UTC, Nick Treleaven wrote: On Wednesday, 8 May 2024 at 04:27:13 UTC, cc wrote: It doesn't allow a simple boolean to be used as an argument, or any other Flag as they are different instantiations of a template rather than equivalent aliases. It is however awful, cumbersome, annoying design and needs to be completely phased out now that we have named arguments. Flag enforces that the argument says what it relates to. `true` does not say what it relates to. Named arguments are optional, so I don't see how they could make Flag redundant. It's pointless mandatory verbosity. StopWatch ctor only takes one boolean argument. It doesn't *need* to specify what it relates to. You either already know, or you have to look it up anyway. Flags made sense when you might get the order of multiple bools confused, but if there's only one, *or* if you can use named arguments to avoid ambiguity, there's no point in demanding every parameter be a unique type. It's easy to remember I can pass a bool to a StopWatch to autostart it. It's less easy to remember that a specific unique type needs to be used, and remembering whether the name/casing of that type was Start, StartNow, StartAuto, Autostart, AutoStart, autostart, autoStart, etc. We have a tool in our box already called `true` and that solves the problem. If we had to type out the full name of every argument passed to every function ever written we may as well just adopt ObjC Cocoa style and call it StopWatchWithAutoStartBool().
moving from classical lex/yacc to pegged parser
Using lex/yacc I can do a more or less complex things in .yacc semantic actions, such complex as bytecode compilation or real CPU assembly. Playing with `pegged`, I can't figure out how to move from `ParseTree` to such like semantic actions. I even can't parse numbers from strings in lexer-like rules because it looks like every rule runs on any token parse, or sumething like this. Also, I use attribute object trees resemble attribute grammar both for parsing and internal code representation: ```C++ class Object { string value; // or `int value` and `float value` for numbers map attr; vector nested; } ``` And I also can't figure out how to inherit `ParseTree` with all my script language objects to get AST right from pegged parser. Should I use some superloop with lot of matches to process parsed `pt` tree into something I need myself, to drop all unneeded parsing meta info and get clean semantic AST?
D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?
A "weak reference" (in the sense that I'm referring to) is a feature in some programming languages for a reference to an object that doesn't prevent the GC from destroying that object. My current understanding is that D doesn't have weak references, though I've found some posts in this forum from many years back that mention something called "weakref". So is weakref a real thing, or just a concept that never got implemented? The functionality that I'm going to describe would be easy with weak references, but I don't know how I would implement it without it. If there is a way to implement it without it, I would like to know how. I am going to describe my specific example, but it may apply to any class that's initialized using contents of a file without any of that data being modified after. In my particular case, the class I've created is a wrapper for the `Texture2D` struct in Raylib. This class holds an image that was loaded from a file. ``` Sprite[string] spritesByPath; Sprite getSprite(string path) { path = path.asAbsolutePath; if (path !in spritesByPath) { spritesByPath[path] = new Sprite(path); } return spritesByPath[path]; } class Sprite { Texture2D texture; alias this = texture; string path; this(string path) { texture = LoadTexture(path.toStringz); this.path = path; } ~this() { if (IsWindowReady) UnloadTexture(texture); if (path in spritesByPath) spritesByName.remove(path); } } ``` Alternatively, `spritesByPath` and `getSprite` may be static members of `Sprite`. If D had weak references, than `spritesByPath` would be made of weak references so that they don't prevent the destruction of `Sprite` objects, which should be destroyed whenever they don't have any references elsewhere. I've considered making `Sprite` reference-counted, but I couldn't manage to figure out how to do it properly. I tried doing `SafeRefCounted!Sprite` but the compiler said it doesn't work on `Object` types. I then tried making my own struct for reference counting that would be placed in place of a direct reference to the `Sprite` object, but there was some bug in which sometimes it didn't increment the reference count, so it didn't work. What's a good way I can achieve what I'm trying to do, using either reference counting or a garbage-collected object?
Re: How can I put the current value of a variable into a delegate?
On Wednesday, 8 May 2024 at 12:29:05 UTC, Rene Zwanenburg wrote: Interestingly enough C# used to have the same behaviour but MS decided to go for a breaking change in C# 5; now it behaves as most people expect. Wow! I wonder if D would be willing to allow such a breaking change with the release of Phobos 3. My choice would be to have it use the current value by default for value types, but allow them to be linked to the same memory address using `*&` when the variable is placed in a delegate. I think that the distinction between value types and reference types should be consistent. If such a breaking change isn't considered acceptable, I suppose a new operator can be introduced for dereferencing a variable when placed in a delegate. Maybe `#` or `$` if they don't conflict with any existing use of those symbols.
Re: How can I put the current value of a variable into a delegate?
On Monday, 6 May 2024 at 16:41:38 UTC, Steven Schveighoffer wrote: On Monday, 6 May 2024 at 06:29:49 UTC, Liam McGillivray wrote: Delegates can be a pain, as they often have results different from what one would intuitively expect. This can easily result in bugs. Here's a line that caused a bug that took me awhile to find: ``` foreach(card; unitCards) card.submitted = delegate() => selectUnit(card.unit); ``` Each `UnitInfoCard` object (which `card` is a member of) contains a `Unit` object called `unit`. The intention of this line was that each object in `unitCards` would call `selectUnit` with it's own `unit` every time it calls `submitted`. Instead, every card calls `submitted` with the *last* value of `card`. Yes, this is because the foreach loop reuses the same memory slot for `card`. Even though this is allocated as a closure, it still only allocates the frame stack of the *enclosing function*, and does not allocate a new slot for each loop iteration. You can force this by using a lambda which allocates the closure: ```d foreach(card; unitCards) card.submitted = (c2) { return () => selectUnit(c2.unit); }(card); ``` This is a lambda which accepts `card` as a parameter, and returns an appropriate delegate. It is important to use a parameter, because if you just use card inside there, it's still using the single stack frame of the calling function! ... I would love to see a solution, but the workaround at least exists! -Steve Well that's something. It's not a very good solution for a language that aims for readability. It took me awhile looking at it to figure out what it is about, as I'm not familiar with this syntax. The solution that I did before seeing this was to add a function to `UnitInfoCard` to give it a delegate with a `Unit unit` parameter, and then that function would give that function with the `unit` parameter set to itself to it's own `submitted` member. I will probably keep it like this for readability. ``` void clickAction(void delegate(Unit) @safe clickAction) { submitted = () => clickAction(unit); } ```
Re: How can I put the current value of a variable into a delegate?
On Monday, 6 May 2024 at 16:41:38 UTC, Steven Schveighoffer wrote: This is a very old issue: https://issues.dlang.org/show_bug.cgi?id=2043 since "moved" to https://issues.dlang.org/show_bug.cgi?id=23136 I would love to see a solution, but the workaround at least exists! -Steve Interestingly enough C# used to have the same behaviour but MS decided to go for a breaking change in C# 5; now it behaves as most people expect. Since it's an unsolved problem to keep links working for 10+ years I gave up looking for something official about the subject. Here's an SO question about it though: https://stackoverflow.com/questions/14184515/action-delegate-uses-the-last-values-of-variables-declared-outside-foreach-loop
Re: Why is Phobos `Flag` so overthought ?
Nick Treleaven kirjoitti 8.5.2024 klo 13.24: On Wednesday, 8 May 2024 at 04:27:13 UTC, cc wrote: It doesn't allow a simple boolean to be used as an argument, or any other Flag as they are different instantiations of a template rather than equivalent aliases. It is however awful, cumbersome, annoying design and needs to be completely phased out now that we have named arguments. Flag enforces that the argument says what it relates to. `true` does not say what it relates to. Named arguments are optional, so I don't see how they could make Flag redundant. Well, ```D private struct Undefinable{} auto functionTakingFlags ( int normalArg, Undefinable = Undefinable.init, bool Flag1, Undefinable = Undefinable.init, bool Flag2 ){ // fun body... } ``` As I understand it, this forces the client to use named arguments because they would be trying to pass an `Undefinable` otherwise. They probably could pass `Undefinable` if they really wanted and therefore avoid using named args but they wouldn't do that accidentally. Whether that is any better than the library `Flag` type is up to taste.
Re: Why is Phobos `Flag` so overthought ?
On Wednesday, 8 May 2024 at 04:27:13 UTC, cc wrote: It doesn't allow a simple boolean to be used as an argument, or any other Flag as they are different instantiations of a template rather than equivalent aliases. It is however awful, cumbersome, annoying design and needs to be completely phased out now that we have named arguments. Flag enforces that the argument says what it relates to. `true` does not say what it relates to. Named arguments are optional, so I don't see how they could make Flag redundant.
Re: Why is Phobos `Flag` so overthought ?
On Monday, 6 May 2024 at 17:55:49 UTC, user1234 wrote: I think this just works: ```d enum Flag : bool { no, yes } ``` ... must be a reason but I cant find it RN ;) In "properly" designed Phobos packages, it's unambiguous. Take for example std.datetime.stopwatch: ```d import std.typecons : Flag; alias AutoStart = Flag!"autoStart"; alias MyOtherFlag = Flag!"myOtherFlag"; ... //auto sw = StopWatch(true); // Not allowed //auto sw = StopWatch(MyOtherFlag.yes); // Not allowed auto sw = StopWatch(AutoStart.yes); ``` It doesn't allow a simple boolean to be used as an argument, or any other Flag as they are different instantiations of a template rather than equivalent aliases. It is however awful, cumbersome, annoying design and needs to be completely phased out now that we have named arguments.
Re: TIL: statically initializing an Associative Array
On Tuesday, 7 May 2024 at 01:14:24 UTC, Steven Schveighoffer wrote: On Tuesday, 7 May 2024 at 00:10:27 UTC, Andy Valencia wrote: I had a set of default error messages to go with error code numbers, and did something along the lines of: string[uint] error_text = [ 400: "A message", 401: "A different message" ]; and got "expression is not a constant" ... This was fixed [in 2.106.0](https://dlang.org/changelog/2.106.0.html#dmd.static-assoc-array) please upgrade your compiler. I'm using ldc2 from Debian stable; great news that it's fixed as of late 2023. I'll probably live with my workaround, but it's good to know that it's a bug which has been resolved. Thank you! Andy
Re: TIL: statically initializing an Associative Array
On Tuesday, 7 May 2024 at 00:10:27 UTC, Andy Valencia wrote: I had a set of default error messages to go with error code numbers, and did something along the lines of: string[uint] error_text = [ 400: "A message", 401: "A different message" ]; and got "expression is not a constant" I eventually found this discussion: https://issues.dlang.org/show_bug.cgi?id=6238 I understand that it's problematic, but a message which makes it clearer that compile-time initialization of global AA's are not supported? Because it cost me about a half hour trying to figure out what I was doing wrong. This error message was changed in 2.101.x (unsure which point release): ``` onlineapp.d(1): Error: static initializations of associative arrays is not allowed. onlineapp.d(1):associative arrays must be initialized at runtime: https://dlang.org/spec/hash-map.html#runtime_initialization ``` (My workaround was to initialize the data structure once during app startup.) This was fixed [in 2.106.0](https://dlang.org/changelog/2.106.0.html#dmd.static-assoc-array) please upgrade your compiler. -Steve
Re: TIL: statically initializing an Associative Array
On Tuesday, 7 May 2024 at 01:02:04 UTC, matheus wrote: On Tuesday, 7 May 2024 at 00:10:27 UTC, Andy Valencia wrote: ... Based on what I understood and that issue, I think it was fixed: ... By the way it works as immutable too. Matheus.
Re: TIL: statically initializing an Associative Array
On Tuesday, 7 May 2024 at 00:10:27 UTC, Andy Valencia wrote: I had a set of default error messages to go with error code numbers, and did something along the lines of: string[uint] error_text = [ 400: "A message", 401: "A different message" ]; and got "expression is not a constant" I eventually found this discussion: https://issues.dlang.org/show_bug.cgi?id=6238 I understand that it's problematic, but a message which makes it clearer that compile-time initialization of global AA's are not supported? Because it cost me about a half hour trying to figure out what I was doing wrong. (My workaround was to initialize the data structure once during app startup.) Based on what I understood and that issue, I think it was fixed: import std.stdio; string[uint] aa1 = [1:"ABC",2:"DEF"]; void main(){ auto aa2 = ['A':1,'B':2]; writeln(aa1[1]); writeln(aa1[2]); writeln(aa2['A']); writeln(aa2['B']); } Prints: ABC DEF 1 2 Matheus.
TIL: statically initializing an Associative Array
I had a set of default error messages to go with error code numbers, and did something along the lines of: string[uint] error_text = [ 400: "A message", 401: "A different message" ]; and got "expression is not a constant" I eventually found this discussion: https://issues.dlang.org/show_bug.cgi?id=6238 I understand that it's problematic, but a message which makes it clearer that compile-time initialization of global AA's are not supported? Because it cost me about a half hour trying to figure out what I was doing wrong. (My workaround was to initialize the data structure once during app startup.)
Re: Why is Phobos `Flag` so overthought ?
On Monday, 6 May 2024 at 18:06:53 UTC, Julian Fondren wrote: On Monday, 6 May 2024 at 17:55:49 UTC, user1234 wrote: I think this just works: ```d enum Flag : bool { no, yes } alias AllowVancancy = Flag; // example usage ``` ```d import std.stdio : writeln; enum Flag : bool { no, yes } alias Traditional = Flag; alias Color = Flag; void hello(Traditional traditional, Color color) { if (traditional && color) { writeln("\x1b[31;1mhello world\x1b[0m"); } else if (traditional && !color) { writeln("hello world"); } else if (!traditional && color) { writeln("\x1b[31;1mHello, world!\x1b[0m"); } else { writeln("Hello, world!"); } } void main() { hello(Color.yes, Traditional.yes); // this is wrong, but accepted } ``` Ah yes I see, strongly typed bools. Thanks .
Re: Why is Phobos `Flag` so overthought ?
On Monday, 6 May 2024 at 17:55:49 UTC, user1234 wrote: I think this just works: ```d enum Flag : bool { no, yes } alias AllowVancancy = Flag; // example usage ``` ```d import std.stdio : writeln; enum Flag : bool { no, yes } alias Traditional = Flag; alias Color = Flag; void hello(Traditional traditional, Color color) { if (traditional && color) { writeln("\x1b[31;1mhello world\x1b[0m"); } else if (traditional && !color) { writeln("hello world"); } else if (!traditional && color) { writeln("\x1b[31;1mHello, world!\x1b[0m"); } else { writeln("Hello, world!"); } } void main() { hello(Color.yes, Traditional.yes); // this is wrong, but accepted } ```
Why is Phobos `Flag` so overthought ?
I think this just works: ```d enum Flag : bool { no, yes } alias AllowVancancy = Flag; // example usage ``` Also this is completion friendly whereas Phobos version does not permit DCD completion as it's based on opDispatch. Compare to phobos version: ```d template Flag(string name) { enum Flag : bool { no = false, yes = true } } struct Yes { template opDispatch(string name) { enum opDispatch = Flag!name.yes; } } struct No { template opDispatch(string name) { enum opDispatch = Flag!name.no; } } ``` must be a reason but I cant find it RN ;)
Re: Phobos function to remove all occurances from dynamic array?
On Wednesday, 1 May 2024 at 15:18:03 UTC, Steven Schveighoffer wrote: On Wednesday, 1 May 2024 at 01:09:33 UTC, Liam McGillivray wrote: This is presumably such a common task that I'm surprised it isn't easy to find the answer by searching; Is there a standard library function that removes all elements from a dynamic array that matches an input argument? In `std.array` there's the `replace` function which is supposed to replace all occurrences that match an input with another. It seems to work as described on strings, but I get compiler errors when using it on other array types. I've tried using it to replace occurrences of a certain object in an array with `[]` in order to remove all occurrences, but it's not allowed. Is there a Phobos function that does what I want? It would be crazy if there isn't. `remove` https://dlang.org/phobos/std_algorithm_mutation.html#remove ```d arr = arr.remove!(v => shouldBeRemoved(v)); ``` Why the reassignment? Because `remove` removes elements *in place*, and does not change the range extents. It returns the portion of the range that contains the unremoved elements. So to give an example: ```d auto arr = [1, 2, 3, 4, 5]; auto result = arr.remove!(i => i % 2 == 1); // remove odd elements assert(result == [2, 4]); // first 2 are the slice that is stored in result // the last three are leftovers. assert(arr == [2, 4, 3, 4, 5]); ``` -Steve In case anyone comes upon this in a search, I wanted to point out a couple dangers of using remove. The first is that it mutates arr, as shown in Steve's example. The second is ``` result[0] = 4; assert(result == [4, 4]); assert(arr == [2, 4, 3, 4, 5]); // Fails arr[0] = 2; assert(result == [4, 4]); // Fails ``` Any future changes you make to result or arr change the other. You can use remove to avoid the allocation of a new array, but you better be sure you never read or modify the original array again. If you use filter ``` auto result = arr.filter!(i => i % 2 == 0).array; ``` arr is unchanged and you can use arr and result as you want.
Re: How can I put the current value of a variable into a delegate?
On Monday, 6 May 2024 at 06:29:49 UTC, Liam McGillivray wrote: Delegates can be a pain, as they often have results different from what one would intuitively expect. This can easily result in bugs. Here's a line that caused a bug that took me awhile to find: ``` foreach(card; unitCards) card.submitted = delegate() => selectUnit(card.unit); ``` Each `UnitInfoCard` object (which `card` is a member of) contains a `Unit` object called `unit`. The intention of this line was that each object in `unitCards` would call `selectUnit` with it's own `unit` every time it calls `submitted`. Instead, every card calls `submitted` with the *last* value of `card`. Yes, this is because the foreach loop reuses the same memory slot for `card`. Even though this is allocated as a closure, it still only allocates the frame stack of the *enclosing function*, and does not allocate a new slot for each loop iteration. You can force this by using a lambda which allocates the closure: ```d foreach(card; unitCards) card.submitted = (c2) { return () => selectUnit(c2.unit); }(card); ``` This is a lambda which accepts `card` as a parameter, and returns an appropriate delegate. It is important to use a parameter, because if you just use card inside there, it's still using the single stack frame of the calling function! I renamed the inner parameter `c2` to avoid confusion, but you could name it `card` also. Essentially, the stack frame of the inner function is now allocated a closure, and it has it's own reference to `card` as a parameter. This is a very old issue: https://issues.dlang.org/show_bug.cgi?id=2043 since "moved" to https://issues.dlang.org/show_bug.cgi?id=23136 I would love to see a solution, but the workaround at least exists! -Steve
Re: How can I put the current value of a variable into a delegate?
On Monday, 6 May 2024 at 06:29:49 UTC, Liam McGillivray wrote: Here's a line that caused a bug that took me awhile to find: ``` foreach(card; unitCards) card.submitted = delegate() => selectUnit(card.unit); ``` I think you can do: ```d import std.algorithm.iteration : each; unitCards.each!(c => c.submitted = () => selectUnit(c.unit)); ```
Re: How can I put the current value of a variable into a delegate?
On Monday, 6 May 2024 at 06:29:49 UTC, Liam McGillivray wrote: This is because the delegate assignment causes the local `card` variable to remain alive. The delegate that's assigned is linked to this variable itself, not the value at the time that the delegate is assigned. This is https://issues.dlang.org/show_bug.cgi?id=23136. Perhaps it can be fixed in the next edition. Is there a way I can dereference a variable when placing it in a delegate, so that it's current value is used, rather than the variable itself? I think you would need to make an array before the loop, assign to an indexed element and use that in the delegate.
How can I put the current value of a variable into a delegate?
Delegates can be a pain, as they often have results different from what one would intuitively expect. This can easily result in bugs. Here's a line that caused a bug that took me awhile to find: ``` foreach(card; unitCards) card.submitted = delegate() => selectUnit(card.unit); ``` Each `UnitInfoCard` object (which `card` is a member of) contains a `Unit` object called `unit`. The intention of this line was that each object in `unitCards` would call `selectUnit` with it's own `unit` every time it calls `submitted`. Instead, every card calls `submitted` with the *last* value of `card`. This is because the delegate assignment causes the local `card` variable to remain alive. The delegate that's assigned is linked to this variable itself, not the value at the time that the delegate is assigned. Is there a way I can dereference a variable when placing it in a delegate, so that it's current value is used, rather than the variable itself?
Re: Show dialog box for uncaught exception (Windows, lld-link)
On Sunday, 5 May 2024 at 18:28:29 UTC, SimonN wrote: My implementation for the message box is now: According to [UTF-8 Everywhere](https://utf8everywhere.org/#windows), I shouldn't use `MessageBoxA` at all. The `A` means ANSI codepages, _not_ UTF-8. My above code _will_ show garbage output when there is some non-ASCII in the exception message. Better: Convert to UTF-16 yourself and call `MessageBoxW`: version (Windows) { import core.sys.windows.windows; import std.conv; const wstring messageBody = wtext(/* ... */, "\0"); MessageBoxW(null, messageBody.ptr, null, MB_ICONERROR); throw /* ... */; } -- Simon
Re: Show dialog box for uncaught exception (Windows, lld-link)
On Sunday, 5 May 2024 at 17:15:10 UTC, Steven Schveighoffer wrote: } catch(Exception e) { visualDisplayOfException(e); throw e; } Thanks! That's practically the same pattern that I already use for logging: Try-catch near the entry point, show the message, re-throw. My implementation for the message box is now: catch (Throwable t) { import core.sys.windows.windows; const string errText = /* ... parse t ... */ MessageBoxA(null, errText.ptr, null, MB_ICONERROR); } That solves my problem. Even though I don't pass my game's window as the parent of the message box (first argument, where I pass `null`), the graphical game halts before exiting, shows the error, and users can screenshot both together. That's good. From your answer, I'll assume: There is no standardized way in the D ecosystem (e.g., by calling a DRuntime function from my usercode) to opt into displaying such a message box for uncaught exceptions. I have to call third-party APIs myself. Or is there something after all? From reading the 2019 thread [Deactivate windows MessageBox dialog on exception](https://forum.dlang.org/post/tlhjypvsaxzymccfc...@forum.dlang.org), it sounds like we should get an error box when we link with `-subsystem:windows`, and no box otherwise. -- Simon
Re: Show dialog box for uncaught exception (Windows, lld-link)
On Sunday, 5 May 2024 at 14:55:20 UTC, SimonN wrote: My application is a graphical game. I close stdout and stderr by passing `-subsystem:windows` to `lld-link` to suppress the extra console window. For a few fatal errors (missing required resources, can't open display, ...), I throw exceptions, log them to logfile, then re-throw them to crash. I can tell Windows users to look in the logfile, but it would be more fitting on Windows to show an error dialog box in addition to the logging. ```d int realMain(string[] args) { // all your normal code goes here } int main(string[] args) { version(Windows) { try { realMain(args); } catch(Exception e) { visualDisplayOfException(e); throw e; } } else { // presumably, non-windows systems shouldn't show a graphical Exception // trace? realMain(args); } } ``` -Steve
Show dialog box for uncaught exception (Windows, lld-link)
Hi, for Windows, I link my executables with `lld-link`, whether for 32-bit and 64-bit and whether I've built with LDC or DMD. How can I generate a dialog box for uncaught exceptions that fly out of my executable's `main()`? When I linked with Optlink years ago for Windows 32-bit, it generated an error dialog box for an uncaught exception. But with `lld-link`, the exception's message lands only on stderr. I didn't see anything related in `lld-link -help`. Can I configure DRuntime in a special way at runtime? My application is a graphical game. I close stdout and stderr by passing `-subsystem:windows` to `lld-link` to suppress the extra console window. For a few fatal errors (missing required resources, can't open display, ...), I throw exceptions, log them to logfile, then re-throw them to crash. I can tell Windows users to look in the logfile, but it would be more fitting on Windows to show an error dialog box in addition to the logging. -- Simon
Re: dlang.org/Learn "hello_world".sort.chain ...
On Tuesday, 26 December 2023 at 10:53:10 UTC, Tony wrote: I just typed in the program that is on the first page of Learn. It has this line: sort(chain(arr1, arr2, arr3)); I assigned that to a variable: arr4 = sort(chain(arr1, arr2, arr3)); then printed it out writefln("%s",arr4); // works and then tried to print out the type of arr4: writefln("%s",typeof(arr4)); and got this error: // HelloWorld.d:25:19: error: cannot pass type SortedRange!(Result, "a < b") as a function argument What exactly is that type? Or maybe, what would it take to understand what that type is? The error message suggests that `SortedRange!(Result, "a < b")` is the type returned by the `sort` function. For additional insights and assistance, you can explore resources like online dissertation help literature review https://literaturereviewwritingservice.com/ This type represents a sorted range of elements, possibly of type `Result`, sorted based on the comparison predicate `"a < b"`. To understand it better, you may need to inspect its definition or consider alternative methods for printing its type.
Re: Turning fixed sized array into tuple
On Saturday, 4 May 2024 at 19:11:14 UTC, Nick Treleaven wrote: On Saturday, 4 May 2024 at 16:58:00 UTC, Dmitry Olshansky wrote: So I have a function: ```d size_t awaitAny(T...)(T args) { ... } ``` And I have: ``d Event*[4] events; `` How do I pass all 4 of events to awaitAny as tuple of arguments? Use `awaitAny(events.tupleof)`? https://dlang.org/spec/arrays.html#array-properties Thanks, totally missed it! — Dmitry Olshansky CEO @ [Glow labs](https://glow-labs.pro) https://olshansky.me
Re: Turning fixed sized array into tuple
On Saturday, 4 May 2024 at 16:58:00 UTC, Dmitry Olshansky wrote: So I have a function: ```d size_t awaitAny(T...)(T args) { ... } ``` And I have: ``d Event*[4] events; `` How do I pass all 4 of events to awaitAny as tuple of arguments? Use `awaitAny(events.tupleof)`? https://dlang.org/spec/arrays.html#array-properties
Turning fixed sized array into tuple
So I have a function: ```d size_t awaitAny(T...)(T args) { ... } ``` And I have: ``d Event*[4] events; `` How do I pass all 4 of events to awaitAny as tuple of arguments? -- Dmitry Olshansky CEO @ [Glow labs](https://glow-labs.pro) https://olshansky.me/about/
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
Well all these proposals to `int` index like `size_t` and `const typeof(arr.length)` are cryptic and less readable and less straightforward in comparison to how it used to be. Feels like horrible decision if the language is suppose to be somewhat futureproof. The `int` was simple, straighforward and great. These suggestions feel like some `C++` all over again.
Re: Goto skipping declarations
On 04/05/2024 8:38 AM, Jonathan M Davis wrote: In any case, I expect that the compiler is just going dumb here because of the label for some reason, and one or more of the checks that it's supposed to be doing is being missed. It is very simple code. A reverse search over the double linked list for the goto from the label. I looked into it fairly recently as an example of type state analysis D is already designed against.
Re: Goto skipping declarations
On Friday, 3 May 2024 at 20:38:31 UTC, Jonathan M Davis wrote: https://issues.dlang.org/show_bug.cgi?id=24535
Re: Goto skipping declarations
On Friday, May 3, 2024 2:38:31 PM MDT Jonathan M Davis via Digitalmars-d-learn wrote: > On Friday, May 3, 2024 1:15:16 PM MDT Ben Jones via Digitalmars-d-learn wrote: > > In general, you can't skip a declaration with goto, but it seems > > to be allowed if the declaration you're skipping is labelled... > > Is that expected or an accepts invalid bug? > > > > https://godbolt.org/z/4qx8Pf6G7 > > > > ```d > > void f1(){ //fails with error about skipping a declaration > > > > int x; > > goto Label; > > int y; > > Label: > > int z; > > > > } > > > > void f2(){ //compiles fine > > > > int x; > > goto Label; > > Dummy: > > int y; > > Label: > > int z; > > > > } > > ``` > > It has to be a bug, and taking it a step further shows that. If you print > out y, you'll get a seemingly random number. E.G. On the first run, I got > > 554440803 > > and on the second I got > > 549310547 > > Presumably, it's a garbage value from whatever happened to be on the stack. > > I'm quite sure that the spec doesn't have anything about being allowed to > skip a declaration just because it has a label on it (honestly, if we _did_ > want that to be the case, the spec would probably be missing it, since it > tends to fall on the side of having too few details rather than too many), > but even if it did, the code is clearly doing something that should not be > happening with initialization without explicitly using = void. So, > _something_ here would nee to be fixed. > > In any case, I expect that the compiler is just going dumb here because of > the label for some reason, and one or more of the checks that it's supposed > to be doing is being missed. Here. I reported it: https://issues.dlang.org/show_bug.cgi?id=24534 - Jonathan M Davis
Re: Goto skipping declarations
On Friday, May 3, 2024 1:15:16 PM MDT Ben Jones via Digitalmars-d-learn wrote: > In general, you can't skip a declaration with goto, but it seems > to be allowed if the declaration you're skipping is labelled... > Is that expected or an accepts invalid bug? > > https://godbolt.org/z/4qx8Pf6G7 > > ```d > void f1(){ //fails with error about skipping a declaration > int x; > goto Label; > int y; > Label: > int z; > } > > void f2(){ //compiles fine > int x; > goto Label; > Dummy: > int y; > Label: > int z; > } > ``` It has to be a bug, and taking it a step further shows that. If you print out y, you'll get a seemingly random number. E.G. On the first run, I got 554440803 and on the second I got 549310547 Presumably, it's a garbage value from whatever happened to be on the stack. I'm quite sure that the spec doesn't have anything about being allowed to skip a declaration just because it has a label on it (honestly, if we _did_ want that to be the case, the spec would probably be missing it, since it tends to fall on the side of having too few details rather than too many), but even if it did, the code is clearly doing something that should not be happening with initialization without explicitly using = void. So, _something_ here would nee to be fixed. In any case, I expect that the compiler is just going dumb here because of the label for some reason, and one or more of the checks that it's supposed to be doing is being missed. - Jonathan M Davis
Goto skipping declarations
In general, you can't skip a declaration with goto, but it seems to be allowed if the declaration you're skipping is labelled... Is that expected or an accepts invalid bug? https://godbolt.org/z/4qx8Pf6G7 ```d void f1(){ //fails with error about skipping a declaration int x; goto Label; int y; Label: int z; } void f2(){ //compiles fine int x; goto Label; Dummy: int y; Label: int z; } ```
Re: Recommendations on porting Python to D
On Friday, 3 May 2024 at 17:38:10 UTC, Chris Piker wrote: On Thursday, 25 April 2024 at 16:57:53 UTC, mw wrote: On Wednesday, 24 April 2024 at 22:07:41 UTC, Chris Piker wrote: Python-AST to D source converter may already exist? https://github.com/joortcom/eiffel_rename/tree/main/yi A rudimentary converter from (extended) Python to D. Maybe you can use it as a starting point. Thanks for the suggestions. I put the question aside for a bit, but yesterday ran across a python transpiler here: https://github.com/py2many/py2many It already has support for C++, Go and others. Since I have mountains of python code created over many years, maybe it would be worth contributing to this project out of self interest. Can you take a look at py2many and see what you think about it? Getting D on the support list might be good. (Haven't checked its own implementation and output code quality.) But it says has output for Kotlin, Dart, these two languages are similar to D syntactically, so will be a good start.
Re: Recommendations on porting Python to D
On Thursday, 25 April 2024 at 16:57:53 UTC, mw wrote: On Wednesday, 24 April 2024 at 22:07:41 UTC, Chris Piker wrote: Python-AST to D source converter may already exist? https://github.com/joortcom/eiffel_rename/tree/main/yi A rudimentary converter from (extended) Python to D. Maybe you can use it as a starting point. Thanks for the suggestions. I put the question aside for a bit, but yesterday ran across a python transpiler here: https://github.com/py2many/py2many It already has support for C++, Go and others. Since I have mountains of python code created over many years, maybe it would be worth contributing to this project out of self interest. Can you take a look at py2many and see what you think about it? Getting D on the support list might be good.
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
On Friday, 3 May 2024 at 15:19:13 UTC, user1234 wrote: On Friday, 3 May 2024 at 14:59:57 UTC, BoQsc wrote: On Friday, 3 May 2024 at 13:18:02 UTC, user1234 wrote: [...] So how would you update this example, what is the right index type here to choose? ``` import std.stdio : writefln; void main() { auto arr = [ [5, 15], // 20 [2, 3, 2, 3], // 10 [3, 6, 2, 9], // 20 ]; foreach (i, row; arr) { double total = 0.0; foreach (e; row) total += e; auto avg = total / row.length; writefln("AVG [row=%d]: %.2f", i, avg); } } ``` Example taken from https://tour.dlang.org/tour/en/basics/foreach Isn't that obvious ? ```d foreach (const size_t i, row; arr) ``` `arr` is not a static array, it is a dynamic one, consequently its `.length` type is `size_t`, even if you have the feeling that, in the present situation, `int` bitwidth would be sufficient. even better: ```d foreach (const typeof(arr.length) i, row; arr) ``` Otherwise I respect your POV, it's just that here I have no problem with the way that works. I dont see any issue with the type system. D type system is static, strong, but optionally inferred. And that's it.
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
On Friday, 3 May 2024 at 14:59:57 UTC, BoQsc wrote: On Friday, 3 May 2024 at 13:18:02 UTC, user1234 wrote: On Friday, 3 May 2024 at 10:50:03 UTC, BoQsc wrote: [...] **You can specify the index type, just choose the right one.** For now there's a deprecation message but after some while you'll get a proper error message, e.g _"index type for arr must be of type T because arr.length type is T"_. What's is happening now is to help people updating their code and prevent abrupt breakages. So how would you update this example, what is the right index type here to choose? ``` import std.stdio : writefln; void main() { auto arr = [ [5, 15], // 20 [2, 3, 2, 3], // 10 [3, 6, 2, 9], // 20 ]; foreach (i, row; arr) { double total = 0.0; foreach (e; row) total += e; auto avg = total / row.length; writefln("AVG [row=%d]: %.2f", i, avg); } } ``` Example taken from https://tour.dlang.org/tour/en/basics/foreach Isn't that obvious ? ```d foreach (const size_t i, row; arr) ``` `arr` is not a static array, it is a dynamic one, consequently its `.length` type is `size_t`, even if you have the feeling that, in the present situation, `int` bitwidth would be sufficient.
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
On Friday, 3 May 2024 at 13:18:02 UTC, user1234 wrote: On Friday, 3 May 2024 at 10:50:03 UTC, BoQsc wrote: Why am I forced to visit this D Lang thread, why this deprecation warning still appears in my console window in the latest version of DMD. Does not make any sense from the developer's perspective to show this warning and pollute the already polluted logging entries of the compiler. How am I suppose to program anything effectively if half of the screen are some nonsensical deprecation warnings without guidance or sane explanations. This is not better ``` foreach (i, row; arr) ``` than ``` foreach (int i, row; arr) ``` Hides the datatype and makes the D language appear in-explicit and annoying. What is this language becoming. A completely weak typed language or something? I would use JavaScript if I would want that. How are we suppose to make whole sane Operating Systems with such syntaxes. Do everyone just enjoy having bugs with some implicit size_t, or do everyone just enjoy deprecation warnings in their logging systems when there are way more important problems to solve, that are actually project related. **You can specify the index type, just choose the right one.** For now there's a deprecation message but after some while you'll get a proper error message, e.g _"index type for arr must be of type T because arr.length type is T"_. What's is happening now is to help people updating their code and prevent abrupt breakages. So how would you update this example, what is the right index type here to choose? ``` import std.stdio : writefln; void main() { auto arr = [ [5, 15], // 20 [2, 3, 2, 3], // 10 [3, 6, 2, 9], // 20 ]; foreach (i, row; arr) { double total = 0.0; foreach (e; row) total += e; auto avg = total / row.length; writefln("AVG [row=%d]: %.2f", i, avg); } } ``` Example taken from https://tour.dlang.org/tour/en/basics/foreach
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
On Friday, 3 May 2024 at 10:50:03 UTC, BoQsc wrote: Why am I forced to visit this D Lang thread, why this deprecation warning still appears in my console window in the latest version of DMD. Does not make any sense from the developer's perspective to show this warning and pollute the already polluted logging entries of the compiler. How am I suppose to program anything effectively if half of the screen are some nonsensical deprecation warnings without guidance or sane explanations. This is not better ``` foreach (i, row; arr) ``` than ``` foreach (int i, row; arr) ``` Hides the datatype and makes the D language appear in-explicit and annoying. What is this language becoming. A completely weak typed language or something? I would use JavaScript if I would want that. How are we suppose to make whole sane Operating Systems with such syntaxes. Do everyone just enjoy having bugs with some implicit size_t, or do everyone just enjoy deprecation warnings in their logging systems when there are way more important problems to solve, that are actually project related. You can specify the index type, just choose the right one. For now there's a deprecation message but after some while you'll get a proper error message, e.g _"index type for arr must be of type T because arr.length type is T"_. What's is happening now is to help people updating their code and prevent abrupt breakages.
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
Why am I forced to visit this D Lang thread, why this deprecation warning still appears in my console window in the latest version of DMD. Does not make any sense from the developer's perspective to show this warning and pollute the already polluted logging entries of the compiler. How am I suppose to program anything effectively if half of the screen are some nonsensical deprecation warnings without guidance or sane explanations. This is not better ``` foreach (i, row; arr) ``` than ``` foreach (int i, row; arr) ``` Hides the datatype and makes the D language appear in-explicit and annoying. What is this language becoming. A completely weak typed language or something? I would use JavaScript if I would want that. How are we suppose to make whole sane Operating Systems with such syntaxes. Do everyone just enjoy having bugs with some implicit size_t, or do everyone just enjoy deprecation warnings in their logging systems when there are way more important problems to solve, that are actually project related.
Re: Challenge Tuples
On Friday, 3 May 2024 at 05:11:28 UTC, Salih Dincer wrote: .. Wouldn't it be great if there was a feature that worked at runtime... SDB@79 module m; @safe: private: import std; void main() { auto myTuple = tuple(1, 2, 3, [1, 3], 5); int[] arrToSum; foreach(int i, val; myTuple.expand) { if(typeof(val).stringof == "int[]") { foreach(v; myTuple.expand[i..i+1]) arrToSum ~= v; } else { arrToSum ~= val; } } writefln("The total value of the tuples is: %s", arrToSum.sum); // 15 }
Re: Challenge Tuples
On Wednesday, 1 May 2024 at 14:15:19 UTC, Andrey Zherikov wrote: Shorter and without allocations: ```d import std.typecons : tuple; import std.algorithm : sum, each; auto sum(int i) => i; void main() { auto t = tuple(1, 2, 3, [1, 3], 5); int res=0; t.each!(e => res += sum(e)); assert(res == 15); } ``` Super! In summary, D is clearly ahead of the tuple. Especially with its features similar to AliasSeq, I think it is unrivaled. Wouldn't it be great if there was a feature that worked at runtime... SDB@79
Recommendations for good concurrent hashset (esp. for strings)?
Hi, I'm looking for recommendations for good concurrent hashset (esp. for strings)? Any libraries? Thanks.
Re: Phobos function to remove all occurances from dynamic array?
On Wednesday, 1 May 2024 at 01:09:33 UTC, Liam McGillivray wrote: This is presumably such a common task that I'm surprised it isn't easy to find the answer by searching; Is there a standard library function that removes all elements from a dynamic array that matches an input argument? In `std.array` there's the `replace` function which is supposed to replace all occurrences that match an input with another. It seems to work as described on strings, but I get compiler errors when using it on other array types. I've tried using it to replace occurrences of a certain object in an array with `[]` in order to remove all occurrences, but it's not allowed. Is there a Phobos function that does what I want? It would be crazy if there isn't. `remove` https://dlang.org/phobos/std_algorithm_mutation.html#remove ```d arr = arr.remove!(v => shouldBeRemoved(v)); ``` Why the reassignment? Because `remove` removes elements *in place*, and does not change the range extents. It returns the portion of the range that contains the unremoved elements. So to give an example: ```d auto arr = [1, 2, 3, 4, 5]; auto result = arr.remove!(i => i % 2 == 1); // remove odd elements assert(result == [2, 4]); // first 2 are the slice that is stored in result // the last three are leftovers. assert(arr == [2, 4, 3, 4, 5]); ``` -Steve
Re: aliasing private
On Wednesday, 1 May 2024 at 12:07:26 UTC, NotYouAgain wrote: I want to do a C like #define on private, but I can't ie. #define private fileprivate // --- module m; alias fileprivate = private; // grr! class myClass { fileprivate int n; } // --- You cant. That is simply not supported.
Re: Challenge Tuples
On Friday, 26 April 2024 at 13:25:34 UTC, Salih Dincer wrote: You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and implement the sum (total = 15) with the least codes using the sum() function of the language you are coding... Let's start with D: ```d import std.typecons : tuple; import std.algorithm : sum; void main() { auto t = tuple(1, 2, 3, [1, 3], 5); int[] arr; t.each!(e => arr ~= e); assert(arr.sum == 15); } ``` and bonus: ```d import std.typecons : tuple; import std.stdio : writeln; void main() { auto t = tuple(1, 2, 3, [1, 3], 5); auto results = [0]; foreach (data; t) { static if (is(typeof(data) == int[])) { int sum; foreach (d; data) { sum += d; } results ~= sum; } else { results ~= data; } } results.writeln; // [0, 1, 2, 3, 4, 5] ``` I bet you won't be able to do it this easily with other languages! Note: I tried with C# and Python and it didn't work! SDB@79 Shorter and without allocations: ```d import std.typecons : tuple; import std.algorithm : sum, each; auto sum(int i) => i; void main() { auto t = tuple(1, 2, 3, [1, 3], 5); int res=0; t.each!(e => res += sum(e)); assert(res == 15); } ```
Re: Phobos function to remove all occurances from dynamic array?
On Wednesday, 1 May 2024 at 01:09:33 UTC, Liam McGillivray wrote: I get compiler errors when using it on other array types. I've tried using it to replace occurrences of a certain object in an array with [] in order to remove all occurrences, but it's not allowed. Can you post a code example?
aliasing private
I want to do a C like #define on private, but I can't ie. #define private fileprivate // --- module m; alias fileprivate = private; // grr! class myClass { fileprivate int n; } // ---
Re: Phobos function to remove all occurances from dynamic array?
On Wednesday, 1 May 2024 at 01:24:55 UTC, Lance Bachmeier wrote: Does filter do what you need? https://dlang.org/phobos/std_algorithm_iteration.html#.filter It seems to do it with the following line: ``` allObjects = allObjects.filter!(element => element !is this).array; ``` So I've found a way to do it. It's still rather strange that it's so difficult to find the solution to such a common problem in the documentation.
Re: Phobos function to remove all occurances from dynamic array?
On Wednesday, 1 May 2024 at 01:09:33 UTC, Liam McGillivray wrote: This is presumably such a common task that I'm surprised it isn't easy to find the answer by searching; Is there a standard library function that removes all elements from a dynamic array that matches an input argument? In `std.array` there's the `replace` function which is supposed to replace all occurrences that match an input with another. It seems to work as described on strings, but I get compiler errors when using it on other array types. I've tried using it to replace occurrences of a certain object in an array with `[]` in order to remove all occurrences, but it's not allowed. Is there a Phobos function that does what I want? It would be crazy if there isn't. Does filter do what you need? https://dlang.org/phobos/std_algorithm_iteration.html#.filter
Re: Find homography in D?
On Sunday, 21 April 2024 at 14:57:33 UTC, Paolo Invernizzi wrote: Hi, Someone can point me to a D implementation of the classical OpenCV find homography matrix? Thank you, Paolo Something I wrote awhile ago... ``` import kaleidic.lubeck : svd; import gfm.math; import mir.ndslice : sliced; auto generateTransformationArray(int[] p) { return generateTransformationArray(p[0],p[1],p[2],p[3]); } auto generateTransformationArray(int x, int y, int x_, int y_) { return [-x, -y, -1, 0, 0, 0, x*x_, y*x_, x_, 0, 0, 0, -x, -y, -1, x*y_, y*y_, y_]; } auto transformCoor (mat3d mat, vec3d vec) { auto res = mat * vec; return res / res[2]; } auto findHomography (int[][] correspondances) { auto a = correspondances .map!(a => a.generateTransformationArray) .joiner .array .sliced(8,9); auto r = a.svd; auto homog = r.vt.back; return mat3d(homog.map!(a => a/homog.back).array); } ```
Re: Find homography in D?
On Sunday, 21 April 2024 at 14:57:33 UTC, Paolo Invernizzi wrote: Hi, Someone can point me to a D implementation of the classical OpenCV find homography matrix? Thank you, Paolo Just for future records in the forum. // https://math.stackexchange.com/questions/3509039/calculate-homography-with-and-without-svd /+dub.sdl: dependency "lubeck" version="~>1.5.4" +/ import std; import mir.ndslice; import kaleidic.lubeck; void main() { double[2] x_1 = [93,-7]; double[2] y_1 = [63,0]; double[2] x_2 = [293,3]; double[2] y_2 = [868,-6]; double[2] x_3 = [1207,7]; double[2] y_3 = [998,-4]; double[2] x_4 = [1218,3]; double[2] y_4 = [309,2]; auto A = [ -x_1[0], -y_1[0], -1, 0, 0, 0, x_1[0]*x_1[1], y_1[0]*x_1[1], x_1[1], 0, 0, 0, -x_1[0], -y_1[0], -1, x_1[0]*y_1[1], y_1[0]*y_1[1], y_1[1], -x_2[0], -y_2[0], -1, 0, 0, 0, x_2[0]*x_2[1], y_2[0]*x_2[1], x_2[1], 0, 0, 0, -x_2[0], -y_2[0], -1, x_2[0]*y_2[1], y_2[0]*y_2[1], y_2[1], -x_3[0], -y_3[0], -1, 0, 0, 0, x_3[0]*x_3[1], y_3[0]*x_3[1], x_3[1], 0, 0, 0, -x_3[0], -y_3[0], -1, x_3[0]*y_3[1], y_3[0]*y_3[1], y_3[1], -x_4[0], -y_4[0], -1, 0, 0, 0, x_4[0]*x_4[1], y_4[0]*x_4[1], x_4[1], 0, 0, 0, -x_4[0], -y_4[0], -1, x_4[0]*y_4[1], y_4[0]*y_4[1], y_4[1] ].sliced(8, 9); auto svdResult = svd(A); auto homography = svdResult.vt[$-1].sliced(3, 3); auto transformedPoint = homography.mtimes([1679, 128, 1].sliced.as!double.slice); transformedPoint[] /= transformedPoint[2]; writeln(transformedPoint); //[4, 7, 1] }
Re: dynamic linker flags with dub
On 30/04/2024 10:20 AM, KytoDragon wrote: I want to use dll-style hot-reloading for a windows application which requires a different name for the PDB file for each compilation. (windows locks the pdb file when loading the dll and the compiler can't create a new pdb with the same name). How can I achieve this with dub? Is there a way to inject variables into the linker flags? E.g. something like this in the dub.json: "lflags-windows-ldc": ["/PDB:foo_%random%.pdb"] Your best bet probably is to use dub as a library, and change your ``targetName`` or ``targetPath`` on each compilation. Alternatively you could generate your dub file with the change in it each time that depends upon the actual library (which would be a ``sourceLibrary``).
Re: Challenge Tuples
On Friday, 26 April 2024 at 13:25:34 UTC, Salih Dincer wrote: You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and implement the sum (total = 15) with the least codes using the sum() function of the language you are coding... Nim: ```nim import std/[math, typetraits, macros] macro unrollRange(low, high: static int; name, body: untyped) = result = newStmtList() for i in low ..< high: result.add(newBlockStmt(newStmtList( newConstStmt(name, newLit i), copy body ))) let t = (1, 2, 3, @[1, 3], 5) var arr: seq[int] unrollRange(0, t.tupleLen, i): arr.add t[i] doAssert arr.sum == 15 ``` vs. D 1. there's no `each` on tuples 2. there's no static for loop, so a macro is needed for the tuple indices 3. `add` is making use of the same overload as D's `~=`
Re: Challenge Tuples
On Friday, 26 April 2024 at 13:25:34 UTC, Salih Dincer wrote: You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and implement the sum (total = 15) with the least codes using the sum() function of the language you are coding... Let's start with D: ```d import std.typecons : tuple; import std.algorithm : sum; void main() { auto t = tuple(1, 2, 3, [1, 3], 5); int[] arr; t.each!(e => arr ~= e); assert(arr.sum == 15); } ``` I bet you won't be able to do it this easily with other languages! Note: I tried with C# and Python and it didn't work! For Python it is possible to use something like: ```python t = (1,2,3,[1,3],5) for e in t: a.append(e) if isinstance(e, int) else a.extend(e) print(sum(a)) ```
Re: Challenge Tuples
On Saturday, 27 April 2024 at 15:36:40 UTC, Nick Treleaven wrote: On Saturday, 27 April 2024 at 15:32:40 UTC, Nick Treleaven wrote: On Saturday, 27 April 2024 at 11:55:58 UTC, Basile B. wrote: foreach const e in u do if echo(is, e, T) do result += e; static if (is(typeof(e) == int)) r += e; Actually I would write that: ```d R r; foreach (e; v) { static if (is(typeof(e) : R)) ``` I like the new sum() function, great Nick! Moreover, it also works with an ordinary range: ```d enum limit = 100; // sum = 5050 iota(limit + 1).sum.writeln; ``` Python seems too complicated to me, but C# looks delicious. Moreover, it was implemented without defining IEnumerator. Well done Matheus! SDB@79
Re: Challenge Tuples
On Saturday, 27 April 2024 at 15:32:40 UTC, Nick Treleaven wrote: On Saturday, 27 April 2024 at 11:55:58 UTC, Basile B. wrote: foreach const e in u do if echo(is, e, T) do result += e; static if (is(typeof(e) == int)) r += e; Actually I would write that: ```d R r; foreach (e; v) { static if (is(typeof(e) : R)) ```
Re: Challenge Tuples
On Saturday, 27 April 2024 at 11:55:58 UTC, Basile B. wrote: Here's [STYX](https://gitlab.com/styx-lang/styx) solution: function sum[T,U](U u): u32 I think you meant `: T`. { var T result; foreach const e in u do if echo(is, e, T) do result += e; else do result += sum![T](e); return result; } function main(): s32 { assert((1, 2, 3, [1, 3], 5).sum![u32]() == 15); return 0; } Mostly equivalent D: ```d R sum(R = long, T)(T v) { R r; foreach (e; v) { static if (is(typeof(e) == int)) r += e; else r += sum!R(e); } return r; } void main() { import std; assert(tuple(1, 2, 3, [1, 3], 5).sum == 15); } ```
Re: Challenge Tuples
On Friday, 26 April 2024 at 13:25:34 UTC, Salih Dincer wrote: You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and implement the sum (total = 15) with the least codes using the sum() function of the language you are coding... Let's start with D: Here's [STYX](https://gitlab.com/styx-lang/styx) solution: function sum[T,U](U u): u32 { var T result; foreach const e in u do if echo(is, e, T) do result += e; else do result += sum![T](e); return result; } function main(): s32 { assert((1, 2, 3, [1, 3], 5).sum![u32]() == 15); return 0; } A few notes: - tuples are first class citizen - `foreach` over tuple is like in D, i.e unrolling - `echo` is like D `__traits` - _Implicit Generic Application_ of `U` (that's like D's IFTI) makes the task easy
Re: Challenge Tuples
On Friday, 26 April 2024 at 13:25:34 UTC, Salih Dincer wrote: You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and implement the sum (total = 15) with the least codes using the sum() function of the language you are coding... My Python solution (function named dosum to avoid collision w. Python primitive): def dosum(itm): if isinstance(itm, (int, float)): return itm return sum( dosum(_i) for _i in itm ); print dosum( [1, 2, 3, [1, 3], 5] )
Re: Challenge Tuples
On Friday, 26 April 2024 at 13:25:34 UTC, Salih Dincer wrote: ... Very nice, for your first example I need to think a bit because I'm bit rusty in C#, but I think it will not be as easier as D version. For the bonus part: private static void Main(string[] args){ var a = (1,2,3,(1,3),5); var t = a as ITuple; var xx = new List(); for(var i=0;i if(t[i].GetType() == typeof(System.ValueTuple)){ var t2 = (t[i] as ITuple); var s = 0; for(var j=0;jAgain I'm rusty in C#... but so far yes it's more verbose than the D version. Matheus.
Challenge Tuples
You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and implement the sum (total = 15) with the least codes using the sum() function of the language you are coding... Let's start with D: ```d import std.typecons : tuple; import std.algorithm : sum; void main() { auto t = tuple(1, 2, 3, [1, 3], 5); int[] arr; t.each!(e => arr ~= e); assert(arr.sum == 15); } ``` and bonus: ```d import std.typecons : tuple; import std.stdio : writeln; void main() { auto t = tuple(1, 2, 3, [1, 3], 5); auto results = [0]; foreach (data; t) { static if (is(typeof(data) == int[])) { int sum; foreach (d; data) { sum += d; } results ~= sum; } else { results ~= data; } } results.writeln; // [0, 1, 2, 3, 4, 5] ``` I bet you won't be able to do it this easily with other languages! Note: I tried with C# and Python and it didn't work! SDB@79
Re: Recommendations on porting Python to D
On Wednesday, 24 April 2024 at 19:50:45 UTC, Chris Piker wrote: Hi D I have a somewhat extensive CGI based web service written in Python and I'd like to port it to D. I can do this manually of course, and maybe that's the best way, but for a rough start, is anyone aware of any tools that generate an abstract syntax tree which could then be converted to somewhat equivalent D code? This might give me a jump-start on the manual conversion process. Then later I can work on removing the CGI dependency. I'm aware that this wouldn't work in general due to all the third party modules typically used in python, but most of this code is self contained Python2 and doesn't depend on many imports. I can just call my old C code from D, but the old Python is another story. Thanks for any advice you may have, A strategy roughly along the lines of: Test what you can, then port the tests, then just let chatgpt have at it can go further than one might reasonably expect (I have used chatgpt to convert to and from languages that don't even exist in public and it can basically get the gist of most things). Treat it interactively rather than like a CLI tool, it must be said.