Re: Can you access the same classes from C++ and D and vise versa, or do the classes have to not form dependency cycle?
Pretty new video from ContextFreeCode covers interop with C++ D also mentioned there :) https://youtu.be/RdypYCxhWtw
Re: Is there a way to
On Sunday, 11 September 2022 at 00:56:39 UTC, Adam D Ruppe wrote: On Sunday, 11 September 2022 at 00:32:18 UTC, Kyle Ingraham wrote: I can't use default parameters because I want to be able to call the delegate with arguments extracted from a URL path at runtime Some kind of wrapper might not only be your best option, it might be your only option. Your delegate would be like string callWith(string[][string] webArgs) and you can generate a wrapper to convert arguments and call the original function. I'm mucking about with a custom router for vibe-d and trying to setup the ability for handlers to have different parameter signatures. I'd be surprised if vibe doesn't already have this built in, my web frameworks have since before vibe was born. (my implementation btw does the wrapper thing like described above) Thanks for the wrapper suggestion Adam. I tried that out and got the functionality that I wanted. I wrap the handler in a delegate that has the signature I need. vibe-d does have a way to achieve something similar but I'm working on a router that does a bit more path validation before calling a handler.
Re: Function attribute best practices
On Mon, Sep 12, 2022 at 10:08:29AM -0700, Ali Çehreli via Digitalmars-d-learn wrote: [...] > What I meant was > > - if I put 'pure' etc. on my templatized code, > > - and then tested with a 'pure' unittest, > > I wouldn't know that the gratuitous use of my 'pure' on the member > function was wrong. I would be fooling myself thinking that I smartly > wrote a 'pure' member function and a 'pure' unittest and all worked. > Wrong idea! :) That's an easy one: write a unittest where you instantiate Foo with a deliberately-impure type (e.g., .front references some local variable in the unittest outside the aggregate). If there was a gratuitous `pure` in Foo, this will fail to compile. T -- "I'm running Windows '98." "Yes." "My computer isn't working now." "Yes, you already said that." -- User-Friendly
Shorten template arguments in debug symbols?
If I have a template that accepts tokenized code to build something, it will create the exact debug symbol with this argument supplied which makes the symbols hard to read and/or waste of memory. Is there any way to truncate or transform it like that? ``` app.fun!"writeln(\"Hello, World\");" => app.fun!"_sym__13" ``` I can pass a pointer to the template but that results in the same symbol. Getting the raw integer value of the pointer instead isn't allowed in compile it seems.
Re: Function attribute best practices
On 9/12/22 11:29, Steven Schveighoffer wrote: > So you are thinking about this the wrong way I believe. Clearly. > When you put `pure` on a template function, you are saying "only > instantiations where this function can be pure are allowed". Makes sense. I was trying to put as many attributes as possible, being proud like, "look: my function is pure, @nogc, etc." Ali
Re: Function attribute best practices
On Monday, 12 September 2022 at 16:14:42 UTC, Ali Çehreli wrote: Is this accurate: Because Foo is a template, it should not put any attribute on member functions? Or only member functions that use a member that depends on a template parameter? And non-members that are templates? Yes. Except for `@trusted`, explicit attributes on template code are a smell. Is putting function attributes on unittest blocks for catching such issues? @nogc nothrow pure @safe unittest { // ... } No, it isn't because unless my unittest code is impure, I can't catch my incorrect 'pure' etc. on my member functions. To test that a particular piece of code *isn't* pure, you can use the following idiom: static assert(!__traits(compiles, () pure { // code to test goes here });
Re: Function attribute best practices
On 9/12/22 12:14 PM, Ali Çehreli wrote: What are best practices here? attributes such as `pure`, `@nogc`, `nothrow`, `@safe` should all be left to inference. Either the function can do those attributes, or it cannot. attributes such as `const` or `inout` are different -- these are *not* inferred, and you need to use introspection to determine these. Which is really unfortunate, because there's no easy way to say "const if this is allowed" -- you have to repeat the implementation. Is this accurate: Because Foo is a template, it should not put any attribute on member functions? Or only member functions that use a member that depends on a template parameter? And non-members that are templates? It is scary because Foo works just fine until it is used with impure code. It's not that scary, because I'm not sure what one would expect passing in an impure function to the template. Is putting function attributes on unittest blocks for catching such issues? @nogc nothrow pure @safe unittest { // ... } No, it isn't because unless my unittest code is impure, I can't catch my incorrect 'pure' etc. on my member functions. Yes, this is exactly what you should do. You don't need to unittest compiler inference -- just expect this to work. What you want to test is if there's any code you wrote for Foo can make impure something that should be pure. Things that Foo calls on its parameter should not count towards your test, that's on the caller. So for instance, create a dummy range that is pure, nogc, nothrow, safe, and test Foo as a wrapper on that range, attributing the unittest with that. And if that works, you should be good. You shouldn't have to test that if you pass in an impure function, the thing becomes impure. Caveat: if you have code that is compiled differently based on those attributes, you should test those cases too to ensure coverage of the code in question. -Steve
Function attribute best practices
The following range Foo is trying to be helpful by adding as many attributes as it can ('const' is missing because ranges cannot be 'const' because at least popFront() needs to be mutable): import std.algorithm; struct Foo(R) { R r; int i; bool empty() @nogc nothrow pure @safe scope { return r.empty; } auto front() @nogc nothrow pure @safe scope { return r.front; } auto popFront() @nogc nothrow pure @safe scope { r.popFront(); } } auto foo(R)(R r) { return Foo!R(r); } int count; void main() { [ 1, 2 ] .map!((i) { ++count;// <-- Impure return i; }) .foo; } Of course there are compilation errors inside the member functions because e.g. r.front that it dispatches to is not pure (it touches the module variable 'count'): Error: `pure` function `deneme.Foo!(MapResult!(__lambda1, int[])).Foo.front` cannot call impure function `deneme.main.MapResult!(__lambda1, int[]).MapResult.front` (Other attributes would cause similar issues if e.g. the lambda were @nogc.) What are best practices here? Is this accurate: Because Foo is a template, it should not put any attribute on member functions? Or only member functions that use a member that depends on a template parameter? And non-members that are templates? It is scary because Foo works just fine until it is used with impure code. Is putting function attributes on unittest blocks for catching such issues? @nogc nothrow pure @safe unittest { // ... } No, it isn't because unless my unittest code is impure, I can't catch my incorrect 'pure' etc. on my member functions. Help! :) Ali
Re: Function attribute best practices
On 9/12/22 09:48, H. S. Teoh wrote: >> @nogc nothrow pure @safe >> unittest >> { >> // ... >> } >> >> No, it isn't because unless my unittest code is impure, I can't catch >> my incorrect 'pure' etc. on my member functions. > [...] > > Sure you can. The `pure unittest` code obviously must itself be pure > (otherwise it wouldn't compile). If Foo introduces impure behaviour, > then the unittest, being pure, wouldn't be allowed to call Foo's impure > methods, which is what we want. What's the problem? There was a problem until you and others put me straigth. :) What I meant was - if I put 'pure' etc. on my templatized code, - and then tested with a 'pure' unittest, I wouldn't know that the gratuitous use of my 'pure' on the member function was wrong. I would be fooling myself thinking that I smartly wrote a 'pure' member function and a 'pure' unittest and all worked. Wrong idea! :) Now I know I must leave attributes as much to inference as possible. Ali
Re: Function attribute best practices
On 9/12/22 1:08 PM, Ali Çehreli wrote: On 9/12/22 09:48, H. S. Teoh wrote: >> @nogc nothrow pure @safe >> unittest >> { >> // ... >> } >> >> No, it isn't because unless my unittest code is impure, I can't catch >> my incorrect 'pure' etc. on my member functions. > [...] > > Sure you can. The `pure unittest` code obviously must itself be pure > (otherwise it wouldn't compile). If Foo introduces impure behaviour, > then the unittest, being pure, wouldn't be allowed to call Foo's impure > methods, which is what we want. What's the problem? There was a problem until you and others put me straigth. :) What I meant was - if I put 'pure' etc. on my templatized code, - and then tested with a 'pure' unittest, I wouldn't know that the gratuitous use of my 'pure' on the member function was wrong. I would be fooling myself thinking that I smartly wrote a 'pure' member function and a 'pure' unittest and all worked. Wrong idea! :) So you are thinking about this the wrong way I believe. When you put `pure` on a template function, you are saying "only instantiations where this function can be pure are allowed". Essentially, that's *you* telling your *user* "this must be pure!". If your intent is to *enforce* pure functions only, then that's what you do. If your intent instead is to ensure that given proper parameters, the function will be pure, then the answer is to unittest. I will say, sometimes this gets really annoying. Like if the unittest fails, you get very little information about *why* it's not working. i.e. you expect the inference to be pure, but it's not. All you get is "impure unittest can't call impure function foo(...)". Figuring out the misinference cause is a chore today. I wish it would be easier. -Steve
Re: Function attribute best practices
On 9/12/22 10:29, H. S. Teoh wrote: write a unittest where you instantiate Foo with a deliberately-impure type Yes. A current on-topic thread on the difficulties of covering all corner cases: https://forum.dlang.org/thread/dmnfdqiplbldxkecp...@forum.dlang.org Ali
Re: Function attribute best practices
On Mon, Sep 12, 2022 at 09:14:42AM -0700, Ali Çehreli via Digitalmars-d-learn wrote: [...] > struct Foo(R) { > R r; > int i; > > bool empty() @nogc nothrow pure @safe scope { > return r.empty; > } > > auto front() @nogc nothrow pure @safe scope { > return r.front; > } > > auto popFront() @nogc nothrow pure @safe scope { > r.popFront(); > } > } [...] > What are best practices here? > > Is this accurate: Because Foo is a template, it should not put any > attribute on member functions? Or only member functions that use a > member that depends on a template parameter? And non-members that are > templates? IMO, attributes on members of template aggregates should be omitted, *except* where you want to enforce that attribute on all instantiations. E.g., if there is some kind of semantic requirement that a method should not mutate the state no matter what, then you could put `const` on it. Otherwise, I'd say let the compiler infer the actual attributes, and use appropriately-crafted unittests to catch attribute violations in the template code. The reason for this is to maximize generality: 1) If some user wants to use your code with their own data type, but they needed it to be, e.g., impure for some reason, or throwing, then your template should "gracefully degrade" rather than refuse to compile (because instantiating Foo with a type whose .front is throwing, for example, would be a compile error). To do this, we must let the compiler infer attributes as much as possible -- so for an instantiation with a nothrow .front it would infer nothrow, for example. But for an instantiation involving a throwing user type, the compiler would infer .front as throwing. 2) If some user uses your code in nothrow code, then your template should not introduce throwing behaviour which would fail to compile. For this, you should use appropriately-attributed unittests to ensure that, eg., when Foo is instantiated with a non-throwing type it does not introduce something that throws. > It is scary because Foo works just fine until it is used with impure > code. Exactly, this is issue (1) above. > Is putting function attributes on unittest blocks for catching such > issues? > > @nogc nothrow pure @safe > unittest > { > // ... > } > > No, it isn't because unless my unittest code is impure, I can't catch > my incorrect 'pure' etc. on my member functions. [...] Sure you can. The `pure unittest` code obviously must itself be pure (otherwise it wouldn't compile). If Foo introduces impure behaviour, then the unittest, being pure, wouldn't be allowed to call Foo's impure methods, which is what we want. What's the problem? T -- Fact is stranger than fiction.
Linker Error with Template Function
I am writing a library where I would like to be able to store instances of a type of class to an associative array for later usage. Each class stored has to implement a function as part of the required interface. The argument given is always the same type but the return value should be flexible. I solved this with an interface: ```d interface PathConverter { T toD(T)(const string value) @safe; } ``` That interface lets me type the associative array and any other part of the library that needs to use implementers of that interface e.g. ```d PathConverter[string] converters; ``` The problem I'm running into is that when compile the library I receive the following error during linking: ``` error LNK2019: unresolved external symbol _D3app13PathConverter__T3toDTAyaZQjMFNfxAyaZQp referenced in function _D3app14TypedURLRouter__T10setHandlerTPFNfC4vibe4http6server17HTTPServerRequestCQBlQBjQBh18HTTPServerResponseAyaZvZQDmMFEQDaQCy6common10HTTPMethodQBlQEhZ__T9__lambda4TQEvTQDoTASQGt16PathCaptureGroupZQBrMFNfQGiQFaQBlZv fatal error LNK1120: 1 unresolved externals Error: linker exited with status 1120 ``` The call is within a delegate to a function that returns a class instance from the associative array. At runtime I fill the associative array. The call looks like this: ```d tailArgs[i] = getPathConverter("id string").toD!(Parameters!(handler)[i])("string to convert"); ``` Am I running into this error because the linker can't find the instantiation of the template method? How would I give the linker the information it needs? Is there a better way to have an interface with flexible return values?
Re: Function attribute best practices
On Mon, Sep 12, 2022 at 02:29:58PM -0400, Steven Schveighoffer via Digitalmars-d-learn wrote: [...] > If your intent is to *enforce* pure functions only, then that's what > you do. If your intent instead is to ensure that given proper > parameters, the function will be pure, then the answer is to unittest. > > I will say, sometimes this gets really annoying. Like if the unittest > fails, you get very little information about *why* it's not working. > > i.e. you expect the inference to be pure, but it's not. All you get is > "impure unittest can't call impure function foo(...)". Figuring out > the misinference cause is a chore today. I wish it would be easier. [...] +1, we need better diagnostics around this. I wonder if it could be done this way: whenever the compiler infers attributes for some function F, along with the inferred attributes it also attaches a list of locations where each attribute was excluded from the inference. For example, if F was inferred as impure, the compiler would also keep a reference to the first line where an impure operation was performed in F. Whenever pure code tries to call F, the compiler would print out this reference (file + line + column) along with the error message. I.e., "pure function G cannot call impure function F because impure was inferred from line 1234 in F." Obviously, this applies only to functions with inferred attributes; if the attribute was explicitly in the code, then there's nothing else to say. Since functions with inferred attributes always must have their bodies accessible (otherwise inference cannot be done), it's guaranteed that the aforementioned reference can always be found. // In the meantime, my usual approach to debugging this sort of problem is to explicitly (temporarily) mark the target function pure, and recompile to find out what in the function made it impure. If it's a call to another inferred function, then mark *that* function pure too, and recompile, etc., until I arrive at the statement that first made it impure. This doesn't always work, though. Sometimes forcefully marking something pure will break the compile in other places, making it a pain to debug (usually involving making a local copy of the function and redirecting calls to/from it). The compiler really should be giving us this information rather than making us figure it out ourselves. T -- Ignorance is bliss... until you suffer the consequences!
Re: Linker Error with Template Function
On Tuesday, 13 September 2022 at 00:57:58 UTC, Kyle Ingraham wrote: I am writing a library where I would like to be able to store instances of a type of class to an associative array for later usage. Each class stored has to implement a function as part of the required interface. The argument given is always the same type but the return value should be flexible. I solved this with an interface: ```d interface PathConverter { T toD(T)(const string value) @safe; } ``` https://dlang.org/spec/template.html#limitations Templates cannot be used to add non-static fields or virtual functions to classes or interfaces. You *should* get an error from the compiler for trying to do this, instead of just a linker error somewhere else down the line, but either way it's not going to work. You'll have to find another solution.
Re: Linker Error with Template Function
On Tuesday, 13 September 2022 at 01:46:14 UTC, Paul Backus wrote: On Tuesday, 13 September 2022 at 00:57:58 UTC, Kyle Ingraham wrote: I am writing a library where I would like to be able to store instances of a type of class to an associative array for later usage. Each class stored has to implement a function as part of the required interface. The argument given is always the same type but the return value should be flexible. I solved this with an interface: ```d interface PathConverter { T toD(T)(const string value) @safe; } ``` https://dlang.org/spec/template.html#limitations Templates cannot be used to add non-static fields or virtual functions to classes or interfaces. You *should* get an error from the compiler for trying to do this, instead of just a linker error somewhere else down the line, but either way it's not going to work. You'll have to find another solution. Thanks for the spec help Paul. I must've skirted around the compiler somehow. This is a minimal example that triggers the linker error: ```d interface PathConverter { T toD(T)(string value); } class NumberConverter(T) : PathConverter { T toD(T)(string value) { import std.conv : to; return to!T(value); } } alias IntConverter = NumberConverter!int; void main() { PathConverter[string] allConverters; allConverters["int"] = new IntConverter; int converted = allConverters["int"].toD!int("9"); } ``` Any suggestions for being able to call one function for any instance given but maintain flexible return types?
How could I fix (debug) the VisualD plugin so that it actually works with the folders / files seen in Windows 10 file man.?
As you may already know if you want to move a file or rename a folder in VisualD, you can't simply do it. I've even had to edit the project file with Notepad++ in order to repair it. So, I'm humbly asking how can we fix this? I'm considering doing something in C++ which I'd rather not because I'm reluctant about all the memory leaks I'm going to make. Right now my project folder lay in disarray and I don't feel like going through fixing the folders for the 20th time. So has anyone got a workaround for these issues (it has many). I apologize for not recalling exactly the problem, but if you use VisualD you will be made aware of them if you don't want to keep all your files in single folder.
Re: Can you access the same classes from C++ and D and vise versa, or do the classes have to not form dependency cycle?
On Sunday, 11 September 2022 at 02:14:51 UTC, zjh wrote: On Saturday, 10 September 2022 at 22:07:32 UTC, Ali Çehreli wrote: On 9/10/22 13:04, Daniel Donnell wrote: > https://dlang.org/spec/cpp_interface.html At DConf, Manu indicated that that page is outdated and that D's C++ support is actually a lot better. Update it quickly, This is a big selling point. So what is the answer here? I'm not sure what they were getting at...