Re: phobo's std.file is completely broke!
On Saturday, 15 September 2018 at 23:06:57 UTC, Jonathan M Davis wrote: On Saturday, September 15, 2018 6:54:50 AM MDT Josphe Brigmo via Digitalmars-d wrote: On Saturday, 15 September 2018 at 12:38:41 UTC, Adam D. Ruppe wrote: > On Saturday, 15 September 2018 at 10:57:56 UTC, Josphe Brigmo > > wrote: >> Phobos *NEEDS* to be modified to work with these newer OS's. > > You need to look at the source code before posting. The code > for remove is literally > > DeleteFileW(name); > > it is a one-line wrapper, and obviously uses the unicode > version. > > https://github.com/dlang/phobos/blob/master/std/file.d#L1047 It doesn't matter, the fact is that something in phobos is broke. Do you really expect me to do all the work? The fact that using executeShell or "\\?\" solves 90% of the problems(maybe all of them) proves that phobos is not up to par. Using std.file should be on par with using the Windows API from C or C++. It doesn't try to fix the arguably broken behavior of the Windows API with regards to long paths but requires that the programmer deal with them just like they would in C/C++. The main differences are that the std.file functions in question use D strings rather than C strings, and they translate them to the UTF-16 C strings for you rather than requiring you to do it. But they don't do anything like add "\\?\" for you any more than the Windows API itself does that. If you consider that to be broken, then sorry. For better or worse, it was decided that it was better to let the programmer deal with those intricacies rather than trying to tweak the input to make it work based on the idea that that could have undesirable consequences in some circumstances. On some level, that does suck, but the Windows API does not make it easy to make this work like it would on a *nix system without introducing subtle bugs. Do you not realize how moronic that is though? You are expecting each user to know the correct behavior and to compensate for it. With that approach all you are doing is creating a whole mess of problems. See, there is only one phobos but many users of phobos. You are expecting every single user to deal with it instead of dealing with it in one place. Your reason is because "It's a problem with windows". Both are "We'll just kick the can down the road cause the other guy kicked it to us". Now, this is great if you want repeat customers and don't care about their sanity but terrible to make progress. If you find that the std.file functions don't work whereas using the same input to the Windows API functions in C/C++ would have, then there's a bug in the D code, and it needs to be fixed, but if it acts the same as the C/C++ code, then it's working as intended. And that is precisely the problem. For some reason you don't get that because it is broke in windows, and you following windows, you are just perpetuating the "brokeness". This is why D sucks the way it does, because of these types of mentalities of "It's not our problem". You basically expect the customers, before eating to wash the dishes, cook the meal, set the table, etc. All you do is provide the food, and not all that great food... and when they are done you expect them to wash the dishes against, clean up their mess, and pay the bill. I'm sure you'll never realize how wrong your mentality is, but at least you could do everyone a favor and think about what you are actually saying. Your logic might have a valid reason, but it is not producing the results that make the world a better place. D won't ever get any traction with the wrong mentalities and I don't even know how it has made it this far. Trust me, if you expect the user to know everything and also solve all the problems over and over and over and over, you will have very few users. But, keep on doing what your doing, it's worked so well, we will see how far it gets D. If D is as perfect as you think it is, why isn't everyone jumping on board? I know, you have answers for that one too!
Re: [OT] My State is Illegally Preventing Me From Voting In The Upcoming 2018 US Elections
Don't worry, your vote actually does not matter either way, so no reason to get upset. Voting is simply a census count to find out how many people still believe that voting still works. If you have 50M eligible voters and 25 million vote, it means you have about 50% of those that believe the government and politics is working as it should. This is a win for the government. They know when it drops too low that they better go to plan B.
Re: phobo's std.file is completely broke!
and the biggest problem is that I don't see any motivation in the D community to make things better. Anyone with the abilities to make it better in the right way simply does not care about having a proper plan to get D to where it needs to be. Hence, it gives me no hope that D will ever reach a status of usability that it should have. What's the point of all the fancy meta language capabilities if ultimately they are ineffective due to the ecosystem of D sucking? What I have learned from D: 1. It has an amazing meta programming language. Of course most functional languages have even better but D allows systems programming and is also fast. 2. I am the most unproductive in D. While I can write meta code that does things 10x easier, it takes me 10x longer to code, debug, and revision... not because the meta programming is difficult but because the errors are pathetic(most of the time a huge amount of noise is created in the errors making me sift through a bunch of junk just to figure out what is going on) and usually not even related to the real problem. Just miss a semicolon and your program can explode with errors having nothing to do with that. 3. No one seems to care about fixing these deficits of D but only on making it more "attractive" on paper. 4. One can't expect a program to work properly, EVER! In other languages, when I write something, debug it, and test it, I am sure that it will generally work fine after and not have to worry in any way shape or form... and when it does break, it is usually obvious and easy to fix. Be it some flaw in the language(such as what I have experienced with the paths and other things) or updating compilers or library features and it breaking something, etc. All these problems, which are well known, and I'd bet you that D has the most forum posts of problems dealing with these types of things than any other language, are rarely addressed. I mean, look at bugzillia... how many bugs have 5+ years and no one has done a damn thing? And these bugs being critical in many cases. Again, this is the whole attitude "It's not our problem"... Of course, once one of the hardcore D guys run in to the bug after actually doing some real programing of real applications, they might have to fix it and then it will get fixed. It's not that D is terrible, it's that it's not great and it has the potential to be great but either no one realizes it or gives a shit. All you guys put in your life energy in to making D what it is but won't put in the energy to strengthen the weaknesses. When you get tired of D, say like Dicebot, you'll leave and some other *idiot* will come along and have the same attitude and the process repeats. This is why it's called "kicking the can down the road" and why I used the term idiot(not meaning a lack of intelligence but a lack of foresight). And this is why after 10+ years of D not really much has changed(even though a lot has changed). After another 20 years, same thing. A lot will change, but the same all problems(the weaknesses) will exist.
Re: phobo's std.file is completely broke!
On Saturday, 15 September 2018 at 13:37:29 UTC, Vladimir Panteleev wrote: On Saturday, 15 September 2018 at 12:59:25 UTC, Josphe Brigmo wrote: The libraries are already copying the user's string and adding the 0 termination prior to calling the windows api, so it seems to me to be a reasonable place to make other modifications if they are needed to accomplish the intended operation. That only works for absolute paths. And that is all I'm using... Yet it is somehow my fault for not reading the source of phobos to make sure it is using unicode api? Which it is and it's still failing! Right. The problem is on the OS side. again, this is why I generally end up regretting using D. Can you list some programming languages that achieve this task in a way you approve of? Plenty, pick just about any one. C#, Haskell, javascript, lua, python, perl, C++(yes, c++, we are not talking about language features but usability). The simple fact is that C++ can be used to do anything almost 100% correct while D can fail. D is only a better language, not a better compiler(except it's speed). You know, there is so many problems with D but you do not care to see them. Take the way the library is designed. strip? trim is the standard. Then you get things like exists. Instead of fileExists or dirExists. Not all that bad though, but what about slurp and others that are just odd and for people that are not professional D programmers requires one to look up the name of what they are trying to do. I don't know how many times I have typed in a name of a function that is "standard" only to find out that is not what D used but some odd ball name... or worse, it differs by a character or two. You can pretend all you want about how great D is, but D is not great, it is just great at some things. That goes for all languages, but at least some languages let you enjoy the experience. With D, it seems the hard core users seem not to care about the experience or think it's great because they don't know how much better it can be. This is the typical mindset with D. There are all these "minor" problems that people(the D community pretends are all that big a deal but when you couple all these problems together it results in a very unpleasant programming experience(out of all the languages I've programmed in D is about the worse in this regard). Please drop this tone, it will make you no allies. I'm not here to make allies. Truth is not subjective and it doesn't depend on how many friends you have that believe in the same BS.
Re: phobo's std.file is completely broke!
On Saturday, 15 September 2018 at 13:23:34 UTC, Rubn wrote: On Saturday, 15 September 2018 at 12:59:25 UTC, Josphe Brigmo wrote: This is the typical mindset with D. There are all these "minor" problems that people(the D community pretends are all that big a deal but when you couple all these problems together it results in a very unpleasant programming experience(out of all the languages I've programmed in D is about the worse in this regard). You keep saying you regret using D, well let's go to C++ then. How are you going to solve this problem with C++? It's a problem that can be worked around, if you are using the latest version of Windows it can be fixed by simply setting a registry entry. Then **all** your applications on your system will work with long file names. Actually, I'd use C#, as it is a well thought out language that is consistent in nature and runtime. But, the damn problem, which you seem to not understand, is that once one chooses D to do something in and puts in time, then only do they find out how poor it works and then the choice is made to continue using it hoping for the best or start over from scratch. The problem is that I'm an optimist at heart but every time that is tested with D. It works for something amazingly well, for other things amazingly poor. But with peoples attitudes like yours it seems this will always be the case for D. It would be nice if people did what was required to make D as great as it could be rather than having the attitude "If you don't like it leave". Usually when someone comes in to bitch about a problem with D(which is usually legit), there is a wall of "it's not our problem" attitudes.
Re: x64 Privileged instruction
On Saturday, 15 September 2018 at 14:57:20 UTC, Vladimir Panteleev wrote: On Thursday, 13 September 2018 at 05:50:53 UTC, Josphe Brigmo wrote: Privileged instruction Lots of code. I pretty much always get this error. Something must have gone really wrong to get this error. Most likely, the CPU instruction pointer ended up in a memory area without any code in it. Windows exception handling is tricky (see Don/Walter's recent discussion), but basic cases should be well-covered by the compiler/runtime test suite. So, I suspect one of the following happened: - Your program is exhibiting an edge case and uncovering a bug not covered by the test case. If this is the case, please reduce your program to a minimal, self-contained example, and file a bug report. - There is a bug in your program that is causing its memory to be corrupted. Using @safe can help narrow it down (https://dlang.org/spec/memory-safe-d.html). - There is something specific to your machine that causes the problem to occur there, but not on the test runners. This could happen e.g. due to software which alter behavior of other programs (like through DLL injection), or using a specific Windows version. You can eliminate this possibility by running the DMD test suite. When I run the code in x86 the error is from a throw and is a first chance exception and the error message is shown as normal. In x64, no changes to source, it is a privileged instruction error. I have always gotten these types of errors on x64 and, it may be my machine, it has happened with many dmd versions, visual D and visual studio... I doubt it is my machine and it seems to be completely dmdx64's fault. Basically I just program in x86 most of the time and compile for x64 because of things like this.
Re: phobo's std.file is completely broke!
For example, https://issues.dlang.org/show_bug.cgi?id=8967 ` Jay Norwood 2014-03-18 18:01:59 UTC More surprising is attempting to remove a long directory path and having an exception occur. The libraries are already copying the user's string and adding the 0 termination prior to calling the windows api, so it seems to me to be a reasonable place to make other modifications if they are needed to accomplish the intended operation. ` Which is almost 5 years old and exactly the same problem I'm having... Yet it is somehow my fault for not reading the source of phobos to make sure it is using unicode api? Which it is and it's still failing! and, of course, no followup on that bug has been done... again, this is why I generally end up regretting using D. I thought it would be easier to write a small utility in a few hours and it's turned in to a few days. Any other sane language and I would have been done with 1/10th of the frustration and I'd actually have working code(which I still don't) because rmdir is till failing for some reason. This is the typical mindset with D. There are all these "minor" problems that people(the D community pretends are all that big a deal but when you couple all these problems together it results in a very unpleasant programming experience(out of all the languages I've programmed in D is about the worse in this regard).
Re: phobo's std.file is completely broke!
On Saturday, 15 September 2018 at 12:38:41 UTC, Adam D. Ruppe wrote: On Saturday, 15 September 2018 at 10:57:56 UTC, Josphe Brigmo wrote: Phobos *NEEDS* to be modified to work with these newer OS's. You need to look at the source code before posting. The code for remove is literally DeleteFileW(name); it is a one-line wrapper, and obviously uses the unicode version. https://github.com/dlang/phobos/blob/master/std/file.d#L1047 It doesn't matter, the fact is that something in phobos is broke. Do you really expect me to do all the work? The fact that using executeShell or "\\?\" solves 90% of the problems(maybe all of them) proves that phobos is not up to par. It's simple as that. just because it uses unicode does not mean squat if it doesn't work. The docs from microsoft said that the unicode functions are suppose to not have the limitation, but that doesn't mean that using them is the only fix. The fact is, I write a directory parser and it failed, then I spend the next day trying to get something relatively easy to be fixed that should already have been fixed. I'm also not the only one with the problem. Maybe you should spend some time on windows and using std.file with long paths. I bet you have actually never done it so you are obviously to the problems. There may be "simple" fixes, but the fact is that something is wrong or else my code would work(you can blame me all you want but the facts are the facts and the code only breaks on long file names). https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation It is a bit more complicated than just saying that phobos is doing it's job. Of course, it could be some windows issue but given that https://issues.dlang.org/show_bug.cgi?id=8967 The point is that these things should be thoroughly tested before blaming the end user. Whatever is going on, it should. File IO is very basic and common and for code to break silently or in ways that does not make sense is bad, regardless of if I existed in this universe or not. How hard is it for phobos to detect long files and absolute files and such and prepend if necessary?
Re: phobo's std.file is completely broke!
On Saturday, 15 September 2018 at 10:48:10 UTC, Vladimir Panteleev wrote: On Friday, 14 September 2018 at 19:42:39 UTC, Josphe Brigmo wrote: "It doesn't matter. When I compile a program or DLL in C/C++ and many other languages, I use the Windows headers. These headers define MAX_PATH to 260. So the program will have the limit set by compile time, no matter what you do in the OS later on. There is no advantage with this setting for now, except that you now *may* pass long paths to API functions w/o the infamous \\?\ prefix, but you have no guarantee for it. So to make this have the advantage that some people think it will provide, we'd need: wait until the Windows headers (in Visual Studio, or the DDK, or the Platform SDK or whatever) is properly updated, i.e. the runtime libs may take advantage of it wait until MS forces this setting to be enabled all the time, otherwise it's useless when it stays optional not checking any more for the target OS in the application, assuming Win 10 with the mentioned update The latter will only be the case when an app can't target an Windows version below 10. So all in all it will take years until we get the advantage for standalone applications, and for TC these things don't matter for now anyway. " enum size_t MAX_PATH = 260; MAX_PATH only applies to static arrays (usually on the stack), i.e. code which does this: void doSomething() { char fileName[MAX_PATH]; ... SomeWindowsAPI(fileName); } D almost never does this - instead, it uses dynamically sized buffers which fit the entire file name. The only times MAX_PATH is used in Phobos is: - thisExePath (return path to current .exe file) - tempDir (return path to temporary directory) Obviously neither of these is related to the problems you're seeing. You are missing the point, MAX_PATH is more than just phobos. It's built in to the windows design. Windows enforces it. All ansi api calls are limited by MAX_PATH. The way to fix it is to use the wide api calls which are not limited or to use other tricks. Phobos *NEEDS* to be modified to work with these newer OS's. You wouldn't like it if phobos limit something that it didn't need that you would use, would you? File operations are so common that this stuff is relevant to all that use windows(and some that don't).
Re: remove file access denied(remove broke)
On Saturday, 15 September 2018 at 06:13:29 UTC, bauss wrote: On Friday, 14 September 2018 at 16:55:21 UTC, Josphe Brigmo wrote: On Friday, 14 September 2018 at 15:21:21 UTC, H. S. Teoh wrote: [...] It woudln't help. I'm dealing with over a million files and you'd need those files too. But basically all I have done is created a new rename function: void removeFile(string fn) { if (!isDir(fn)) { // remove(fn) setAttributes(fn, 0x80); auto ls = executeShell(`del /F /Q "`~fn~`"`); if (ls.status != 0) throw new Exception("Cannot delete file `"~fn~"`!"); } } And this works and functions appropriately. The other code is basically just recursively going through the directory as standard practice using dirEntries and deleting certain files(it's a little more complex since there is some logic on the file name, but nothing touches the file except delete). Went ahead and did the following in case anyone comes across your issue in the future: https://github.com/dlang/phobos/pull/6707 That way the documentation will at least be clear about it. Thanks. The problem ultimately is MAX_PATH. Seems that phobo's does not detect windows 10 nor use unicode for such things as it should which would not break simple code(one expects file routines to be well used and the bugs fixed). Seems not to many people use D for windows with long paths and files and hence D for windows. The fix is relatively simple ("prepend \\?\ or use the wide functions).
Re: phobo's std.file is completely broke!
On Saturday, 15 September 2018 at 09:47:25 UTC, WebFreak001 wrote: On Friday, 14 September 2018 at 19:06:14 UTC, Josphe Brigmo wrote: For very long file names it is broke and every command fails. These paths are not all that long but over 256 limit. (For windows) The problem this causes can be disastrous. If some check fails and runs code that isn't mean to run if the file exists, it could destroy data. I replaced many of the std.file functions with executeShell(...) and using command line functions and they work. But then my code was still failing and it was because exist was returning false even though the file exists. I'm sure this is not a big deal to some... this is an issue with the Win32 API having that 260 character limit. To work around it, you can use the special path syntax Microsoft allows you to do, which will pass the string you provide directly to the Filesystem instead of parsing it, effectively raising your limit to whatever the Filesystem limits to. See also their official site on this: https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation C:/Some/Very/Long/Path.txt should then become \\?\C:\Some\Very\Long\Path.txt converting / to \ is important because according to the docs windows doesn't do it with the \\?\ prefix. You also have to normalize the path beforehand (i.e. remove ..\ and .\ because they would be treated as actual folder names) To change a server path such as \\share\public you change it to \\?\UNC\share\public There are also some other useful things in there you might want to look at too like the special files such as COM1 Yes, I did that and it worked for some(most) things it seems but rmdir, for example, seems to fail. Also, windows 10 does not have this problem nor does unicode so maybe phobos needs to automatically do everything? If it did I wouldn't have had this problem and wasted a day of my life trying to figure out what is going on(I didn't design my program around having to hack such things, I just assumed they would work, because, after all, they should, right?). I then used execute shell and had to work around that but still had problems because I didn't think dirEntries would be failing. Basically every file function will fail in some odd way(depending on it's use) leaving one to deal with a whole complex of "bugs" when there is really a common bug. rmdir, now is failing but this may be some other bug introduced by me in trying to fix other bugs.
Bug in VD
When having two loops it seems the variables are never show if the name is already used: foreach(string a; x) { // a not shown in the locals or autos} foreach(string a; y) { // a not shown } renaming one of them to b, say, works as long as be wasn't used somewhere else.
Re: phobo's std.file is completely broke!
https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maxpath But because MAX_PATH is an enum, it can't be redefined without recompiling phobos, which means it will break later on... It does say that this is not a problem with unicode... but...
Re: phobo's std.file is completely broke!
On Friday, 14 September 2018 at 19:17:58 UTC, bachmeier wrote: On Friday, 14 September 2018 at 19:06:14 UTC, Josphe Brigmo wrote: For very long file names it is broke and every command fails. These paths are not all that long but over 256 limit. (For windows) Please file a bug report with reproducible examples if you believe it's a bug. It's a bug, but how the hell can I reproduce examples when it depends on the file system? Do you want me to make a VM image and upload that too? dirEntries(elem, SpanMode.shallow)) also fails. I've changed all my code over to using executeShell and everything works except that now I can't even iterate over directories that are too long. This is ridiculous! "It doesn't matter. When I compile a program or DLL in C/C++ and many other languages, I use the Windows headers. These headers define MAX_PATH to 260. So the program will have the limit set by compile time, no matter what you do in the OS later on. There is no advantage with this setting for now, except that you now *may* pass long paths to API functions w/o the infamous \\?\ prefix, but you have no guarantee for it. So to make this have the advantage that some people think it will provide, we'd need: wait until the Windows headers (in Visual Studio, or the DDK, or the Platform SDK or whatever) is properly updated, i.e. the runtime libs may take advantage of it wait until MS forces this setting to be enabled all the time, otherwise it's useless when it stays optional not checking any more for the target OS in the application, assuming Win 10 with the mentioned update The latter will only be the case when an app can't target an Windows version below 10. So all in all it will take years until we get the advantage for standalone applications, and for TC these things don't matter for now anyway. " enum size_t MAX_PATH = 260; !! Seems this is the problem! What a great failure scenario! How bout at least check if the filename is larger than max path? Seesh, the more I use D the more I regret it.
phobo's std.file is completely broke!
For very long file names it is broke and every command fails. These paths are not all that long but over 256 limit. (For windows) The problem this causes can be disastrous. If some check fails and runs code that isn't mean to run if the file exists, it could destroy data. I replaced many of the std.file functions with executeShell(...) and using command line functions and they work. But then my code was still failing and it was because exist was returning false even though the file exists. I'm sure this is not a big deal to some...
dealing with very long paths and names
Seems to break dirEntries when trying to deal with long pathnames(> 512) on windows. It's a strange error because it just fails with access denied or missing file.
Re: remove file access denied(remove broke)
On Friday, 14 September 2018 at 15:21:21 UTC, H. S. Teoh wrote: On Fri, Sep 14, 2018 at 02:36:34PM +, Josphe Brigmo via Digitalmars-d-learn wrote: [...] It happens on a bunch. I do get errors or overlong file names but this doesn't seem to be the case. The fact is, that simply using execute shell using the same file name works. So this is a D problem. It happens quite often and every time I can delete the files in file explorer. It would really help if you post a stripped-down version of the code that exhibits the same problem. Otherwise we're just guessing what the real problem is. T It woudln't help. I'm dealing with over a million files and you'd need those files too. But basically all I have done is created a new rename function: void removeFile(string fn) { if (!isDir(fn)) { // remove(fn) setAttributes(fn, 0x80); auto ls = executeShell(`del /F /Q "`~fn~`"`); if (ls.status != 0) throw new Exception("Cannot delete file `"~fn~"`!"); } } And this works and functions appropriately. The other code is basically just recursively going through the directory as standard practice using dirEntries and deleting certain files(it's a little more complex since there is some logic on the file name, but nothing touches the file except delete).
Re: Why the hell do exceptions give error in the library rather than the user code?
On Friday, 14 September 2018 at 15:52:20 UTC, Neia Neutuladh wrote: On Friday, 14 September 2018 at 14:34:36 UTC, Josphe Brigmo wrote: std.file.FileException@C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d(3153): It is very annoying when the only error info I have is pointing to code in a library which tells me absolutely nothing about where the error occurs in the in the user code(which is what matters). It's what matters when the exception is caused by a bug in user code. It's what matters when the exception is caused by something environmental and the operation was a narrow, focused operation directed by user code. If you have a bug caused by something in the depths of a complex library, the full stacktrace matters. Surely the call stack can be unrolled to find code that exists in the user code? Or at least display several lines like a trace stack. They do, I thought? Let me test quickly: --- void doThrow() { throw new Exception("here!"); } void main() { try doThrow; catch (Exception e) writeln(e); } --- That prints something like: object.Exception@scratch.d(7): here! scratch.d:7 void scratch.doThrow() [0x9d8acd53] scratch.d:14 _Dmain [0x9d8acd68] That's a stacktrace. And if I don't catch the exception, the runtime still gives me a stacktrace. You do need to include debug symbols to get filenames and line numbers; just compile with -g. It is because you are throwing inside your code. When the throw is from the library, it gives something like this: std.file.FileException@C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d(3153): test.txt: Access is denied. 0x000B043A 0x000B0356 0x000A2899 0x000A2CC0 0x000A2CC0 0x000A2CC0 0x000A2CC0 0x000A11EF 0x000BD0EF 0x000BD06D 0x000BCF01 0x000B2EA8 0x00113B5E 0x00113A51 0x001138FD 0x00113BC8 0x76148744 in BaseThreadInitThunk 0x7795582D in RtlGetAppContainerNamedObjectPath 0x779557FD in RtlGetAppContainerNamedObjectPath Where the error is from file. In visual D this always breaks in to the library(which is very annoying but it does show a full stack trace and lets one view the frame). I could wrap my entire program in a try catch and maybe that will offer some new information, but It seems pointless to do that. The stack should be displayed and much of the nonsense removed(like the 20 lines of pointers which is useless to me(they will be invalid when the program exists so why show them?).
Re: Why the hell do exceptions give error in the library rather than the user code?
On Friday, 14 September 2018 at 15:40:46 UTC, Jonathan Marler wrote: On Friday, 14 September 2018 at 14:34:36 UTC, Josphe Brigmo wrote: std.file.FileException@C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d(3153): It is very annoying when the only error info I have is pointing to code in a library which tells me absolutely nothing about where the error occurs in the in the user code(which is what matters). Surely the call stack can be unrolled to find code that exists in the user code? Or at least display several lines like a trace stack. Not getting a stack trace? What platform are you on and what's the command line you used to compile? I get the main exception. Using windows x86 and visual D with it's default command line and in debug mode. It seems these are "first chance exceptions" and that they seem to cause multiple problems. This is the only kind of error I get std.file.FileException@C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d(3153): test.txt: Access is denied. 0x000B043A 0x000B0356 0x000A2899 0x000A2CC0 0x000A2CC0 0x000A2CC0 0x000A2CC0 0x000A11EF 0x000BD0EF 0x000BD06D 0x000BCF01 0x000B2EA8 0x00113B5E 0x00113A51 0x001138FD 0x00113BC8 0x76148744 in BaseThreadInitThunk 0x7795582D in RtlGetAppContainerNamedObjectPath 0x779557FD in RtlGetAppContainerNamedObjectPath Which is about useless in helping me find the error when I use several file command.
Re: remove file access denied(remove broke)
On Friday, 14 September 2018 at 13:28:41 UTC, Adam D. Ruppe wrote: On Friday, 14 September 2018 at 08:32:48 UTC, Josphe Brigmo wrote: Seems remove is broke. The source code for remove is DeleteFile(name), so not much room for bugs there, except maybe string conversion. What is the filename you are working on? It happens on a bunch. I do get errors or overlong file names but this doesn't seem to be the case. The fact is, that simply using execute shell using the same file name works. So this is a D problem. It happens quite often and every time I can delete the files in file explorer.
Why the hell do exceptions give error in the library rather than the user code?
std.file.FileException@C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d(3153): It is very annoying when the only error info I have is pointing to code in a library which tells me absolutely nothing about where the error occurs in the in the user code(which is what matters). Surely the call stack can be unrolled to find code that exists in the user code? Or at least display several lines like a trace stack.
Re: remove file access denied(remove broke)
On Friday, 14 September 2018 at 04:48:09 UTC, Norm wrote: On Thursday, 13 September 2018 at 23:25:24 UTC, Josphe Brigmo wrote: I am trying to remove a file remove(filename); and I get an access denied! I can remove it from explorer just fine. I am able to remove other files but there should be no reason why the file can't be removed in this case. All I am doing to mess with the file is reading it's contents right before to do a file compare(I am removing the file if it is a duplicate). Does read() lock the file at all? (maybe the lock is persisting just long enough to make the remove fail? Since I can delete the file outside the program and since the filename is valid(I copied and pasted it to remove it to check), This seems like a D problem. Do you have the file open when you call remove? If so close the file handle before the remove call. If you can post a stripped down version of your code it would also help. bye, Norm No, I use read, there is no file handles. Pointless to post code because it won't offer much. Also, I have security privileges. I simply read the file to compare it's contents then I try to remove the file if it had the same contents and it says it is invalid. I also, of course, check that it exist and is a file. This is all I'm doing that is related to file reading and I cannot remove the file(but can read it and such). So, I'm really wondering if read locks the file but doesn't release it in time. Using lockHunder shows the file isn't locked but the directory is(Probably because I'm iterating through it. Seems it is an error with remove, using executeShell works fine: auto ls = executeShell(`del /F /Q "`~fn~`"`); which does not give an error but remove(fn) does. Seems remove is broke.
remove file access denied
I am trying to remove a file remove(filename); and I get an access denied! I can remove it from explorer just fine. I am able to remove other files but there should be no reason why the file can't be removed in this case. All I am doing to mess with the file is reading it's contents right before to do a file compare(I am removing the file if it is a duplicate). Does read() lock the file at all? (maybe the lock is persisting just long enough to make the remove fail? Since I can delete the file outside the program and since the filename is valid(I copied and pasted it to remove it to check), This seems like a D problem.
Re: x64 Privileged instruction
On Wednesday, 12 September 2018 at 13:26:03 UTC, Stefan Koch wrote: On Wednesday, 12 September 2018 at 10:42:08 UTC, Josphe Brigmo wrote: x64 gives Privileged instruction but x86 gives First-chance exception: std.file.FileException "C:\": The filename, directory name, or volume label syntax is incorrect. at std\file.d(4573) which is much more informative... seems like a bug to me. More context needed. What code does produce this behavior. Lots of code. I pretty much always get this error. Just throw. It is a first chance exception so that should be clear enough. The point is that x64 doesn't seem to handle first chance exceptions and gives a privileged instruction. This happens windows 10 visual D and I've had it happen for a long time.
x64 Privileged instruction
x64 gives Privileged instruction but x86 gives First-chance exception: std.file.FileException "C:\": The filename, directory name, or volume label syntax is incorrect. at std\file.d(4573) which is much more informative... seems like a bug to me.
DlangUI and android
Is there an emulator that can run the apks? Android emulator does not work, I suppose, because it isn't java. Complains about a missing classes.dex file. I'd rather have an emulator version if possible for quicker dev.
Re: Source changes should include date of change
On Sunday, 9 September 2018 at 02:48:40 UTC, Neia Neutuladh wrote: On Sunday, 9 September 2018 at 01:27:06 UTC, Josphe Brigmo wrote: How hard would it be to automate dating for dmd source so that everything is consistent in a way that makes sense? Perhaps you could find out by trying to implement such a system? That's what I usually do. You haven't described the problems you want to address in any detail, so you're the only one who knows what would make sense. That means you're the only person who could even hope to estimate the difficulty. Plus it would be a fair bit of work that nobody else seems that interested in, so unless you're offering to pay, you're the only one motivated to do the work. But perhaps, if you presented your results, they would be interesting enough for others to adopt. Yes, but the fact is they would not appreciate my work because they do not appreciate it now. You might appreciate it but the fact is, people that bitch and complain about someone saying they have a problem with something and that "Do it my way attitude" are people who don't appreciate other peoples work, they only use it to further their own self. So, since I don't have to implement it, and because it is not a huge problem, I won't. Screw the assholes who try to shut down people and progress just because they are assholes(and who have no good reasons). It's one thing to debate a topic to find the best solution and it's another to try to shut it down based on an irrelevant argument. You know, not everything is complex: What is proposed here does not change the source any one bit. It only adds to it. It is basically inheritance(or a product). It doesn't distort the code(e.g., map it to a random alphabet) nor does it introduce any bugs. All it can do is add bloat. That is it! So, what they are bitching about, really, is they don't want bloat. But they can't see that because they are only conformist and they don't want anything to interfere with them conforming. But see, the problem with bloat is not necessary a problem. It is only a problem if the bloat is not useful. E.g., a class inheriting another class is adding bloat, so to speak. So, the issue should be how much bloat, how to control the bloat, and how to make the bloat useful... But guess what? No relevant discussion on these meaningful issues of the problem(the ones that, if they could be solved would solve the problem for everyone within reason) because they shut down the argument with there authoritative and mindless drivel. So, no, I will not help out, it's obviously no one wants help. I do have to do a risk analysis assessment because it does cost me my time. What I see is that I won't invest it because I won't invest in people with such attitudes which further helps them along and only generally strengthens their attitudes(because it must be working, right?). I will not play the shit slinging game. You or others will think I am slinging shit because I don't conform, but it's precisely why I am not slinging shit, because I am not conforming to the shit slingers. Of course, that assumes I am not a shit linger but it does prove that only one side slings shit. I let the historical record be my proof of who slings shit. They should be easy to spot because they have the smelly hands. A question I propose to you is that if a shit slinger slings shit at someone and that person throws the shit back at the original shit slinger, are they too a shit slinger? If so, are they equally culpable?
Re: Source changes should include date of change
On Sunday, 9 September 2018 at 02:49:45 UTC, Walter Bright wrote: On 9/8/2018 4:29 AM, Josphe Brigmo wrote: Um, I didn't say don't use Git! I've done this manually before git. I can guarantee you that the dates put in the file are invariably wrong, incomplete, or non-existent. But if you bring up a source file in github, and click on the "Blame" button, it'll tell you, for every line in the source, which PR last changed that line. Yes, but if one has access to git then that is pointless. Yes, dates go out of sync and are hard to maintain. THis is why it takes a more complex system to cover those issues property. One wouldn't just include the date but other meta information that removes and reduces these problems that people complain about. If git would automatically do the dates then one could download the source code. Git would be the central repository and if one wanted an offline version that had enough info in it such as the data a change was made, who changed it, the date the file was generated etc, then it would be better than having nothing. To throw the baby out with the bath water is wrong. Special comments could be used so they could easily be removed if desired along with any necessary information such as the library version, dates the code was changed, etc. No need to include everything. Some information is better than none, that is always the case. Data(knowledge) can't hurt you, only the lack of it. The thing is, none of this shit hurts anything. Comments don't change programs so really it is just an issue about bloat and rot. The rot is covered by git hub automatically generating all the info(then it becomes no different than the problem of versioning with everything, want an update, just download it from git). The bloat is minimum and the bloat is precisely valid information(it's not like it is gibberish). So, for people to pretend that this is evil and shouldn't be done just because they feel it is not as good as using git directly is really moronic. What they are saying is "Because git hub has it all we shouldn't go the extra step to provide partial information". But the problem with such logic is git up is not always available and not everyone wants to go that route. So, instead of a compromise these people want to enforce some absolute law that they imagined they can enforce(some people murder over such things, just to show you how bad it can get). It's one thing to say that it shouldn't be done because no one thinks it's important(e.g., almost everyone uses git hub) and quite a different thing to dictate some fictitious authoritative dictator persona as if the dictator is god and knows everything. 30 years ago if asked most programmers about starting a git hub they would laugh at you and tell you it is not needed. The sad fact is that most people have no clue what is actually needed and what is good and what is bad. They just follow the asses in front of them, usually, eventually, over a cliff.
Re: Source changes should include date of change
On Saturday, 8 September 2018 at 18:47:39 UTC, Neia Neutuladh wrote: On Saturday, 8 September 2018 at 06:59:28 UTC, Josphe Brigmo wrote: Having source code that doesn't show changes with dates is pretty useless for diagnostics. I realize that git has the changes but the source code should. What problem did you encounter where you had trouble getting the information you needed with git blame, where a source code comment listing change dates would help? Why not also add a link to the git hub patch Because that's a lot of work to replicate something git already does. or bugzilla or whatever? Currently, some code in phobos does reference issues on the dlang bugzilla. The common categories for this include: * Explaining why we want things to work this way, if that requires more than a couple sentences of explanation * Pointing out what problem this is a workaround for * Pointing out which past problem motivated this unittest Things that help you understand the code as it currently is. Is there some situation you've encountered in the past where that kind of comment wasn't enough? This has nothing to do with git. People think git is the end all be all. What if git is not available, then what? It's moronic to think that one has to use one or the other when both options are available and both only add information. The same people that are saying use git used to say that git was overkill because it wasn't needed before it became popular. They are simply always looking for a way to justify their current belief. They think the world is black or white. They then pretend that a choice has to be made between two possibilities. e.g., either religion or science(but not both because they only have xor in their operations), either black or white. Either yes or no, either hot or cold, either this or that. They then go crazy when someone offers the other choice as a solution because they feel they will lose their safety blanket. How hard would it be to automate dating for dmd source so that everything is consistent in a way that makes sense? See, people rather blow off their bad leg just so they have one good leg rather than have a bad leg and a good leg. "A false dilemma is a type of informal fallacy in which something is falsely claimed to be an "either/or" situation, when in fact there is at least one additional option. A false dilemma can arise intentionally, when a fallacy is used in an attempt to force a choice or outcome." BTW, not every uses git and git is not always available so to say "You must use git" just sounds likes arrogant(of course, arrogant people don't think they are arrogant). When I have to dive in to source code to find something, it helps to have some clue when the code was added. A clue is better than being in the dark, but as we know, some people just like to bury their head in the sand. For them, ignorance is bliss.
Re: Error: expression `update` of type `void` does not have a boolean value
On Saturday, 8 September 2018 at 07:30:35 UTC, Alex wrote: On Saturday, 8 September 2018 at 06:56:40 UTC, Josphe Brigmo wrote: My project does not use the term update at all in any other context except that one. But I did find: void update(K, V, C, U)(ref V[K] aa, K key, scope C create, scope U update) Ok... found something here: https://dlang.org/changelog/2.082.0.html#require_update and here: https://dlang.org/spec/hash-map.html#advanced_updating It seems, they were added in 2.082.0. No idea why they are conflicting with your existing code, however... And even whether they are the source of conflict... obviously who ever added it screwed the pooch.
Re: Source changes should include date of change
On Saturday, 8 September 2018 at 07:08:46 UTC, Colin wrote: On Saturday, 8 September 2018 at 06:59:28 UTC, Josphe Brigmo wrote: Having source code that doesn't show changes with dates is pretty useless for diagnostics. I realize that git has the changes but the source code should. If some code is added or changed it is very simple to add the date of change in a comment. // Date: Date1, Date2, Date3, Anything below a was changed at those dates. Why not also add a link to the git hub patch or bugzilla or whatever? Git is the tool that's used to manage changes, including viewing the changes. A lot of dev time has gone into it and it works really well. Some ad hoc comment system in source code to point out changes will never be as good. Just Use Git! Um, I didn't say don't use Git! Your illogic is that you believe that one can have only one or the other when one can have both. Hence, you are excluding a completely valid addition. You think it is an alternative. You are wrong. Please think about the question before you answer next time so that you don't get in the habit of doing it. No one said that Git couldn't be used and telling me to use it is very arrogant of yourself. The fact of the matter is that dates in source code will help when git is not available and one only has the source code.
Re: Error: expression `update` of type `void` does not have a boolean value
On Saturday, 8 September 2018 at 05:39:39 UTC, Alex wrote: On Saturday, 8 September 2018 at 03:12:56 UTC, Josphe Brigmo wrote: auto foo(bool update = false)() { static if(update) { } } and the compiler, after upgrading to 2.082 from 2.080 now says: Error: expression `update` of type `void` does not have a boolean value when update is clearly a bool. Why the hell is the compiler now thinking update is a void? 1. This code compiles fine in a test app and 2. when I rename update to something else it works fine. 2. There is no other use of update in the entire module(not that it should matter) Seems this is a compiler bug but only has a problem in context. Remember, it worked find before I updated dmd and there is no reason why it shouldn't work. Could you show some more code, as this works for me: ´´´ import std.stdio; void main() { foo; } auto foo(bool update = false)() { static if(update) { } } ´´´ compiled with dmd --version DMD64 D Compiler v2.082.0 Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved written by Walter Bright dmd ./source/app.d used on a Mac with Darwin Kernel Version 17.7.0 I can't, the code is from a very large project and it's too intertwined. I already said it worked in simple form and that it worked with a previous compiler, so this is a regression. Changing no code and only swapping compilers produces this bug... and as you can see, it's obviously a bug given the form of the function and the error message and that it worked before without changes. Why the specific term update? I don't know. My project does not use the term update at all in any other context except that one. But I did find: void update(K, V, C, U)(ref V[K] aa, K key, scope C create, scope U update)
Source changes should include date of change
Having source code that doesn't show changes with dates is pretty useless for diagnostics. I realize that git has the changes but the source code should. If some code is added or changed it is very simple to add the date of change in a comment. // Date: Date1, Date2, Date3, Anything below a was changed at those dates. Why not also add a link to the git hub patch or bugzilla or whatever?
Error: expression `update` of type `void` does not have a boolean value
auto foo(bool update = false)() { static if(update) { } } and the compiler, after upgrading to 2.082 from 2.080 now says: Error: expression `update` of type `void` does not have a boolean value when update is clearly a bool. Why the hell is the compiler now thinking update is a void? 1. This code compiles fine in a test app and 2. when I rename update to something else it works fine. 2. There is no other use of update in the entire module(not that it should matter) Seems this is a compiler bug but only has a problem in context. Remember, it worked find before I updated dmd and there is no reason why it shouldn't work.
GTKD for android?
I have an app I'm writing using GtkD on windows. Eventually I'd like to port it to android. Since I have never been able to actually get anything to work on android I'm curious if there are any demos with gtkD for android? I'm wondering if I just scrap the idea of using it because it won't port without a ton of work. Ideally I'd like to just cross compile and it all work out except for a few bugs.
Re: Variant is just a class
Here is a working example: import std.stdio; class Project(Wrapped, Interface) : Interface { import std.traits; Wrapped wrapped; static foreach (member; __traits(allMembers, Interface)) { static foreach (overload; __traits(getOverloads, Interface, member)) { mixin(`ReturnType!overload ` ~ member ~ `(Parameters!overload params) { return wrapped.` ~ member ~ `(params); }`); } } //this(Wrapped w) static Interface opCall(Wrapped w) { auto t = new typeof(this); t.wrapped = w; return t; } } interface I { void foo(); } class A { void foo() { writeln("A"); } } class B { void foo() { writeln("B"); } } void main() { auto b = new B(); auto a = new A(); auto x = Project!(A, I)(a); auto y = Project!(B, I)(b); a.foo(); b.foo(); x.foo(); y.foo(); }
compiler asserts
import std.stdio, std.variant; class Wrapper(Interface, Wrapped) : Interface { import std.traits; Wrapped wrapped; static foreach (member; __traits(allMembers, Interface)) { } } void main() { } when I try to compile this v2.080.0 object.Error@(0): Access Violation 0x00415999 0x0040A3B7 Seems to work fine online so maybe this is an issue with the dmd version? Seems like it shouldn't crash though, nothing is being done. Updated to latest 2.082 and it was fixed... so I'll post anyways for anyone else that might have this issue.
Re: Variant is just a class
On Friday, 7 September 2018 at 18:18:50 UTC, Neia Neutuladh wrote: On Friday, 7 September 2018 at 03:04:19 UTC, Josphe Brigmo wrote: We are talking about two different things that are related: A variant holds a set of objects. Using VariantClass limits the types to a subset and allows for inherited types to be added. Algebraic!SomeInterface should allow anything that inherits from that interface (possibly with an explicit cast). It doesn't. import std.stdio, std.variant; class A { } class B : A { } void main() { B b; Algebraic!A a; a = b; } "Cannot store a B in a VariantN!(8LU, A). Valid types are (A)" Why this is better is because it allows objects that may not have been inherited from some interface in the design(pre-existing). OOP is better when you don't trust people to implement types correctly and you want them to get errors at the proper location when they get it wrong. Structural typing is better when you don't trust people to implement types correctly and you want to make things easier on yourself when they don't. They're both useful. Most of the time, you're dealing with your own types. Sometimes, you need a type you don't control to implement an interface. the default way of making structural typing work in D is with templates. You can also auto-generate a wrapper type. Cool, I will check it out. It seems it would allow DuckingVariant to be created. It would allow you to make a wrapper type that works with a wide range of types. It's probably worse on average than writing a template to create a wrapper class that implements the interface you need. I mean, the wrapper is pretty much (untested): class Wrapper(Interface, Wrapped): Interface { Wrapped wrapped; static foreach (member; __traits(allMembers, Interface)) { static foreach (overload; __traits(getOverloads, Interface, member)) { mixin(`ReturnType!Overload ` ~ method ~ `(Parameters!overload params)` { return wrapped.` ~ method ~ `(params); }`); } } } And now you don't need a VariantClass!SomeInterface, just SomeInterface. One of the problems with the above is that it doesn't allow different 'Wrapped' to equate to the same type: Wrapper!(I, A) != Wrapper!(I, B) Although, by construction, they implement I e.g., one couldn't make a variable Wrapped!(I, A) a; and put a Wrapped!(I,B) in it because D will think they are different types simply because the parameters are different. I guess one needs to return a WrappedBase!I type that is common to all and does some magic to trick the compiler. Although, maybe Wrapped!(I, Object) a; will allow this to work?
Re: Variant is just a class
On Thursday, 6 September 2018 at 20:25:18 UTC, Neia Neutuladh wrote: On Thursday, 6 September 2018 at 10:18:43 UTC, Josphe Brigmo wrote: Variants can hold an arbitrary set of types. I imagine that it is effectively just a type id and an object pointer!? It's a typeid and a static array large enough to hold any basic builtin type: the now-deprecated creal, a dynamic array, or a delegate. If you make a Variant from an object, it stores that object reference. The object reference is just a pointer, yes. If you make a Variant from a 256-byte struct, it copies that struct onto the heap and stores a pointer. If you make a Variant from a 6-byte struct, then it stores that struct and does no heap allocations. If so, then it really is just a special type of a class class. It's similar to a java.lang.Object with explicit boxing, but without the need to create a new wrapper class for each value type. It seems that variant and oop are essentially the same thing, more or less, as whatever can be done in one can effectively be done in the other, except, of course, that the class version has compile time type information associated with it, which sort of restricts variant to a subset of all types!?! Object-oriented programming includes inheritance and member function overloading. Variant doesn't; it's just about storage. We are talking about two different things that are related: A variant holds a set of objects. Using VariantClass limits the types to a subset and allows for inherited types to be added. Those objects may be classes which already have inheritance and hence matching and calling their methods will dispatch appropriately. A variant sits on top of the object hierarchy, it is not somewhere in the middle where objects will inherit from it(which is impossible). The difference is simply Object x; Variant y; There is very little difference. If x is a class type then so will variant hold class type and it will act just like the Object does. That is, Variant can do no worse than just being an object(except it then becomes pointless as it can hold only one type. If you're working with classes, you'd be better off using a base class or interface instead of Variant for fields that can only hold objects of those types. But variant can reduce the code complexity if one restricts it's inputs to a specific class of types: Yes, for which you can use std.variant.Algebraic. For instance, Algebraic!(int, long, float) will accept ints, longs, and floats, but nothing else. It is not the same since Algebraic does not allow inherited types inside it's container? Or maybe it does? VariantClass!X will accept anything derived from X and it will dispatch appropriately since it just delegates to the normal class dispatching mechanisms. Then VariantClass will prevent any arbitrary type from being assigned to the variant, effectively allow inheritance to be used(in the sense that it will prevent any type from being used at compile time, like inheritance): VariantClass!X v; // only T : X's are allowed. That's equivalent to `X v;` except with a wrapper around it. Yes, but the whole point of the wrapper is simply to insure that only a subset of types is used but allow for different types. X v; only allows types derived from X. VariantClass!(X, Y) v; allows types derived from X or from Y. then matching on the type will simply delegate everything appropriately. If X and Y have a common type I then one can do VariantClass!I v; which would be the same as I v; But not the same as Algebraic!I v; because we couldn't stick in a derived object for I. We can cast, and it works but it simply doesn't naturally allow derived types for some reason. VariantClass allows derived types. This is a big difference because Algebraic doesn't naturally work well with oop but VariantClass does. Matching then is dispatch. We could further extend VariantClass to return specific classes for each type that dispatch to match and vice versa. I think you're saying that this sort of Algebraic could expose any methods and fields common to all its types? Can D project interfaces like this? interface I { int foo(int); } I i = project!I(o); You can write code to make that work. It would create a wrapper class that implements the requested interface, and that wrapper would just forward everything to the wrapped value. It would be a lot easier just to have the type implement the interface itself, if that's possible. But this is just oop. Opp requires more work to design because one has to implement the interfaces in a prescribed way. What I am talking about taking any object and if it has certain methods that conform to some "interface" then it will behave as if it were derived... even if it were not specified as derived. Why this is better is because it allows objects that may not have been inherited from some interface in the
Variant is just a class
Variants can hold an arbitrary set of types. I imagine that it is effectively just a type id and an object pointer!? If so, then it really is just a special type of a class class. Let me explain: I have a class that will "hold/wrap" another class. I could hold them using a variant but also I could require some new wrapper class that takes the object and include that wrapper class instead: class A { variant o; } vs class A { B oo; } class B { ... Object ooo; // or variant } id matching on o is basically virtual functions. The matcher dispatching is single dispatch. Of course, the class version gives compile time specificity since it provides a compile time interface that the variant does not represent. It seems that variant and oop are essentially the same thing, more or less, as whatever can be done in one can effectively be done in the other, except, of course, that the class version has compile time type information associated with it, which sort of restricts variant to a subset of all types!?! But variant can reduce the code complexity if one restricts it's inputs to a specific class of types: struct VariantClass(T...) { private Variant v; alias v this; static foreach(t; T) auto opAssign(t x) { v = x; } } Then VariantClass will prevent any arbitrary type from being assigned to the variant, effectively allow inheritance to be used(in the sense that it will prevent any type from being used at compile time, like inheritance): VariantClass!X v; // only T : X's are allowed. Matching then is dispatch. We could further extend VariantClass to return specific classes for each type that dispatch to match and vice versa. They might not be exactly the same though but it seems that they essentially both cover the same problem but from different perspectives. Anyone have any thoughts? I'm mainly trying to decide if I should use a variant or go full oop. Variant seems more appropriate than using Object for a general purpose singleton container in that I can leverage it's design. If I use oop then it does require me to design an inheritance between the objects. It would be cool if duck typing could be used though. Essentially all I want to do is access a very small interface of the object that has a draw command and maybe a few other things. I want all the objects to posses these functions(be a duck) but other than that, I could care less. Seems like I could extend the VariantClass to do introspection on the types and make sure they have the members I need but otherwise do not limit their types to inheritance but then it starts feeling like oop as I'll need to specify an interface. Seems like partial interface matching is what is needed. One specifies an interface I and any object that partially matches it by design(contains same function signatures, regardless if it physically implements the interface). Can D project interfaces like this? interface I { int foo(int); } I i = project!I(o); project returns part of the interface o(can be object but must have a int foo(int)) that matches I or null otherwise. Seems though this cannot be used at runtime though since function signatures are not transported in the binary? If they are, then maybe it would work and would reduce the overhead of oop as one could just project types to other types that overlap.