Re: Problem with dtor behavior
On Thursday, 27 July 2017 at 20:28:47 UTC, Moritz Maxeiner wrote: On Thursday, 27 July 2017 at 19:19:27 UTC, SrMordred wrote: //D-CODE struct MyStruct{ int id; this(int id){ writeln("ctor"); } ~this(){ writeln("dtor"); } } MyStruct* obj; void push(T)(auto ref T value){ obj[0] = value; } void main() { obj = cast(MyStruct*)malloc( MyStruct.sizeof ); push(MyStruct(1)); } OUTPUT: ctor dtor dtor I didnt expected to see two dtors in D (this destroy any attempt to free resources properly on the destructor). AFAICT it's because opAssign (`obj[0] = value` is an opAssign) creates a temporary struct object (you can see it being destroyed by printing the value of `cast(void*) ` in the destructor). Can someone explain why is this happening and how to achieve the same behavior as c++? Use std.conv.emplace: --- import std.conv : emplace; void push(T)(auto ref T value){ emplace(obj, value); } --- It worked but isnt this odd? like, if I change the push(MyStruct(1)) for obj[0] = MyStruct(1); (which is what I expected in case of compiler inlining for example) the behavior change: OUTPUT: ctor dtor I´m having the feeling that this "auto ref T" don´t have the same behavior that the "T&&" on c++. I find this very strange because if i copy/paste/tweak code from c/c++ on D, and have some kind of malloc/free on the ctor/dtor the code will blow in my face without warning.
Re: It makes me sick!
On Friday, 28 July 2017 at 12:48:37 UTC, Grander wrote: On Friday, 28 July 2017 at 12:40:27 UTC, rjframe wrote: On Fri, 28 Jul 2017 05:14:16 +, FoxyBrown wrote: You can make any claim you want like: "The end user should install in to a clean dir so that DMD doesn't get confused and load a module that doesn't actually have any implementation" but that's just your opinion. I have never seen extracting into the directory as a supported upgrade path for anything except the simplest of applications and a few PHP projects that supply a migration script. Well, any other installer would have done the required cleanup in such a case. The D installer completely uninstalls the previous installation. Anyone who chooses to instead manually extract the zip file should manually delete the previous installation to avoid potential problems. As Jonathan said earlier, overwriting works most of the time, but whenever anything is removed, issues like this can crop up.
Re: It makes me sick!
On 07/28/2017 03:29 PM, Mike Parker wrote: The D installer completely uninstalls the previous installation. Anyone who chooses to instead manually extract the zip file should manually delete the previous installation to avoid potential problems. As Jonathan said earlier, overwriting works most of the time, but whenever anything is removed, issues like this can crop up. To me the only issue would be that (one of) the documentation pages [1] only talks about the zip file. I think it should be made clearer that the installer is the recommended / supported way, and that the zip is only meant for experts (with a recommendation to uncompress to a clean directory to avoid problems). I know this page is not the MAIN "download" [2] page, but it's both reached from the "About" link, and as the first google hit for "dlang download windows", so it should be kept as up to date as possible. [1]: https://dlang.org/dmd-windows.html#installation [2]: https://dlang.org/download.html
Re: Profiling after exit()
On 2017-07-28 11:30, Mario Kröplin wrote: Our programs are intended to run "forever". 24/7 servers. What's wrong with having a bool that determines if the loop should continue running? -- /Jacob Carlborg
Re: It makes me sick!
On Friday, 28 July 2017 at 13:39:42 UTC, Arafel wrote: I know this page is not the MAIN "download" [2] page, but it's both reached from the "About" link, and as the first google hit for "dlang download windows", so it should be kept as up to date as possible. [1]: https://dlang.org/dmd-windows.html#installation Ugh. Agreed. That page needs an update.
Re: It makes me sick!
On Friday, 28 July 2017 at 05:14:16 UTC, FoxyBrown wrote: On Friday, 28 July 2017 at 01:10:03 UTC, Mike Parker wrote: [...] Nope, your unreasonable expecting the end user to clean up the mess "you" leave. [...] Nope. Virtually all apps, at least on windows, work fine if you replace their contents with new versions. Generally, only generated files such as settings and such could break the apps... but this is not the problem here. If dmd breaks in strange and unpredictable ways IT IS DMD's fault! No exceptions, no matter what you believe, what you say, what lawyer you pay to create a law for you to make you think you are legally correct! You can make any claim you want like: "The end user should install in to a clean dir so that DMD doesn't get confused and load a module that doesn't actually have any implementation" but that's just your opinion. At the end of the day it only makes you and dmd look bad when it doesn't work because of some lame minor issue that could be easily fixed. It suggests laziness["Oh, there's a fix but I'm too lazy to add it"], arrogance["Oh, it's the end users fault, let them deal with it"], and a bit of ignorance. In the long run, mentalities like yours are hurting D rather than helping it. Sure, you might contribute significantly to D's infrastructure, but if no one uses because there are so many "insignificant" issues then you've just wasted an significant portion of your life for absolutely nothing. So, I'd suggest you rethink your position and the nearsighted rhetoric that you use. You can keep the mentality of kicking the can down the road and blaming the end user but it will ultimately get you no where. @FoxyBrown You make the small but crucial mistake of thinking anything in D has been made for the user's sake. In fact, nothing has even been made to be used by a developer. Actually, D is a programming language for tinkerers, people with too much time and botchers. Should any of my statements above against all expectations not be right, then something in the design of D went, more or less, very terribly wrong ...
Re: It makes me sick!
On Fri, 28 Jul 2017 05:14:16 +, FoxyBrown wrote: > > You can make any claim you want like: "The end user should install in to > a clean dir so that DMD doesn't get confused and load a module that > doesn't actually have any implementation" but that's just your opinion. I have never seen extracting into the directory as a supported upgrade path for anything except the simplest of applications and a few PHP projects that supply a migration script. > At the end of the day it only makes you and dmd look bad when it doesn't > work because of some lame minor issue that could be easily fixed. It > suggests laziness["Oh, there's a fix but I'm too lazy to add it"], > arrogance["Oh, it's the end users fault, let them deal with it"], and a > bit of ignorance. The only solution I can think of is never splitting a module in Phobos; the alternative would be to change the way the module system works (which seems to be what you want), and that's going to break everybody's everything.
Re: It makes me sick!
On Friday, 28 July 2017 at 12:40:27 UTC, rjframe wrote: On Fri, 28 Jul 2017 05:14:16 +, FoxyBrown wrote: You can make any claim you want like: "The end user should install in to a clean dir so that DMD doesn't get confused and load a module that doesn't actually have any implementation" but that's just your opinion. I have never seen extracting into the directory as a supported upgrade path for anything except the simplest of applications and a few PHP projects that supply a migration script. Well, any other installer would have done the required cleanup in such a case.
Re: It makes me sick!
On Friday, 28 July 2017 at 05:14:16 UTC, FoxyBrown wrote: If dmd breaks in strange and unpredictable ways IT IS DMD's fault! No exceptions, no matter what you believe, what you say, what lawyer you pay to create a law for you to make you think you are legally correct! You can make any claim you want like: "The end user should install in to a clean dir so that DMD doesn't get confused and load a module that doesn't actually have any implementation" but that's just your opinion. At the end of the day it only makes you and dmd look bad when it doesn't work because of some lame minor issue that could be easily fixed. But it's not being installed, it's being manually extracted, meaning you can't even have cleanup scripts. Compare keeping an installation of audio files in mp3 (bird calls), and then getting an upgrade where they are in ogg in a new neat directory hierarchy. There's an installer that properly and cleanly removes the old mp3s before extracting the new files, as well as a bonus archive if you want to unzip it yourself. Manually extracting it onto the old directory puts the oggs next to the mp3s, leaving it with twice the number of original audio files. Meanwhile, the official upgrade path (installer) properly removes the stale ones. You can't reasonably expect your audio player to not list them all there.
Re: Problem with dtor behavior
On Thursday, 27 July 2017 at 19:19:27 UTC, SrMordred wrote: void push(T)(auto ref T value){ push(MyStruct(1)); template void push(T&& value){ push(MyStruct(1)); Those aren't the same... the D one will pass by value, the C++ one won't. D's auto ref means ref for lvalues, value for rvalues. C++ will do rvalue by ref too. I didnt expected to see two dtors in D (this destroy any attempt to free resources properly on the destructor). In D, you must write destructors such that they can be called on a default-initialized object. (This also means your malloc is wrong, since it doesn't perform the default initialization.) Can someone explain why is this happening and how to achieve the same behavior as c++? I would blit it over as raw memory then call the ctor instead of using the assign operator. That's what std.conv.emplace does..
Re: Problem with dtor behavior
On Friday, 28 July 2017 at 15:49:42 UTC, Moritz Maxeiner wrote: [...] Nice, a bit more clear now, thank you!
Re: Problem with dtor behavior
On Friday, 28 July 2017 at 11:39:56 UTC, SrMordred wrote: On Thursday, 27 July 2017 at 20:28:47 UTC, Moritz Maxeiner wrote: On Thursday, 27 July 2017 at 19:19:27 UTC, SrMordred wrote: //D-CODE struct MyStruct{ int id; this(int id){ writeln("ctor"); } ~this(){ writeln("dtor"); } } MyStruct* obj; void push(T)(auto ref T value){ obj[0] = value; } void main() { obj = cast(MyStruct*)malloc( MyStruct.sizeof ); push(MyStruct(1)); } OUTPUT: ctor dtor dtor I didnt expected to see two dtors in D (this destroy any attempt to free resources properly on the destructor). AFAICT it's because opAssign (`obj[0] = value` is an opAssign) creates a temporary struct object (you can see it being destroyed by printing the value of `cast(void*) ` in the destructor). Can someone explain why is this happening and how to achieve the same behavior as c++? Use std.conv.emplace: --- import std.conv : emplace; void push(T)(auto ref T value){ emplace(obj, value); } --- It worked but isnt this odd? Here's the summary: Because D uses default initialization opAssign assumes its destination is an initialized (live) object (in this case located at `obj[0]`) and destructs this object before copying the source over it. Emplace is designed to get around this by assuming that its destination is an uninitialized memory chunk (not a live object). `MyStruct(1)` is a struct literal, not a struct object, i.e. (in contrast to struct objects) it's never destroyed. When passing the struct literal into `push`, a new struct object is created and initialized from the struct literal; this struct object is then passed into `push` instead of the struct literal, used as the source for the opAssign, and then finally destroyed after `push` returns. When assigning the struct literal directly to `obj[0]` no such extra struct object gets created, `obj[0]` still gets destroyed by opAssign and then overwritten by the struct literal. W.r.t to `auto ref`: To paraphrase the spec [1], an auto ref parameter is passed by reference if and only if it's an lvalue (i.e. if it has an accessible address). (Struct) literals are not lvalues (they do not have an address) and as such cannot be passed by reference. [1] https://dlang.org/spec/template.html#auto-ref-parameters
Re: Problem with dtor behavior
On Friday, 28 July 2017 at 16:25:01 UTC, Adam D. Ruppe wrote: On Thursday, 27 July 2017 at 19:19:27 UTC, SrMordred wrote: "auto ref means ref for lvalues, value for rvalues." Iep, my confusion was there. My mind is still wrapped around the rvalue references and move semantics of c++
Re: Profiling after exit()
On 2017-07-27 16:30, Eugene Wissner wrote: I have a multi-threaded application, whose threads normally run forever. But I need to profile this program, so I compile the code with -profile, send a SIGTERM and call exit(0) from my signal handler to exit the program. The problem is that I get the profiling information only from the main thread, but not from the other ones. Is there a way to get the profiling information from all threads before terminating the program? Maybe some way to finish the threads gracefully? or manully call "write trace.log"-function for a thread? As others have mentioned, you should in general avoid calling "exit" in a D program. There's a C function called "atexit" that allows to register a callback that is called after calling "exit". You could perhaps join the threads there. I don't know if that helps with the profiling though. -- /Jacob Carlborg
std.meta.Replace using index
Hi I want to replace each occurrence of a particular type in an AliasSeq with a type from another AliasSeq (the both have the same length) with the corresponding index i.e. (int long long float) (byte char double dchar) replacing long should yield (int char double float) std.meta.Replace would see to do the trick except the lambda depends in the index and I'm not sure how to pass that.
Re: Profiling after exit()
On Friday, 28 July 2017 at 06:32:59 UTC, Jacob Carlborg wrote: On 2017-07-27 16:30, Eugene Wissner wrote: I have a multi-threaded application, whose threads normally run forever. But I need to profile this program, so I compile the code with -profile, send a SIGTERM and call exit(0) from my signal handler to exit the program. The problem is that I get the profiling information only from the main thread, but not from the other ones. Is there a way to get the profiling information from all threads before terminating the program? Maybe some way to finish the threads gracefully? or manully call "write trace.log"-function for a thread? As others have mentioned, you should in general avoid calling "exit" in a D program. There's a C function called "atexit" that allows to register a callback that is called after calling "exit". You could perhaps join the threads there. I don't know if that helps with the profiling though. Unfortunately I can't join threads, because the program wouldn't exit then, the threads run forever normally. I thought maybe there is some way to kill a thread gracefully in linux, so it can write its profiling information; or another way to get profiling. Thanks anyway.
Re: Profiling after exit()
On Friday, 28 July 2017 at 08:06:33 UTC, Eugene Wissner wrote: On Friday, 28 July 2017 at 06:32:59 UTC, Jacob Carlborg wrote: On 2017-07-27 16:30, Eugene Wissner wrote: I have a multi-threaded application, whose threads normally run forever. But I need to profile this program, so I compile the code with -profile, send a SIGTERM and call exit(0) from my signal handler to exit the program. The problem is that I get the profiling information only from the main thread, but not from the other ones. Is there a way to get the profiling information from all threads before terminating the program? Maybe some way to finish the threads gracefully? or manully call "write trace.log"-function for a thread? As others have mentioned, you should in general avoid calling "exit" in a D program. There's a C function called "atexit" that allows to register a callback that is called after calling "exit". You could perhaps join the threads there. I don't know if that helps with the profiling though. Unfortunately I can't join threads, because the program wouldn't exit then, the threads run forever normally. I thought maybe there is some way to kill a thread gracefully in linux, so it can write its profiling information; or another way to get profiling. Thanks anyway. There's no "gracefully" way to kill a thread. If your thread cannot join, then you're doing something wrong
Re: Profiling after exit()
On Friday, 28 July 2017 at 09:02:10 UTC, Temtaime wrote: There's no "gracefully" way to kill a thread. If your thread cannot join, then you're doing something wrong Our programs are intended to run "forever". 24/7 servers.
Re: Pass range to a function
On Thursday, 27 July 2017 at 21:16:03 UTC, Chris wrote: In C#, it'd be `IEnumerable`. I'd rather not do a to-array on the sequence, if possible. (e.g. It'd be nice to just pass the lazy sequence into my categorize function.) This comparison between Linq and D ranges might help you in the future too: https://github.com/wilzbach/linq
Re: It makes me sick!
On Friday, 28 July 2017 at 13:55:33 UTC, Anonymouse wrote: On Friday, 28 July 2017 at 05:14:16 UTC, FoxyBrown wrote: If dmd breaks in strange and unpredictable ways IT IS DMD's fault! No exceptions, no matter what you believe, what you say, what lawyer you pay to create a law for you to make you think you are legally correct! You can make any claim you want like: "The end user should install in to a clean dir so that DMD doesn't get confused and load a module that doesn't actually have any implementation" but that's just your opinion. At the end of the day it only makes you and dmd look bad when it doesn't work because of some lame minor issue that could be easily fixed. But it's not being installed, it's being manually extracted, meaning you can't even have cleanup scripts. Compare keeping an installation of audio files in mp3 (bird calls), and then getting an upgrade where they are in ogg in a new neat directory hierarchy. There's an installer that properly and cleanly removes the old mp3s before extracting the new files, as well as a bonus archive if you want to unzip it yourself. Manually extracting it onto the old directory puts the oggs next to the mp3s, leaving it with twice the number of original audio files. Meanwhile, the official upgrade path (installer) properly removes the stale ones. You can't reasonably expect your audio player to not list them all there. So, the program, if it is updated shouldn't use the mp3's then. Why the hell is the program that you say was upgraded to use the ogg still searching and using mp3's? You are trying to make up reasons why it shouldn't work... at least come up with valid reasons. Yes, there might be "twice" the files and one might waste space BUT that is different from the application crapping out and the end user spending hours trying to figure out what is wrong. TOTALLY different issues. We are not talking about "listing" files or anything like that, we are talking about the app not working because of "stale" files because it decided to use them, even though it should have been told not too because the whole point of the upgrade was to migrate from one set of files to another... and yet some idiot who programmed the app still had the app use the old files... it's the idiots fault... not the end user. What if the end user does a partial restore from some system issues and those mp4's were restored? Then what? The end users fault when he opens up the app and it crashes? Some programmers need to start taking responsibility for the crap they spew out. What a programmer is creating is effecting many many end users. It is up to the programmer to do the correct job to prevent a large factor of end user waste. That is what the programmer gets paid for.
Re: It makes me sick!
On Friday, 28 July 2017 at 01:10:03 UTC, Mike Parker wrote: On Friday, 28 July 2017 at 00:28:52 UTC, FoxyBrown wrote: You are not being very logical. The zip file as N files in it. No matter what those files are, it should be a closed system. That is, if I insert or add(not replace) M file to the directory structure it should not break D, period! That's *not* what happened here. Jonathan explained it quite well. std.datetime was refactored into a package, its contents split into new modules. When you import a module foo, dmd looks for: 1. foo.di 2. foo.d 3. foo/package.d When it finds one, it stops looking. It's not an error for all three to exist. Your error came because it found std/datetime.d, but you linked to a library that included symbols for std/datatetime/package.d. It's not the compiler's responsibility to error in that case. It's your responsibility to properly install. Why? Because NO file in the zip should be referencing any file not in the zip unless it is designed to behave that way(e.g., an external lib or whatever). If an old external program is referencing a file in dmd2 that isn't in the new zip it should err. Why? Because suppose you have an old program that references some old file in dmd2 dir and you upgrade dmd2 by extracting the zip. The program MAY still work and use broke functionality that will go undetected but be harmful. Why? Because dmd.exe is reference a file it shouldn't and it should know it shouldn't yet it does so anyways. It really has nothing to do with the file being in the dir but that dmd is being stupid because no one bothered to sanity checks because they are too lazy/think it's irrelevant because it doesn't effect them. That's unreasonable. I should be able to put any extra files anywhere in the dmd2 dir structure and it should NOT break dmd. There are numerous applications out there that can break if you simply overwrite a directory with a newer version of the app. DMD is not alone with this. You should always delete the directory first. It's precisely why the compiler does so. So, that proves nothing. You are simply ok with wasting the end users time... you should grow up and take responsibility for what you release. Your logic is not sound mathematically unless you think it's ok to waste end users time: There is 1 programmer, you and N end users of your app. Ok? got that? Very simple mathematics. Now, suppose you decide it is not worth your 10 mins to fix a problem or add sanity checks or robustness to your program and it effects 1% of the users of your app(we'll use a low percentage just to give you a fighting chance, which you don't deserve but we'll allow it). Now, suppose that wastes only 10 mins of the end users time(again, we'll low ball the number because usually it is much greater since the end user is not familiar with out the program works like the creator of that program is). This means that 10*0.01*N minutes are wasted overall of the human race because you didn't want to spend 10 minutes to fix a program. If 1 users use your app, that is 1000 minutes wasted ~= 17 hours. And that is a low estimate. So, just because you want to save 10 minutes you've wasted 17 hours of human life... what an investment! That is your mentality. You should run for US President! Your mentality fits right in with how the US handles it's money. Remember how much of your own life has been wasted on fixing other peoples mess and maybe you might realize how bad it is... probably not though, maybe when your on your death bed you might get a spark of sanity... but then it will be too late and pointless.
Re: It makes me sick!
On Friday, 28 July 2017 at 21:23:22 UTC, FoxyBrown wrote: So, the program, if it is updated shouldn't use the mp3's then. Why the hell is the program that you say was upgraded to use the ogg still searching and using mp3's? You are trying to make up reasons why it shouldn't work... at least come up with valid reasons. I'm sorry if I'm not expressing it in a way that agrees with you but you're looking at the wrong side of the example. You're pasting one set of files onto another and expect the software to somehow know to ignore some of them.
Re: It makes me sick!
On Friday, 28 July 2017 at 21:35:01 UTC, Anonymouse wrote: On Friday, 28 July 2017 at 21:23:22 UTC, FoxyBrown wrote: So, the program, if it is updated shouldn't use the mp3's then. Why the hell is the program that you say was upgraded to use the ogg still searching and using mp3's? You are trying to make up reasons why it shouldn't work... at least come up with valid reasons. I'm sorry if I'm not expressing it in a way that agrees with you but you're looking at the wrong side of the example. You're pasting one set of files onto another and expect the software to somehow know to ignore some of them. YES! EXACTLY! I AM EXPECTING THE SOFTWARE, WHICH IS WHAT THE PROGRAMMER CREATED AND HANDLES THE FILES TO ACTUALLY KNOW WHAT THE HELL IT IS DOING! I'm sorry if that is too complex to understand. If the software has some build in design that makes it use arbitrary files in a specific way like it does with std.datetime, then it should have sanity checks. After all, who the hell knows more about dmd using std.datetime and how it uses it and such, the end user or the programmer of dmd? You are expecting the end user, who generally knows very little to do the dirty work instead of having the programmer who is suppose to know what the fuck is going on to add sanity checks, useful error messages, etc. Ali suggested a very reasonable solution that would have solved this problem and you guys are against it and offer no solution to the issue. It all boils down to laziness. Too lazy to spend the time to add code that makes dmd more robust. Simple as that. It's not that it can't be done, like you bone-heads are claiming, but that you simply don't want to do it. Another very simple solution: Before the zip file is generated, a listing of all the files in the dmd installation that are used(which should be all of them) is taken. This file then is parsed by dmd and only those files in the dmd dir that are in the list are used. This would also have avoided the issue and future issues. Any stale files in the dir would simply be ignored. But, again, too much work. Keep making the end users deal with these problems instead of doing your due diligence. That we, we have something to waste our time with in these forums instead of real problems.
Re: std.meta.Replace using index
On 07/28/2017 12:04 PM, Ali Çehreli wrote: On 07/28/2017 01:22 AM, Nicholas Wilson wrote: Hi I want to replace each occurrence of a particular type in an AliasSeq with a type from another AliasSeq (the both have the same length) with the corresponding index i.e. (int long long float) (byte char double dchar) replacing long should yield (int char double float) std.meta.Replace would see to do the trick except the lambda depends in the index and I'm not sure how to pass that. I think it works: template replace(T) { template inside(Src...) { template from(Dst...) { import std.meta; enum f = staticIndexOf!(T, Src); static if (f == -1) { alias from = Src; } else { alias from = AliasSeq!(Src[0 .. f], Dst[f], inside!(Src[f + 1 .. $]).from!(Dst[f + 1 .. $])); } } } } unittest { import std.meta : AliasSeq; replace!long .inside!(long, int, long, long, float, long) .from!(int, byte, char, double, dchar, real) a; static assert(is (typeof(a) == AliasSeq!(int, int, char, double, float, real))); } void main() { } Ali
Re: std.meta.Replace using index
On 07/28/2017 01:22 AM, Nicholas Wilson wrote: Hi I want to replace each occurrence of a particular type in an AliasSeq with a type from another AliasSeq (the both have the same length) with the corresponding index i.e. (int long long float) (byte char double dchar) replacing long should yield (int char double float) std.meta.Replace would see to do the trick except the lambda depends in the index and I'm not sure how to pass that. No time to complete it but here is a busy syntax that may work: template Replace(T) { template From(Src...) { template With(Dst...) { pragma(msg, T); pragma(msg, Src); pragma(msg, Dst); // Place holder, which needs to be implemented. :) import std.meta : AliasSeq; alias With = AliasSeq!int; } } } void main() { Replace!long .From!(int, long, long, float) .With!(byte, char, double, dchar) a; } Ali
Re: std.meta.Replace using index
On Friday, 28 July 2017 at 22:06:27 UTC, Ali Çehreli wrote: I think it works: template replace(T) { template inside(Src...) { template from(Dst...) { import std.meta; enum f = staticIndexOf!(T, Src); static if (f == -1) { alias from = Src; } else { alias from = AliasSeq!(Src[0 .. f], Dst[f], inside!(Src[f + 1 .. $]).from!(Dst[f + 1 .. $])); } } } } unittest { import std.meta : AliasSeq; replace!long .inside!(long, int, long, long, float, long) .from!(int, byte, char, double, dchar, real) a; static assert(is (typeof(a) == AliasSeq!(int, int, char, double, float, real))); } void main() { } Ali Thanks!
Re: Pass range to a function
On Thursday, 27 July 2017 at 21:16:03 UTC, Chris wrote: I'm using regex `matchAll`, and mapping it to get a sequence of strings. I then want to pass that sequence to a function. What is the general "sequence of strings" type declaration I'd need to use? In C#, it'd be `IEnumerable`. I'd rather not do a to-array on the sequence, if possible. (e.g. It'd be nice to just pass the lazy sequence into my categorize function.) What is the value of `???` in the following program: ``` import std.stdio, std.regex, std.string, std.algorithm.iteration; auto regexToStrSeq(RegexMatch!string toks) { return toks.map!(t => t[0].strip()); } void categorize(??? toks) { foreach (t; toks) { writeln(t); } } void main() { auto reg = regex("[\\s,]*(~@|[\\[\\]{\\}()'`~^@]|\"(?:.|[^\"])*\"|;.*|[^\\s\\[\\]{}('\"`,;)]*)"); auto line = "(+ 1 (* 2 32))"; auto baz = matchAll(line, reg); categorize(regexToStrSeq(baz).array); } ``` If for some reason you can't make categorize a template like Ali suggested, or you need runtime polymorphism, you can use std.range.interfaces: import std.range.interfaces; void categorize(InputRange!string toks) { foreach (t; toks) { writeln(t); } } void main() { //etc. categorize(inputRangeObject(regexToStrSeq(baz))); }
Re: dmd can't build gtk x64
On Friday, 28 July 2017 at 22:45:58 UTC, FoxyBrown wrote: Error: can't run 'C:\VS\VC\Tools\MSVC\14.10.25017\bin\HostX64\x64', check PATH It is trying to run some x64.exe/com/bat file... why? What is this file? simply doing dmd -m64 build.d Works fine for x86. I was able to get this to work by copying all the required lib's to the lib dir from the windows sdk(liburct.lib, shell32.lib) and copying link.exe to x64. The program compiles, but when ran, I get the error object.Exception@generated\gtkd\gtkd\Loader.d(125): Library load failed (libgdk-3-0.dll): is not a valid Win32 application. which I assume is due to the fact that I have x86 gtk installed(I think, as I thought I installed the dual package... can't seem to find x64 gtk3+ standalone).
dmd can't build gtk x64
Error: can't run 'C:\VS\VC\Tools\MSVC\14.10.25017\bin\HostX64\x64', check PATH It is trying to run some x64.exe/com/bat file... why? What is this file? simply doing dmd -m64 build.d Works fine for x86.
Error 1: Previous Definition Different : _D3gtk3All12__ModuleInfoZ (gtk.All.__ModuleInfo)
After upgrading to latest dmd and having to rebuild gtk, I now get the following error Error 1: Previous Definition Different : _D3gtk3All12__ModuleInfoZ (gtk.All.__ModuleInfo) in my apps that were previously working(no changes, opened up old app and tried to build it and it didn't work). All I did was upgrade dmd2. So tired of D and it's crap ;/ So unstable in so many ways. About 10% as productive overall than other languages I've used. It's error messages are about as helpful as a rock.
Re: It makes me sick!
On Friday, 28 July 2017 at 12:48:37 UTC, Grander wrote: On Friday, 28 July 2017 at 12:40:27 UTC, rjframe wrote: On Fri, 28 Jul 2017 05:14:16 +, FoxyBrown wrote: You can make any claim you want like: "The end user should install in to a clean dir so that DMD doesn't get confused and load a module that doesn't actually have any implementation" but that's just your opinion. I have never seen extracting into the directory as a supported upgrade path for anything except the simplest of applications and a few PHP projects that supply a migration script. Well, any other installer would have done the required cleanup in such a case. One of the reasons to extract a zip instead of using an installer is that you want to replace only certain files. There's nothing reasonable about this argument.
Re: Bug or not? Statics inside blocks
On Saturday, July 29, 2017 1:54:29 AM MDT Cecil Ward via Digitalmars-d-learn wrote: > The snippet below failed to compile (I think) in the latest DMD - > but I can't see the error message in the web-based editor at > dlang.org. It certainly failed to compile under GDC 5.2.0 when > tried out using d.godbolt.org. (Is there any chance of a later > GDC compiler there?) > > Is it my bug, or a compiler bug? (name clash at link-time?): > > void main() > { > { > immutable static dstring str1 = "a"; > } > { > immutable static dstring str1 = "b"; > } > } Well, based on the error message, I'd say that the restriction is on purpose: q.d(7): Error: declaration q.main.str1 is already defined in another scope in main The bit about "another scope" just wouldn't make sense if it weren't on purpose, since there is normally no such restriction. That being said, I have no idea why such a restriction would be in place. It works perfectly well if the variables aren't static, so it's something about static that's causing it. I would argue that it _should_ work, so I think that you should at least open up an enhancement request, but I have no idea what the compiler devs would say on the matter. - Jonathan M Davis
Re: Bug or not? Statics inside blocks
On 07/29/2017 03:54 AM, Cecil Ward wrote: Is it my bug, or a compiler bug? (name clash at link-time?): void main() { { immutable static dstring str1 = "a"; } { immutable static dstring str1 = "b"; } } https://issues.dlang.org/show_bug.cgi?id=11720 Ideally (imo), the code would work. The two variables would need different mangled names. No idea how hard that would be to implement.
D Debug101
BLUF: How can I set up a D debugger? Background: So, I've been trying to get a D debugger set up and I've been having a pretty difficult time doing so. Hoping someone can point me towards the right direction. The compiler I'm using is DMD (32 bit) v2.075.0 on Windows. I've seen the list of debuggers below but it's been a mix of results: https://wiki.dlang.org/Debuggers -I don't want anything to do with Mago since it appears to be tied with VS -ddbg appears to be dead -WinDbg and OllyDbg 2 kind of work WinDbg will allow me to step through lines of code which is great but I can't seem to get a list of declared variables and their values. If I knew how to get such a list I'd be happy. OllyDbg 2 can debug but it appears to be on an assembly level. I don't want to even go there. It also seems to lack a variables list like WinDbg. I'd be fine with GDB if that worked but it chokes on any D compiled program I pass to it. Unsure if I am missing flags when compiling or something else. I'm hoping I am just doing something stupid. Advice appreciated. Thanks
Bug or not? Statics inside blocks
The snippet below failed to compile (I think) in the latest DMD - but I can't see the error message in the web-based editor at dlang.org. It certainly failed to compile under GDC 5.2.0 when tried out using d.godbolt.org. (Is there any chance of a later GDC compiler there?) Is it my bug, or a compiler bug? (name clash at link-time?): void main() { { immutable static dstring str1 = "a"; } { immutable static dstring str1 = "b"; } }
Re: Bug or not? Statics inside blocks
On Saturday, 29 July 2017 at 01:54:29 UTC, Cecil Ward wrote: The snippet below failed to compile (I think) in the latest DMD - but I can't see the error message in the web-based editor at dlang.org. It certainly failed to compile under GDC 5.2.0 when tried out using d.godbolt.org. (Is there any chance of a later GDC compiler there?) Is it my bug, or a compiler bug? (name clash at link-time?): void main() { { immutable static dstring str1 = "a"; } { immutable static dstring str1 = "b"; } } Workaround is just to rename one, assuming that avoids a name clash at-time.