Re: UFCS limit
On Friday, 17 June 2022 at 05:17:20 UTC, Tejas wrote: On Friday, 17 June 2022 at 01:04:28 UTC, Paul Backus wrote: Nope. The way UFCS works is that allows you to call free functions using member-function syntax, and member-function syntax is always `object.memberName`, so UFCS only works for functions that have a name, not anonymous functions. Would it be worthwhile to extend the scope of UFCS to accomodate this use case as well though?? Probably not.
Re: UFCS limit
On Friday, 17 June 2022 at 01:04:28 UTC, Paul Backus wrote: Nope. The way UFCS works is that allows you to call free functions using member-function syntax, and member-function syntax is always `object.memberName`, so UFCS only works for functions that have a name, not anonymous functions. Would it be worthwhile to extend the scope of UFCS to accomodate this use case as well though??
Re: UFCS limit
On Thursday, 16 June 2022 at 23:59:06 UTC, Antonio wrote: Is it there any way to apply UFCS on the returned method in the same expression? Nope. The way UFCS works is that allows you to call free functions using member-function syntax, and member-function syntax is always `object.memberName`, so UFCS only works for functions that have a name, not anonymous functions.
UFCS limit
```d auto doSomething(string text) { return (string text2) { import std.stdio; writeln(text,",",text2); }; } void main() { doSomething("Hello")("X"); "X".doSomething("Hello")(); } ``` Compiler error: ``` ... onlineapp.d(13):expected 1 argument(s), not 2 ``` I tried with some syntax change: ```d void main() { doSomething("Hello")("X"); (doSomething("Hello"))("X"); // it works "X".(doSomething("Hello"))(); // fails!!! } ``` ```onlineapp.d(14): Error: identifier or `new` expected following `.`, not `( Is it there any way to apply UFCS on the returned method in the same expression?
Re: UI Library
On Saturday, 11 June 2022 at 21:50:47 UTC, Adam D Ruppe wrote: On Saturday, 11 June 2022 at 01:20:17 UTC, harakim wrote: The issue I'm having is that I don't understand how to assign bounds in the nested widget. I'm sure there's a very clean solution. I basically want a paintContent method but with the bounds dynamically assigned by the parent. Well the bounds given to paintContent just define your content area boundaries, relative to the nested widget. The content area is inside its own border. The actual position is assigned by the parent (the virtual function there is recomputeChildLayout, you can override that to arrange instead of letting it automatically fill the space). The recomputeChildLayout method is the answer I was looking for. You describe copying the paint method into the paint content method. I did the exact opposite and copied from the paintContent method to the paint method and it worked. I am getting pretty comfortable with using simple display, but I will probably look to minigui in the future. This application is just for me to use so I don't need interactive buttons and so forth. Thanks for making these libraries available. I'm also using your sqllite and http2 modules so far. :)
Re: Creating DLL
On Thursday, 16 June 2022 at 16:19:22 UTC, Ali Çehreli wrote: On 6/16/22 09:07, Sergeant wrote: This answer may be relevant: https://forum.dlang.org/post/t8diks$2l79$1...@digitalmars.com Ali, thank you, I'll take a look.
Re: Creating DLL
Adam, thank you again! Adding Initialize()/Terminate() to code and calling from my application as you suggested didn't help, unfortunately. Maybe the problem is in the scripting language I'm using (AHK) which is not designed to handle situations like these. In any case, appreciate your help!
Re: Comparing Exceptions and Errors
On Thursday, 16 June 2022 at 13:54:52 UTC, Steven Schveighoffer wrote: [scope (success) lowered to finally] [...] Furthermore I always thought of scope guards as a means for cleanup. Cleanup implies in my eyes removing things which have been used in a previous task. This intended use is documented here: https://tour.dlang.org/tour/en/gems/scope-guards Using scope guards makes code much cleaner and allows resource allocation and clean up code to be placed next to each other. These little helpers also improve safety because they make sure certain cleanup code is always called independent of which paths are actually taken at runtime. Performing a COMMIT is rather the opposite of cleanup: It makes (writes) changes to the database persistent. Semantically, you are just not undoing (rollback) the previous steps. Objection! Not doing a rollback is not the same as doing a COMMIT. Even not "semantically". Until the COMMIT has succeeded none of the changed data of the transactions is visible in other DMBS sessions.
Re: Creating DLL
On Thursday, 16 June 2022 at 16:37:34 UTC, Ali Çehreli wrote: Agreed but that excludes using the D runtime in 'static this' (and shared) blocks, right? It is runtime.initialize that calls those `static this` blocks. If my explicit call to Initialize is in a 'shared static this' This is backward - the explicit call to Initalize is in the exe. It'd look like: // this code is in the exe! pretend it is C++ or whatever HANDLE lib = LoadLibrary("my_d_lib.dll"); if(lib !is null) { auto fn = cast(typeof(init_func)) GetProcAddress("Initialize"); if(fn !is null) { fn(); // this now calls runtime.initialize which calls the static this blocks etc // you're now good to call any D functions } }
Re: Creating DLL
On 6/16/22 09:32, Adam D Ruppe wrote: > This is why an explicit initialization call is the preferred method - > there, the time it is called is well-defined by the user after initial > loading is complete. Agreed but that excludes using the D runtime in 'static this' (and shared) blocks, right? If my explicit call to Initialize is in a 'shared static this', then I can have only one such block, right? Ali
Re: Creating DLL
On Thursday, 16 June 2022 at 16:19:22 UTC, Ali Çehreli wrote: pragma (crt_constructor) You have to be pretty careful about this since it might not run in the order you expect. If there's two things in the program with a equal-priority crt constructor, they are run in arbitrary order. In a shared lib, there's also the possibility that loader locks are in place, and if it runs rt_init specifically, that can run D module constructors... which might load other libraries. Similar concerns apply to doing rt_init in DllMain. This is why an explicit initialization call is the preferred method - there, the time it is called is well-defined by the user after initial loading is complete.
Re: Creating DLL
On 6/16/22 09:07, Sergeant wrote: > May I ask one more question: why a code like this would work in > D-application but not in D-DLL? D programs generated by D compilers automatically initialize the D runtime. You can do the same with rt_init: pragma (crt_constructor) extern(C) int initialize() { // Can have any name return rt_init(); } And to deinitialize; pragma (crt_destructor) extern(C) int terminate() { // Can have any name return rt_term(); } Although, I haven't tested it with a DLL but with .so libraries on Linux... :/ This answer may be relevant: https://forum.dlang.org/post/t8diks$2l79$1...@digitalmars.com Ali
Re: Creating DLL
On Thursday, 16 June 2022 at 16:07:41 UTC, Sergeant wrote: May I ask one more question: why a code like this would work in D-application but not in D-DLL? (also I notice some other D functions don't work in DLL): Probably because the runtime not initialized properly. Export an Initialize() and Terminate() functions and call them from your application loading the dll. Inside those functions: export extern(C) void Initialize() { import core.runtime; Runtime.initialize(); } export extern(C) void Terminate() { import core.runtime; Runtime.terminate(); } If you call those the other functions should start working. (this is a fairly common thing libraries need to do, but it might be tricky if you are loading the dll into an uncooperative application, there's other hacks for that, but having your functions like this and the app calling them are the right way to do it)
Re: map! evaluates twice
On 6/16/22 00:58, Salih Dincer wrote: > I guess the developed cached() and cache() are different things, > right? cache caches only the front element. https://dlang.org/library/std/algorithm/iteration/cache.html > I tried cached() cached() is supposed to cache as many elements as needed as long as there are ranges that still reference the elements. Technically, cached() does not exist because only a couple of people have seen a draft of it. :) Ali
Re: Creating DLL
Adam thank you, it works now! May I ask one more question: why a code like this would work in D-application but not in D-DLL? (also I notice some other D functions don't work in DLL): import std.string; export extern(C) string my(string input) { string output = ""; auto lines = input.lineSplitter(); foreach (line; lines){ output ~= line; } return output }
Re: Creating DLL
On Thursday, 16 June 2022 at 13:57:48 UTC, Sergeant wrote: export int my(int a, int b) the name here is going to be mangled, so like "_D5mydll2myiiZi" or something like that. You might want to add `extern(C)` to it so it keeps the simple name "my", that might help.
Re: getSymbolsByUDA in constructor/member functions
On Thursday, 16 June 2022 at 13:27:25 UTC, frame wrote: But it looks like a compiler bug since the output of `getSymbolsByUDA` is just an alias sequence and nothing should happen before consuming it? Yes, this is a compiler bug. I've filed a report for it on bugzilla: https://issues.dlang.org/show_bug.cgi?id=23192
Creating DLL
Hi, I wonder if anyone knowledgeable can point me in the right direction here. I created DLL in Visual D, but when I try to use it by my application (AHK script), DLL itself is loaded ok, but error is set to "specified function could not be found inside the DLL". (Same DLL that I made in C++ works, but this doesn't somehow) Sample code looks like this: module my_dll; import core.sys.windows.windows; import core.sys.windows.dll; export int my(int a, int b) { // ... my code ... // return output; } mixin SimpleDllMain; I set "-shared" switch in VS. Is there anything I'm missing here? Thanks!
Re: Comparing Exceptions and Errors
On 6/16/22 6:07 AM, kdevel wrote: On Wednesday, 15 June 2022 at 20:46:56 UTC, Steven Schveighoffer wrote: [...] It has not harmed my code though. I tried throwing inside a scope guard, and it just works, I'm not sure why you can't throw in those? You can but that is not acceptable for the spec explicitly forbids that: https://dlang.org/spec/statement.html#scope-guard-statement Quote (again): "A [...] scope(success) statement may not exit with a throw [...]." I know. I'm not saying it's valid, I'm wondering *why* it's not valid, since it's trivial for the compiler to detect that code might throw (yet doesn't in this case), and the construct it lowers to (the finally clause) allows throwing. Note that the finally clause has all the same restrictions as scope(exit) and scope(success) *except* throwing. It might be an oversight in the spec. Furthermore I always thought of scope guards as a means for cleanup. Cleanup implies in my eyes removing things which have been used in a previous task. This intended use is documented here: https://tour.dlang.org/tour/en/gems/scope-guards Using scope guards makes code much cleaner and allows resource allocation and clean up code to be placed next to each other. These little helpers also improve safety because they make sure certain cleanup code is always called independent of which paths are actually taken at runtime. Performing a COMMIT is rather the opposite of cleanup: It makes (writes) changes to the database persistent. Semantically, you are just not undoing (rollback) the previous steps. How it's implemented in the database is up to them. -Steve
Re: getSymbolsByUDA in constructor/member functions
On Thursday, 16 June 2022 at 09:29:36 UTC, Arafel wrote: Classes can have static members just as structs, so I don't think you always need an instance for a class either. Well, ok. So if you call `getMember` from a member function, it adds the hidden `this` reference, and this has subtle consequences later on, even if `this.C` is practically just an alias for `C`. I still think this is a bug in `getMember`, although perhaps not as obvious as I first thought. Maybe you are right. I also don't see why the `this` reference should be there in the static call. But it looks like a compiler bug since the output of `getSymbolsByUDA` is just an alias sequence and nothing should happen before consuming it? This works fine too: ```d class C { @E int a; void foo() { alias seq = getSymbolsByUDA!(C, E); static foreach (i; 0 .. seq.length) { pragma(msg, hasUDA!(seq[i], E)); } } } ```
Re: Comparing Exceptions and Errors
On Thursday, 16 June 2022 at 11:38:40 UTC, kdevel wrote: On Thursday, 16 June 2022 at 11:28:32 UTC, bauss wrote: [...] https://dlang.org/spec/statement.html#scope-guard-statement Quote (again): "A [...] scope(success) statement may not exit with a throw [...]." [...] If the spec forbids it, but the compiler allows it, wouldn't it then be a bug? What does "it" referer to? The code, throwing in scope guard? The spec? The compiler? [yes, no, no] Throwing in a scope guard.
Re: Comparing Exceptions and Errors
On Thursday, 16 June 2022 at 11:28:32 UTC, bauss wrote: [...] https://dlang.org/spec/statement.html#scope-guard-statement Quote (again): "A [...] scope(success) statement may not exit with a throw [...]." [...] If the spec forbids it, but the compiler allows it, wouldn't it then be a bug? What does "it" referer to? The code, throwing in scope guard? The spec? The compiler? [yes, no, no]
Re: Comparing Exceptions and Errors
On Thursday, 16 June 2022 at 10:07:23 UTC, kdevel wrote: On Wednesday, 15 June 2022 at 20:46:56 UTC, Steven Schveighoffer wrote: [...] It has not harmed my code though. I tried throwing inside a scope guard, and it just works, I'm not sure why you can't throw in those? You can but that is not acceptable for the spec explicitly forbids that: https://dlang.org/spec/statement.html#scope-guard-statement Quote (again): "A [...] scope(success) statement may not exit with a throw [...]." Furthermore I always thought of scope guards as a means for cleanup. Cleanup implies in my eyes removing things which have been used in a previous task. This intended use is documented here: https://tour.dlang.org/tour/en/gems/scope-guards Using scope guards makes code much cleaner and allows resource allocation and clean up code to be placed next to each other. These little helpers also improve safety because they make sure certain cleanup code is always called independent of which paths are actually taken at runtime. Performing a COMMIT is rather the opposite of cleanup: It makes (writes) changes to the database persistent. If the spec forbids it, but the compiler allows it, wouldn't it then be a bug?
Re: Bug in dmd?
On Wednesday, 15 June 2022 at 16:53:13 UTC, mw wrote: Create a simple test case, file bug at: https://issues.dlang.org/ I tried. No luck.
Re: Comparing Exceptions and Errors
On Wednesday, 15 June 2022 at 20:46:56 UTC, Steven Schveighoffer wrote: [...] It has not harmed my code though. I tried throwing inside a scope guard, and it just works, I'm not sure why you can't throw in those? You can but that is not acceptable for the spec explicitly forbids that: https://dlang.org/spec/statement.html#scope-guard-statement Quote (again): "A [...] scope(success) statement may not exit with a throw [...]." Furthermore I always thought of scope guards as a means for cleanup. Cleanup implies in my eyes removing things which have been used in a previous task. This intended use is documented here: https://tour.dlang.org/tour/en/gems/scope-guards Using scope guards makes code much cleaner and allows resource allocation and clean up code to be placed next to each other. These little helpers also improve safety because they make sure certain cleanup code is always called independent of which paths are actually taken at runtime. Performing a COMMIT is rather the opposite of cleanup: It makes (writes) changes to the database persistent.
Re: Can I create a package with friendly modules
On Monday, 13 June 2022 at 06:05:03 UTC, Tejas wrote: Directory structure: ```sh src | |--- main_file.d | |---parent | |--- driver.d | |--- package.d | |--- thing | |--- package.d | |--- first.d | |--- second.d | |--- third.d ``` Code : `src/main_file.d`: ```d import parent; void main() { func(); } ``` `src/parent/package.d`: ```d module parent; public import driver; ``` `src/parent/driver.d`: ```d module parent.driver; import thing; void func() { S s;// from third.d auto t = first.a; // from second.d auto l = second.dbl;// from first.d } ``` `src/parent/thing/package.d`: ```d module parent.thing; public import first, second, third; ``` `src/parent/thing/first.d`: ```d module thing.first; import second; static this() { a = second.g; // can also access symbols within neighbouring modules } package(parent): int a; int b; string c; ``` `src/parent/thing/second.d`: ```d module thing.second; package(parent): int g; char p; double dbl; ``` `src/parent/thing/third.d`: ```d module thing.third; package(parent): struct S { int a; char c; string s; } private S private_struct; // can't access via parent package, since marked private ``` You run it via: `dmd -i -I=./parent -I=./parent/thing main_file.d` (I'm pretty sure it'll look far prettier using `dub`) Here, all the symbols that are within package `thing` are visible to package `parent` as well, but not visible to any other package/module Thanks, we all appreciate your efforts... SDB@79
Re: getSymbolsByUDA in constructor/member functions
On 16/6/22 10:55, frame wrote: On Thursday, 16 June 2022 at 08:23:20 UTC, Arafel wrote: This is not true. `getMember` can return the symbol to the instance or the type/alias, depending if you pass `this` or `Def`. The last is static. It makes no sense to use the attribute from a class without an instance. Classes can have static members just as structs, so I don't think you always need an instance for a class either. It seems the issue could be somewhere else: ``` import std.traits: getSymbolsByUDA; enum E; class C { @E int a; pragma(msg, __traits(getMember,C,"a").stringof); // `a` void foo() { pragma(msg, C.stringof); // `C` pragma(msg, __traits(getMember,C,"a").stringof); // `this.C.a` // Fails here //static foreach (sym; getSymbolsByUDA!(C, E)) { } } // But works here static foreach (sym; getSymbolsByUDA!(C, E)) { } } ``` So if you call `getMember` from a member function, it adds the hidden `this` reference, and this has subtle consequences later on, even if `this.C` is practically just an alias for `C`. I still think this is a bug in `getMember`, although perhaps not as obvious as I first thought.
Re: getSymbolsByUDA in constructor/member functions
On Thursday, 16 June 2022 at 08:23:20 UTC, Arafel wrote: As you can see, it's `getMember` who is returning a reference to the `this` instance. In my view, this is a bug according the documentation and examples [1]. It might be that classes behave differently, but then it should be documented. In fact, it shouldn't work at all and you'd need to instantiate Def: `getMember` should fail because `x` and `y` are not static. This is not true. `getMember` can return the symbol to the instance or the type/alias, depending if you pass `this` or `Def`. The last is static. It makes no sense to use the attribute from a class without an instance.
Re: getSymbolsByUDA in constructor/member functions
On 15/6/22 14:26, cc wrote: ```d import std.traits; class XML {} class Def { @XML { int x; int y; } int z; this() { static foreach (sym; getSymbolsByUDA!(Def, XML)) { } } } void main() { auto def = new Def; } ``` ``` test.d(12): Error: value of `this` is not known at compile time test.d(12): Error: value of `this` is not known at compile time ``` Why doesn't this work? There is nothing in the foreach body. ```d alias ALL = getSymbolsByUDA!(Def, XML); pragma(msg, ALL.stringof); ``` reports `tuple(this.x, this.y)`. Why is `this.` added? I think it's a bug either in the `getSymbolsByUDA` implementation, or actually rather in the `__traits` system. A workaround bypassing `getSymbolsByUDA`: ```d import std.traits; import std.meta: Alias; class XML {} class Def { @XML { int x; int y; } int z; this() { static foreach (sym; __traits(allMembers, Def)) {{ alias member = Alias!(__traits(getMember, Def, sym)); static if (hasUDA!(member, XML)) { pragma(msg, member.stringof); pragma(msg, sym); } }} } } void main() { auto def = new Def; } ``` As you can see, it's `getMember` who is returning a reference to the `this` instance. In my view, this is a bug according the documentation and examples [1]. It might be that classes behave differently, but then it should be documented. In fact, it shouldn't work at all and you'd need to instantiate Def: `getMember` should fail because `x` and `y` are not static. Interestingly, `hasUDA` (or rather `__traits(getAttributes, ...)`) later doesn't care about the dangling `this` reference, so I'm not sure who is to blame here... in any case, at the very least the documentation doesn't match the actual behavior. [1]: https://dlang.org/spec/traits.html#getMember
Re: Convering strings containing number
On Wednesday, 15 June 2022 at 04:39:21 UTC, Mike Parker wrote: ```d str[3..4].to!int; ``` Thanks, I got the solution based on your answer. I also created different slicing functions. They work just fine without the need for conversion: ```d T solKes(string str, size_t a, size_t l) { import std.conv; const b = a + l; return str[a + 1..b].to!T; } T kalKes(string str, size_t a, size_t l) { import std.conv; const b = a + l; return str[b - 1..b].to!T; } T sagKes(string str, size_t a, size_t l) { import std.conv; const b = a + l; return str[a..b - 1].to!T; } T tekKes(string str, size_t a, size_t l) { import std.conv; return str[a..a + l].to!T; } ``` Thanks again... SDB@79
Re: map! evaluates twice
On Friday, 10 June 2022 at 22:10:10 UTC, Ali Çehreli wrote: [...] I am trying to finish a .cached range algorithm that caches all elements that are in use. (It must drop old elements so that an infinite range does not require infinite cache.) It is supposed to evaluate elements only once. I guess the developed cached() and cache() are different things, right? I tried cached(), it works fine and cleverly designed... SDB@79
Re: getSymbolsByUDA in constructor/member functions
On Wednesday, 15 June 2022 at 12:26:40 UTC, cc wrote: Why doesn't this work? There is nothing in the foreach body. ```d alias ALL = getSymbolsByUDA!(Def, XML); pragma(msg, ALL.stringof); ``` reports `tuple(this.x, this.y)`. Why is `this.` added? I can only answer this partially, I guess `this` is just added because `getSymbolsByUDA` want an instance but `@XML` is only seen as a type. As instance, you need to write `@XML()` instead: ```d class XML { static opCall() { return new XML(); } } class Def { @XML() { int x; int y; } int z; this() { static foreach (sym; getSymbolsByUDA!(Def, XML)) { } } } ```