Re: Adding more projects to the Project Tester
On Friday, 6 July 2018 at 03:19:44 UTC, Seb wrote: So learning from the recent Vibe.d regression fiasco (we temporarily disabled a subconfiguration in Vibe.d and promptly got a regression in 2.081), I think we should try to add more projects to the Project Tester. The current list is here: https://github.com/dlang/ci/blob/master/vars/runPipeline.groovy#L443 Any suggestions? Why should I add my project to the Project Tester? -- Once a project is added to the Project Tester, DMD can't regress on it anymore as for every PR at dmd, druntime, phobos, tools and dub the testsuite of the added projects are run. How does the Project Tester work? - - By default, it will run the same commands as Travis would do. Although, if necessary, custom commands can be used too. - It will checkout the latest, stable git tag Requirements - moderately popular or was prone to regressions in the past - rather easy to build (i.e. you don't need to download and recompile clang) - no flaky testsuite (random errors in the testsuite due to network connectivity shouldn't happen. Though there's `DETERMINISTIC_HINT=1` set, s.t. you could disable such parts of your testsuite) - reachable author or development (if there's ever a case where we need to push changes via a trivial PR to the repo, it shouldn't sit in the queue for weeks) The LDC compiler? kinke recently had an issue because of all the C++ integration changes upstream: https://github.com/ldc-developers/ldc/pull/2752#issuecomment-398897813 As perhaps the largest consumer of extern(C++), it may make sense to add it for all the C++ work being done. It would require the llvm package be pre-installed in the test environ. List of current projects looks great, was tough to think of anything to add.
Re: How to use LLD linker?
On Saturday, 30 June 2018 at 10:48:49 UTC, Suliman wrote: Correct me if I am wrong, but I have read news that dmd now can be used without C++ Build Tools. I trying to build simple project. And getting Error: Warning: no Visual C++ installation detected OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html OPTLINK : Error 8: Illegal Filename ... Error: C:\D\dmd2\windows\bin\link.exe failed with status: 1 ldc2 failed with exit code 1. Same with dmd. How to use LLD linker? Well I just installed the VS 2017 to try the ldc and get (maybe) the same error. dub run --config=application --arch=x86_64 --build=debug --compiler=ldc2 Performing "debug" build using ldc2 for x86_64. lib ~master: building configuration "application"... OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html OPTLINK : Error 8: Illegal Filename /NOLOGO /DEBUG /OPT:REF /OPT:ICF /DEFAULTLIB:libcmt /DEFAULTLIB:libvcruntime "/OUT:.dub\build\application-debug-windows-x86_64-ldc_2081-FC0CCB721F0C7E0D58B93FB1E50E3401\lib.exe" ".dub\obj\lib.obj" "d:\ldc2\lib\ldc_rt.builtins.lib" /LIBPATH:d:/ldc2/bin/../lib phobos2-ldc.lib druntime-ldc.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ^ Error: d:\D\dmd2\windows\bin\link.exe failed with status: 1 ldc2 failed with exit code 1.
Adding more projects to the Project Tester
So learning from the recent Vibe.d regression fiasco (we temporarily disabled a subconfiguration in Vibe.d and promptly got a regression in 2.081), I think we should try to add more projects to the Project Tester. The current list is here: https://github.com/dlang/ci/blob/master/vars/runPipeline.groovy#L443 Any suggestions? Why should I add my project to the Project Tester? -- Once a project is added to the Project Tester, DMD can't regress on it anymore as for every PR at dmd, druntime, phobos, tools and dub the testsuite of the added projects are run. How does the Project Tester work? - - By default, it will run the same commands as Travis would do. Although, if necessary, custom commands can be used too. - It will checkout the latest, stable git tag Requirements - moderately popular or was prone to regressions in the past - rather easy to build (i.e. you don't need to download and recompile clang) - no flaky testsuite (random errors in the testsuite due to network connectivity shouldn't happen. Though there's `DETERMINISTIC_HINT=1` set, s.t. you could disable such parts of your testsuite) - reachable author or development (if there's ever a case where we need to push changes via a trivial PR to the repo, it shouldn't sit in the queue for weeks)
Re: std.traits : Select - could it be better?
On Thursday, 5 July 2018 at 20:29:02 UTC, Steven Schveighoffer wrote: On 7/5/18 4:27 PM, Steven Schveighoffer wrote: template BetterSelect(bool cond, alias temp1, alias temp2, Args...) { import std.meta : Instantiate; static if(cond) alias BetterSelect = Instantiate!(temp1, Args); else alias BetterSelect = Instantiate!(temp2, Args); } ugh, got too cute for my own good :) No need for Instantiate here: alias BetterSelect = temp1!Args; alias BetterSelect = temp2!Args; -Steve I find another solution :) template Try(alias T, Args...) { static if( is( T!Args ) ) alias Try = T!Args; } alias U = Select!( isPointer!T, Try!( PointerTarget, T ), T );
Re: Argon: an alternative parser for command-line arguments
On Thursday, 3 March 2016 at 09:33:38 UTC, Johannes Pfau wrote: Am Thu, 03 Mar 2016 09:09:38 + schrieb Markus Laker : * It can open files specified at the command line. It can do a simplified version of what cat(1) does and many Perl programs so, and open a file specified by the user or fall back to reading from stdin. There's also a convention that the user can type "-" to mean stdin or stdout, depending on the open-mode you specify. The rest of this list sounds quite good, but please reconsider automatically opening files: https://media.ccc.de/v/32c3-7130-the_perl_jam_2 No one wants to watch a 40 minute video just to find out what your point is. I guess the scenario can't happen in D as our open file methods won't execute programs (!) but still But still? What other problem is there? What does it matter whether the command line parser opens the file or some other part of the program does?
Re: Static member function returning immutable slice; compiler error: without this cannot be immutable
On 07/05/2018 01:00 PM, ag0aep6g wrote: > `immutable` means that the data can't ever change. Not even the owning > Foo is allowed to change it. If you want to disallow changes from > outside, but still allow the owning Foo to make changes, use `const`: > > static const(Foo[]) getFooList() To add, in that context 'immutable' would be a guarantee to the outside world: "I will never change this data." On the other hand, 'const' means "Dear compiler, please make sure the caller does not mutate this data." However, I think the return type would be more useful as const(Foo)[] to let the caller to be able to add elements to their local copy of the slice: struct Foo { } Foo[] foos; // const(Foo[]) would not allow the concatenation in main. const(Foo)[] getFooList() { return foos; } void main() { auto f = getFooList(); f ~= Foo(); } But then one might argue that if the caller would concatenate anyway, which would cause memory allocation and copying, wouldn't the caller better use .dup to get a mutable copy of the elements. auto f = getFooList().dup; f ~= Foo(); I don't know... Too much analysis... :) Ali
[Issue 19064] [REG2.081] getOverloads traits returns empty tuples for void functions
https://issues.dlang.org/show_bug.cgi?id=19064 --- Comment #5 from github-bugzi...@puremagic.com --- Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/d3f65c73d521f0279c57fec4aec09d03f49b4028 Fix Issue 19064 - [REG2.081] Vibe.d's InterfaceProxy no longer works https://github.com/dlang/dmd/commit/678a445c5a275d7dace466970b48cb2961341cd1 Merge pull request #8456 from RazvanN7/Issue_19064 Fix Issue 19064 - [REG2.081] Vibe.d's InterfaceProxy no longer works merged-on-behalf-of: Sebastian Wilzbach --
[Issue 19064] [REG2.081] getOverloads traits returns empty tuples for void functions
https://issues.dlang.org/show_bug.cgi?id=19064 github-bugzi...@puremagic.com changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --
Re: Why is it hard to make Qt bindings?
On Thursday, 5 July 2018 at 12:52:49 UTC, Steven Schveighoffer wrote: On 7/5/18 4:42 AM, drug wrote: There were several attempts to make Qt binding for dlang, but either they has failed or has been stalled. It would be nice to collect that experience. Considering 2.081 supports C++ special member (not all but majority) isn't it time to make another attempt or the problem is more complex? Could you publish your experience in making Qt bindings here? I'm not a Qt user, but doesn't Qt require a special pre-compiler, or even use the preprocessor in a way that is difficult to duplicate in D? Qt does have it's own pre-processor, but CopperSpice, a fork of Qt does not require that. http://www.copperspice.com/
Re: DVM - D Version Manager 0.4.4
On Wednesday, 4 July 2018 at 19:14:57 UTC, Jacob Carlborg wrote: On 2018-07-03 03:34, Tony wrote: Thanks, that worked! It doesn't announce where it put the compiler, which turns out to be: C:\Users\\AppData\Roaming\dvm\ You're not supposed to know where it puts the compiler. You're activating it with "dvm use " where "" is the version you want to activate. This will persist for the end of the shell session. To set a default compiler use "dvm use -d". This allows to use separate versions simultaneously in different shell sessions. See the usage information [1]. [1] https://github.com/jacob-carlborg/dvm#use-a-compiler I should have done a little more reading. Thanks, and thanks for writing it!
Re: libfirm-d - D bindings of Firm, a compiler IR based on the SSA form
On Thursday, 5 July 2018 at 01:11:58 UTC, Basile B. wrote: On Thursday, 5 July 2018 at 00:00:07 UTC, Chris M. wrote: On Sunday, 1 July 2018 at 12:04:06 UTC, Basile B. wrote: [...] Very nice, I remember checking this one out a while back. I don't see the files from the ADT module though, was there a reason they weren't included? https://github.com/libfirm/libfirm/tree/master/include/libfirm/adt Yes there's a reason that is that these files mostly contain data structures, they are not needed in D and i don't remember having seen them as parameter type during translation of the headers, (although it's been done semi manually, so i could have missed one). Makes sense, I didn't think you would have just missed them.
Re: Sutter's ISO C++ Trip Report - The best compliment is when someone else steals your ideas....
On Thu, Jul 05, 2018 at 10:05:44PM +, John Carter via Digitalmars-d wrote: [...] > At work here I have emerged from a long, dark, debate on the subject > within the team. > > The ultimately solution was to realize there are actually TWO > facilities with TWO entirely different purposes that have been > overloaded with the same name. > > Alas, the word "assert" now is inextricably mired in this confusion. > > Half our team used asserts to mean "This mustn't _ever_ happen in unit > tests (unless we set up a specific test case for that), and it will > never happen if the incoming signal is standards compliant, but it may > happen (due to RF noise, and/or competitor violating the standard > and/or adding in proprietary stuff into the data and/or we're being > attacked) so we _must_ fall through the assert at run time, and handle > that case somehow, but preferably make a note that something > unexpected happened." > > The other half of the team meant, "If the expression is false, it > means the code on this line or on the execution path prior to it is > definitely defective and must be fixed immediately. [...] In D, I believe the first meaning is assigned to "enforce" (i.e., std.exception.enforce), and the second meaning is assigned to "assert" (the built-in assert). Unfortunately, the word "assert" has been used outside the context of D to mean either thing, so people keep tripping over the terminology and using assert for the wrong thing. And it doesn't help that "enforce" is a library function rather than a built-in construct, which some people wrongly interpret as "secondary, therefore somehow inferior, and probably not what I intend". T -- "I suspect the best way to deal with procrastination is to put off the procrastination itself until later. I've been meaning to try this, but haven't gotten around to it yet. " -- swr
Re: Sutter's ISO C++ Trip Report - The best compliment is when someone else steals your ideas....
On Tuesday, 3 July 2018 at 04:54:46 UTC, Walter Bright wrote: On 7/2/2018 7:53 PM, John Carter wrote: In general all pre/post/assert-condition violations) cause a corrupted state that cannot be recovered from programmatically, and so they should never be reported to the calling code as exceptions or error codes that code could somehow handle. Ah, that's a really nice statement. So, I have finally convinced the C++ world about that! Now if I can only convince the D world :-) Oh, I'm convinced. At work here I have emerged from a long, dark, debate on the subject within the team. The ultimately solution was to realize there are actually TWO facilities with TWO entirely different purposes that have been overloaded with the same name. Alas, the word "assert" now is inextricably mired in this confusion. Half our team used asserts to mean "This mustn't _ever_ happen in unit tests (unless we set up a specific test case for that), and it will never happen if the incoming signal is standards compliant, but it may happen (due to RF noise, and/or competitor violating the standard and/or adding in proprietary stuff into the data and/or we're being attacked) so we _must_ fall through the assert at run time, and handle that case somehow, but preferably make a note that something unexpected happened." The other half of the team meant, "If the expression is false, it means the code on this line or on the execution path prior to it is definitely defective and must be fixed immediately. And there is absolutely no hope the code after it will work, and continuing on will make the system flaky and unreliable, and the only path back to reliable function is a reset. All code after this line may explicitly assume, and depend on, the expression being true. Any attempt to handle the possibility of the expression is false is buggy, useless and probably will be removed by the optimizer. Any urge to handle the possibility of the expression being false after the assert, should be replaced by the inclination to review the code on the execution path prior to the assert, to ensure that the expression will always be true." Alas, both sides were using the same word "assert" to mean these different things, resulting in conversations that went around and around in meaningless circles. We have resolved the debate by identifying these two different meanings, and given the facilities implementing them two different names and documenting the difference in meaning and intent.
[Issue 19057] 2.079 changelog variadic template and default arguments
https://issues.dlang.org/show_bug.cgi?id=19057 --- Comment #10 from johanenge...@weka.io --- (In reply to Steven Schveighoffer from comment #9) > (In reply to johanengelen from comment #7) > > This did break code at Weka, luckily in non-silent way, but now I probably > > will have to modify the old compiler to error on these things, to not cause > > trouble with silently broken code. > > I'm curious if there is any reason to have default parameter specification > in any of these cases. Given that you could never use the default parameters > anyway (you had to specify them all), isn't the fix to just change them all > to not have default values? Indeed, the fix is trivial. But finding all places to fix it may not be so easy. Perhaps it's not so bad and a regexp search will find them. I was happy to find out that it never really worked. --
Re: I have a plan.. I really DO
On Wednesday, 4 July 2018 at 19:29:55 UTC, Ecstatic Coder wrote: On Wednesday, 4 July 2018 at 18:05:15 UTC, wjoe wrote: On Wednesday, 4 July 2018 at 08:50:57 UTC, Ecstatic Coder wrote: But indeed, being able use D in a GC-free environment (like C++ and Rust do) would be something many people may NEED, for instance to be able to EASILY use D for soft-realtime applications like games. This has to be the no. 1 excuse. Games have been made with GC'd languages, 3D games, even. And successfully, too. Minecraft, a very successful one, comes to mind, which is or at least was made in Java. Plenty of games are made in C#, too. +1 Slow code is slow and allocating memory in a tight loop is a huge performance killer - regardless of language. +1 Nothing forces anyone to use the GC, memory can be managed manually via malloc/free and you get to do it with scope statements/nested functions which makes it nicer than in C. You could also implement shared/weak ptr stuff in D - warts and all. That's what Timur said. If you need a GC free standard library, I believe there is an ongoing effort -or several- at code.dlang.org and probably other places. You said do this and that, GC, etc. to motivate C++ folks to come to D. I say it's an excuse not to use D and no matter the effort of advertising, a GC free phobos, etc. on part of the D-Lang Foundation and contributors would make these folks switch. They would simply find a different excuse. You say that garbage collection is not a real problem for game development. Maybe, but that's not my experience. For instance, have you read Unity's own official recommandations on how to overcome this problem ? And obviously, Tibur, a highly skilled D game engine developer, is not a big fan of D's non incremental garbage collector, from the number of @nogc he has put in his Dlib container code. He has written no-GC libs for sure but he said in a blog post about his projects that he has no problem with GC. As long as you do not use it in critical areas. Modern D is a very attractive choice as a language for game development. Even the garbage collector is not a problem, because you can use object pools, custom allocators, or simply malloc and free. The key point is to know when the GC is invoked and try to avoid those cases in performance critical code. Personally, I prefer using malloc so that I can free the memory when I want, since delete has been deprecated and destroy just releases all the references to an object instance without actually deleting it. Using manual memory management imposes some restrictions on the code–for example, you can’t use closures or D’s built-in containers–but that, again, is not a big problem. A large effort is currently underway to lessen GC usage in dlib, so that you can use it to write fully unmanaged applications with ease. It has GC-free containers, file I/O streams, image decoders, and so on. https://dlang.org/blog/2016/09/16/project-highlight-timur-gafarov/ Remember he's into real-time stuff. As an indie game developer with a strong bias toward graphics engines and rendering tech, I always try to keep track of modern compiled languages effective enough for writing real-time stuff. The most obvious choice in this field is C++, and I actually used it for several years until I found D in 2010. I immediately fell in love with the language’s clean, beautiful syntax, its powerful template system, the numerous built-in features absent in C++, and the rich and easy to use standard library. Maybe you disagree with us because you are a professional game developer who has already released a successful commercial game in D without caring for the garbage collection. If it's the case, then nice, I'd be happy to have it wrong on this :) Read the blog post, you're wrong. Of course it's perfectly your right to develop your games without caring for all these performance "details". But other people do. GC in not a performance bottle neck if you truly know what you're doing. So, as I said, those who use C++ or Rust because D's GC is a problem for them, won't probably use D in its current state. If D had X people. Not customers.
[Issue 19057] 2.079 changelog variadic template and default arguments
https://issues.dlang.org/show_bug.cgi?id=19057 --- Comment #9 from Steven Schveighoffer --- (In reply to johanengelen from comment #7) > This did break code at Weka, luckily in non-silent way, but now I probably > will have to modify the old compiler to error on these things, to not cause > trouble with silently broken code. I'm curious if there is any reason to have default parameter specification in any of these cases. Given that you could never use the default parameters anyway (you had to specify them all), isn't the fix to just change them all to not have default values? --
[Issue 19057] 2.079 changelog variadic template and default arguments
https://issues.dlang.org/show_bug.cgi?id=19057 --- Comment #8 from Steven Schveighoffer --- I think we need to find a way to change this behavior, and soon. As it stands now, it doesn't make sense, as it's only useful in the __FILE__ and __LINE__ context. It could easily be generalized to fit all contexts, even in a way where the original behavior is valid. I'd flag this as a regression if it were up to me. The change that allows default parameters to work is reasonable. The change that makes them NEVER match IFTI-passed arguments is very bad and not intuitive. I'd absolutely expect this to work like anyone would think it should: Exception genErr(A...)(A args, string file = __FILE__, size_t line = __LINE__) Exception genSpecificError(string file = __FILE__, size_t line = __LINE) { return genErr(1, 2, 3, file, line); } And the workaround is NOT pleasant. --
Re: LDC 1.11.0 beta
Thx for the rationale; I may have a look at it over the weekend.
Re: 2.079 semantic change needs to be marked in changelog
On Tuesday, 3 July 2018 at 01:07:53 UTC, Walter Bright wrote: Please post bug reports (including documentation problems) on bugzilla! https://issues.dlang.org/show_bug.cgi?id=19057
[Issue 19057] 2.079 changelog variadic template and default arguments
https://issues.dlang.org/show_bug.cgi?id=19057 --- Comment #7 from johanenge...@weka.io --- Thanks for the support Steven. I hope this helps put the message across to be _very careful_ in making language additions / changes. This should have been a DIP. And not a PR that gets merged after a single (!) day. It's not a good story at all for industrial use of D. Note that with the current high-paced release cycle, testing of new compilers is guaranteed to happen only after 2 new releases have happened, as I've argued before. Proof given again in this bug report. This did break code at Weka, luckily in non-silent way, but now I probably will have to modify the old compiler to error on these things, to not cause trouble with silently broken code. Regardless of breakage, the new behavior is also one more special case to learn about in the language. I can already see style guides telling people to never use this functionality, except for __FILE__. This is a bit of a rant, I know, my apologies for that, but it seems my message has not gotten through yet and I don't know how else than to just repeat it. --
[Issue 19057] 2.079 changelog variadic template and default arguments
https://issues.dlang.org/show_bug.cgi?id=19057 --- Comment #6 from Steven Schveighoffer --- OK, I misunderstood. So essentially, any function that uses variadic parameters AND a normal parameter with a default value was EXACTLY the same as a function which takes the varargs parameter and a normal parameter WITHOUT a default value prior to 2.079. i.e. ALL code that uses default parameters after varargs parameters can be rewritten to simply remove the default parameter, and the same behavior occurred But in addition, there is a strange new behavior that has default parameters NEVER match the parameters unless you disable IFTI. Indeed I find it odd that this would be the case: void foo(A...)(A a, int timeout) {} void bar(A...)(A a, int timeout = 0) {} foo(1); // equivalent to foo!()(1) bar(1); // equivalent to bar!(int)(1, 0) ??? Given the use case of file and line parameters, this makes sense, as you almost never want to pass those parameters. But in the general case it makes very little sense. I'm pretty sure phobos was changed to take advantage of this immediately. So reverting would be really painful, right? If I were to start over before 2.079, this is the path I would have taken: 1. Make default parameters in these cases actually work in the way we would expect (i.e. they match if they are the right type, otherwise they go to the variadic). 2. Fix issue 18919 3. Create a new type `Location`, which accepts a filename and line number, and use THAT as the final parameter for such functions, with a default value of Location loc = Location(__FILE__, __LINE__). Now, you would never "accidentally" pass in a file or line number. I don't know the path forward now... --
[Issue 19060] [REG2.081] Incorrect "Using this as a type is deprecated" error
https://issues.dlang.org/show_bug.cgi?id=19060 --- Comment #5 from johanenge...@weka.io --- OK, then this is still broken and should receive a deprecation message too: ``` struct S { int a; bool x; public ref foo() { alias yoyo = this.x; return yoyo; } } ``` --
[Issue 19057] 2.079 changelog variadic template and default arguments
https://issues.dlang.org/show_bug.cgi?id=19057 Jonathan M Davis changed: What|Removed |Added CC||issues.dl...@jmdavisprog.co ||m --- Comment #5 from Jonathan M Davis --- Honestly, I would guess that far more code has been written to take advantage of the new behavior since it was released than was ever purposefully written to use the old behavior. I think that many (most?) of us had no clue that there was any way to use default arguments with variadic templates and IFTI prior to the 2.079 release, and many were very interested in the new behavior, because it fixes the file and line problem. So, changing the behvior back (as would have to be done to deprecate it) would definitely break existing code (whereas I question that much code was broken with the change in 2.079), and we've now had three major releases with the new behvior. So, I don't think that it makes any sense to try and deprecate the old behavior at this point. Clearly, the fact that this was a breaking change was not properly caught, and we should have deprecated the old behavior before introducing the new. But while that was definitely a screw-up, I don't see how it makes much sense to backtrack now. The new behavior has been out for three releases and is something that enough folks were looking for that I expect that there are quite a few folks using it now. So, if anything, if we were to decide that the current behavior is undesirable, then we arguably need a deprecation warning for that, not the old behavior. --
Re: std.traits : Select - could it be better?
On 7/5/18 4:27 PM, Steven Schveighoffer wrote: template BetterSelect(bool cond, alias temp1, alias temp2, Args...) { import std.meta : Instantiate; static if(cond) alias BetterSelect = Instantiate!(temp1, Args); else alias BetterSelect = Instantiate!(temp2, Args); } ugh, got too cute for my own good :) No need for Instantiate here: alias BetterSelect = temp1!Args; alias BetterSelect = temp2!Args; -Steve
Re: std.traits : Select - could it be better?
On 7/5/18 2:50 PM, SrMordred wrote: alias U = Select!( isPointer!T, PointerTarget!T, T ); This don´t compile if T are not a pointer; so you have to do this: static if( isPointer!T ) alias U = PointerTarget!T; else alias U = T; Shouldnt the 'correct' way of Select to work is ignoring the choice that was not taken? I love the idea of Select, but because of this I almost never use it. Hm... only thing I can think of is to do the instantiation within the template itself: template BetterSelect(bool cond, alias temp1, alias temp2, Args...) { import std.meta : Instantiate; static if(cond) alias BetterSelect = Instantiate!(temp1, Args); else alias BetterSelect = Instantiate!(temp2, Args); } alias U = BetterSelect!(isPointer!T, PointerTarget, Alias, T) Of course, this requires you to have templates that take EXACTLY the same parameters. I don't know if this (or something like it) is worth adding to std.traits or std.meta. -Steve
[Issue 19057] 2.079 changelog variadic template and default arguments
https://issues.dlang.org/show_bug.cgi?id=19057 --- Comment #4 from johanenge...@weka.io --- My concern is not about use cases. It's about breaking old code (silently), and also about strange (arguable) language behavior in the current situation. Note that before 2.079, the default argument was never used: the template would not match (in the testcase, `bar("a","b");` would not compile pre-2.079). (which is probably why Timothee wrote that it now becomes possible to use default args) Breaking old code: The fact that default argument was never used in pre-2079 is bad news: it means that old code always specifies a value for the default value, and thus that with the new compiler things are always broken (except when the caller is not using IFTI, which is unlikely I think). Strange new behavior: Adding a default value for a parameter now changes the template instantiation (if IFTI is used, which I think will happen in the majority of cases). ``` // Adding the default value will change behavior. void bar(Args...)(Args _args, int timeout /* = 0 */) { writeln(_args, timeout); } void main() { bar("a", "b", 2); // used to print "ab2", but since 2.079 prints "ab20" } ``` How many people would expect that to happen? The use case of the new style does not discuss much about how to override the default value (something that is trivially explained for normal functions). Here, you need to disable IFTI, which is painful. I've mainly seen discussion of the use case with __FILE__, but not for the general case. Note: there is no old use case, because the default value itself didn't work (syntax was allowed, but always need to specify value for the parameter at call site). A better fix for the __FILE__ use case would perhaps have been something like this: `void bar(Args...)(Args args, TypeThatIsNeverMatched = TypeThatIsNeverMatched.init, string file = __FILE__)`, where default arguments work but IFTI matching on callsite first matches the non-variadic parameters, and then starts matching the variadic part. --
Re: Static member function returning immutable slice; compiler error: without this cannot be immutable
On 07/05/2018 09:43 PM, Ivo Maffei wrote: class Foo { private static Foo[] fooSlice = new Foo[0]; //private static slice static immutable Foo[] getFooList() { //static method returning an immutable slice return fooSlice; } } However when compiling with dub I get the following error: Error: function `main.Foo.getFooList` without this cannot be immutable If you want to return an `immutable Foo[]`, you have to write the signature like this: static immutable(Foo[]) getFooList() Otherwise, the `immutable` qualifier applies to the method itself instead of the `Foo[]` return type. But a static method can't be immutable, so you get the error. But it won't work even if you fix that, because mutable doesn't convert to immutable like that. `immutable` means that the data can't ever change. Not even the owning Foo is allowed to change it. If you want to disallow changes from outside, but still allow the owning Foo to make changes, use `const`: static const(Foo[]) getFooList()
Re: Static member function returning immutable slice; compiler error: without this cannot be immutable
On Thursday, 5 July 2018 at 19:43:43 UTC, Ivo Maffei wrote: private static Foo[] fooSlice = new Foo[0]; //private static That initializer is useless, don't do that, just use the slice. static immutable Foo[] getFooList() { //static method returning an immutable slice Actually, that's a static immutable *method* returning a mutable slice. It is like you wrote: immutable { // bunch of methods here } so it is applying to this. To make it apply to the return, use parens around it: static immutable(Foo)[] getFooList() {} or static immutable(Foo[]) getFooList() {} the former is a mutable array of immutable objects and the latter is all immutable
[Issue 19064] [REG2.081] getOverloads traits returns empty tuples for void functions
https://issues.dlang.org/show_bug.cgi?id=19064 --- Comment #4 from Vladimir Panteleev --- (In reply to Seb from comment #0) > I'm still trying to reduce vibe-core, it's a bit difficult because DustMite > is pretty greedy and just removing the mixin methods would also lead to the > attribute not being found. The best way to reduce a regression is to invoke a working and broken compiler in the test script: https://github.com/CyberShadow/DustMite/wiki/Reducing-a-regression-between-two-D-versions --
[Issue 19058] __traits(getUnitTests) stops working with separate compilation in dmd 2.081.0
https://issues.dlang.org/show_bug.cgi?id=19058 johanenge...@weka.io changed: What|Removed |Added CC||johanenge...@weka.io --- Comment #1 from johanenge...@weka.io --- Do you have a testcase ? --
Static member function returning immutable slice; compiler error: without this cannot be immutable
I'm writing my first D program and I want to have a class which contains a private static list of objects. Moreover such list should be visible from outside the class, so I wrote a get method which returns such list as immutable (so that the list cannot be modified outside the class). Finally such method should be static since the list is static and therefore I should not need an object to access such list. Here is the code: class Foo { private static Foo[] fooSlice = new Foo[0]; //private static slice static immutable Foo[] getFooList() { //static method returning an immutable slice return fooSlice; } } However when compiling with dub I get the following error: Error: function `main.Foo.getFooList` without this cannot be immutable I noted that the error goes away when I remove the static or immutable qualifier. Thanks a lot for any help.
Re: std.traits : Select - could it be better?
On 7/5/18 2:50 PM, SrMordred wrote: alias U = Select!( isPointer!T, PointerTarget!T, T ); This don´t compile if T are not a pointer; so you have to do this: static if( isPointer!T ) alias U = PointerTarget!T; else alias U = T; Shouldnt the 'correct' way of Select to work is ignoring the choice that was not taken? I love the idea of Select, but because of this I almost never use it. mixin("alias U = " ~ Select!(isPointer!T, "PointerTarget!T", "T") ~ ";"); Ehm this is actually not better :o). Andrei
Re: dmd optimizer now converted to D!
On Thursday, 5 July 2018 at 14:30:05 UTC, Dukc wrote: foreach(j, ref piece; cast(int[4][]) a) { auto pieceI = j * 4; static foreach(i; 0 .. piece.length) piece[i] = pieceI + i; } Can probably be made even better by designing some template helper. Thanks! The cast to an array of int[4]s is just hilarious.
Re: dmd optimizer now converted to D!
On Thursday, 5 July 2018 at 14:05:42 UTC, Seb wrote: FYI: you can introduce scopes with static foreach to declare new variables: for (int i = 0; i < 4 * n; i += 4) { static foreach (k; 0..4) {{ auto idx = i + k a[idx] += idx; }} } Thanks! The two parentheses trick is nice. Generally, I was reluctant to declare a variable because, well, micro-optimizing means being dissatisfied with compiler optimization. So the mindset didn't allow me to just go and declare a variable in the innermost loop, in fear that the optimizer might not optimize the allocation away.
std.traits : Select - could it be better?
alias U = Select!( isPointer!T, PointerTarget!T, T ); This don´t compile if T are not a pointer; so you have to do this: static if( isPointer!T ) alias U = PointerTarget!T; else alias U = T; Shouldnt the 'correct' way of Select to work is ignoring the choice that was not taken? I love the idea of Select, but because of this I almost never use it.
[Issue 19059] Invalid integer literal 08 and 09 allowed
https://issues.dlang.org/show_bug.cgi?id=19059 RazvanN changed: What|Removed |Added CC||razvan.nitu1...@gmail.com --- Comment #6 from RazvanN --- Attemptive PR : https://github.com/dlang/dmd/pull/8451 --
[Issue 19060] [REG2.081] Incorrect "Using this as a type is deprecated" error
https://issues.dlang.org/show_bug.cgi?id=19060 RazvanN changed: What|Removed |Added CC||razvan.nitu1...@gmail.com --- Comment #4 from RazvanN --- Indeed, this is not a regression, it is intended behavior. --
Re: Alternative destructors, do/should we have them?
On Thursday, 5 July 2018 at 16:12:08 UTC, Atila Neves wrote: On Thursday, 5 July 2018 at 10:57:51 UTC, Dukc wrote: D does not have default constructors for structs, but I have thought that this might get around the problem: [...] You already have that capability: struct HandGrenade { void* ptr; void destroy() { import core.stdc.stdlib: free; free(ptr); } } This isn't a great example since it's perfectly fine to pass null to core.stdc.stdlib.free. Atila On Thursday, 5 July 2018 at 16:12:08 UTC, Atila Neves wrote: This isn't a great example since it's perfectly fine to pass null to core.stdc.stdlib.free. Atila You're right. Well, It could be some custom allocation table that does not check for such things: struct HandGrenade {void* ptr; ~this() { foreach ( ref _byte; cast(ubyte[]) ptr[0 .. memoryTable.assumeSorted.upperBound(ptr).front - ptr] ) _byte = 0; } }
[Issue 19057] 2.079 changelog variadic template and default arguments
https://issues.dlang.org/show_bug.cgi?id=19057 Seb changed: What|Removed |Added CC||greensunn...@gmail.com --
Re: Alternative destructors, do/should we have them?
On Thursday, 5 July 2018 at 15:58:14 UTC, Andrea Fontana wrote: On Thursday, 5 July 2018 at 10:57:51 UTC, Dukc wrote: If not, should we in your opinion have an ability to define an alternative destructor which runs only when explicitly requested? What does "when explicity requested" mean? That the alternative destructor runs only when you ask it to. There would be some way to say before an end of a block, return statement, break statement ect that you want the alternative destructor to be applied to the struct. The normal destructor would not run when an alternative one is used, but would run otherwise. In fact, in this case it would be enough to elide the destructor somehow.
[Issue 19057] 2.079 changelog variadic template and default arguments
https://issues.dlang.org/show_bug.cgi?id=19057 Steven Schveighoffer changed: What|Removed |Added See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=8687 --
[Issue 8687] Variadic templates do not work properly with default arguments
https://issues.dlang.org/show_bug.cgi?id=8687 Steven Schveighoffer changed: What|Removed |Added See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=19057 --
[Issue 19064] [REG2.081] getOverloads traits returns empty tuples for void functions
https://issues.dlang.org/show_bug.cgi?id=19064 Seb changed: What|Removed |Added Summary|[REG2.081] Vibe.d's |[REG2.081] getOverloads |InterfaceProxy no longer|traits returns empty tuples |works |for void functions --
Re: ranges.chunks and map! does not work
On Thursday, 5 July 2018 at 12:00:03 UTC, vit wrote: On Thursday, 5 July 2018 at 09:47:32 UTC, Andre Pany wrote: [...] roundRobin doesn't return RandomAccessRange => chunks doesn't return range of RandomAccessRange => Error: no [] operator overload try this: string content = roundRobin(timestamps, temperatures, pressures) .array .chunks(3) //.map!(c => c.array) .map!(c => "%.10g,%.10g,%.10g".format(c[0],c[1],c[2])) .join("\n"); Thanks a lot for all the answers. Kind regards Andre
Re: Function Template for Dynamic Parameter
On Sunday, 1 July 2018 at 12:46:30 UTC, Timoses wrote: On Sunday, 1 July 2018 at 11:58:30 UTC, vino.B wrote: On Sunday, 1 July 2018 at 11:52:19 UTC, Alex wrote: NewType.d(19): Error: function declaration without return type. (Note that constructors are always named this) [...] auto coCleanFiles(T ...)(T args) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(FFs, SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name, a.timeLastModified))); return dFiles; } void ptManagecoRoutine(T)(T function(T ...)(T args), Array!string Dirlst) { alias scRType = typeof(coRoutine(args.init)); auto PFresult = taskPool.workerLocalStorage!scRType; ReturnType!coRoutine rData; foreach (string FFs; Dirlst[]) { PFresult.get ~= coRoutine(FFs.strip); } foreach(i; PFresult.toRange) { rData ~= i[][]; } if (!rData[].empty) { rData[].sort!((a,b) => a[1] < b[1]).each!(e => writefln!"%-83s %.20s"(e[0], e[1].to!string)); } } void main () { Array!string CleanDirlst; CleanDirlst.insertBack("C:\\Temp\\BACKUP1"); ptManagecoRoutine(, CleanDirlst); } auto coCleanFiles(T ...)(T args) { ... } void ptManagecoRoutine(T)(T fun, Array!string DirList) { foreach (dir; DirList) fun(dir); } or void ptManagecoRoutine2(alias func)(Array!string DirList) if (is (typeof(func!(typeof(DirList[0]))) == function)) { alias t = typeof(DirList[0]); ptManagecoRoutine(!t, DirList); } callable via Array!string CleanDirlst; ptManagecoRoutine(!string, CleanDirlst); ptManagecoRoutine2!coCleanFiles(CleanDirlst); Hi All, Request your help on the below code auto coCleanFiles(T ...) (T FFs) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(FFs, SpanMode.depth).map!(a => tuple(a.name, a.timeCreated))); return dFiles; } void process(T)(T pfunction, Array!string Dirlst) { alias wlsType = typeof(pfunction(T)); auto Result = taskPool.workerLocalStorage!wlsType(); foreach (FFs; parallel(Dirlst[],1)) { Result.get ~= pfunction(FFs); } foreach(i; Result.toRange) { writeln(i[][]); } } void main() { Array!string Cleanlst; Cleanlst.insert("C:\\Temp\\BACKUP1"); process(, Cleanlst); } Error : Error: coCleanFiles(T...)(T FFs) is not an lvalue and cannot be modified From, Vino.B
Re: Alternative destructors, do/should we have them?
On Thursday, 5 July 2018 at 10:57:51 UTC, Dukc wrote: D does not have default constructors for structs, but I have thought that this might get around the problem: [...] You already have that capability: struct HandGrenade { void* ptr; void destroy() { import core.stdc.stdlib: free; free(ptr); } } This isn't a great example since it's perfectly fine to pass null to core.stdc.stdlib.free. Atila
Re: Compilation is taking a ton of memory
On Wed, Jul 04, 2018 at 04:17:22PM -0400, Nick Sabalausky (Abscissa) via Digitalmars-d wrote: [...] > Long compilation times are almost always the fault of Dub. Dub is > pretty well-known for taking DMD's near-instant compile times and > bloating them out to the ridiculous (by D standards) lengths you're > experiencing. I'd say try just writing a basic buildscript that runs > DMD directly. Plus, that way you can customize it to your own > project's needs: Which files/packages get compiled together, which get > compiled separately. Yeah, I'm sorry to say that I have been quite disappointed with dub (as a build system), and currently have taken to avoiding it as much as possible. As a packaging system it's not bad, but it simply doesn't have the options I need to use it as a build tool. But to be fair, it's not always dub's fault. Heavy template / CTFE usage is also known to bloat compilation times, sometimes by a lot. Earlier this year I discovered that the very act of importing std.format or std.regex causes compilation time to almost double. There were some issues related to compiling with -unittest that triggered this behaviour, though we found that the underlying issue was actually more tricky than it might first appear. I don't remember if this issue has been completely resolved yet. T -- Живёшь только однажды.
Re: Alternative destructors, do/should we have them?
On Thursday, 5 July 2018 at 10:57:51 UTC, Dukc wrote: If not, should we in your opinion have an ability to define an alternative destructor which runs only when explicitly requested? What does "when explicity requested" mean?
[Issue 18992] Appender doesn't work with structs that have impure postblit
https://issues.dlang.org/show_bug.cgi?id=18992 Andrea Fontana changed: What|Removed |Added CC||trik...@gmail.com --- Comment #1 from Andrea Fontana --- See https://issues.dlang.org/show_bug.cgi?id=13300 --
[Issue 19057] 2.079 changelog variadic template and default arguments
https://issues.dlang.org/show_bug.cgi?id=19057 --- Comment #3 from Steven Schveighoffer --- So the use case for the new style is pretty well discussed and documented (and makes a lot of sense). The use cases for the old style are not discussed really. Looks like the only times default parameters were used is when the number of parameters was less than the default (then the variadic template was inferred as an empty list). I can potentially see the benefit there. Can that functionality be duplicated with the new mechanism? That is the main question we have to answer. If it can, then the deprecation period can be relatively short, with a nice message on how to rewrite. If not, then I don't know what the right path is. Clearly it's a hugely useful thing to be able to specify default parameters for line and file without doing it in the template list. Johan, do you have some sample code to show a good use case for the old way? --
Re: #dbugfix 13300
On Thursday, 5 July 2018 at 13:41:23 UTC, Andrea Fontana wrote: My vote for this one :) For lazy people https://issues.dlang.org/show_bug.cgi?id=13300
Re: Why do core.atomic functions require shared
On Thursday, July 05, 2018 11:31:15 FeepingCreature via Digitalmars-d wrote: > On Wednesday, 4 July 2018 at 10:47:12 UTC, Jonathan M Davis wrote: > > At this point, to operate on anything that's shared, either > > means using atomics or protecting the data with a mutex (be > > that with a synchronized block / function or a mutex object) > > and temporarily casting away shared while operating on the > > data. Afterwards, the mutex is released, and at that point, > > there should just be only shared references to the data. About > > the only time that operating directly on a shared object then > > makes sense is when it manages the atomics or mutex and > > associated cast internally. > > > > ... > > It's a very difficult problem. Synchronized classes were > > proposed in an attempt to solve it, but even if they were fully > > implemented, they'd only help partially, because they can only > > strip off the outermost layer of shared. In order for the > > compiler to cast away shared for you, it has to be able to > > guarantee that there are no unprotected references to that > > data, and because D doesn't have any kind of ownership system > > in the language, we don't have a clean way to do it. > > Once we have DIP1000, can accessing shared class members in a > synchronized class (optionally? implicitly?) result in scoped > rvalues? I'm not quite sure what you're asking exactly, but if you're wondering if scope can help indicate that a reference hasn't escaped from a synchronized class, then I don't think so. e.g. something like mySynchObj.foo().func(); or scope foo = mySynchObj.foo(); foo.bar(); would already be a problem, even though scope prevents the reference from being kept around, because another thread could come in and access foo or what it refers to at the same time. The mutex would have been released as soon as the member function returned. Maybe some changes could be made to how synchronized works so that the mutex would be left locked until the expression terminated, and then if all you're allowed to do is call a member function on the scope reference that's returned, then maybe it could work - but even then, you have the problem of a reference escaping via that member function call, and even a scoped reference is unacceptable, because then it could escape the mutex's lock, even if it didn't last long - and that's assuming that the mutex was made to stay locked for the duration of the expression rather than for the duration of the member function call. scope is designed around making sure that the lifetime of a reference, ref, pointer, or dynamic array is not longer than the lifetime of the object it refers to and not around the lifetime of a function call or mutex lock. It has to be guaranteed that any time the data is accessed, the mutex protecting it is locked. If it could be guaranteed that the data never escapes - even temporarily - from any member function call (i.e. they never return any references to any member variables or anything they refer to, and all of the member functions are pure), and it's guaranteed that the data in the member variables was all created inside the class (so any data that was passed to a member function - including the constructor - and then assigned to or passed to a member variable is a value type or it was a reference type that was duped - though we don't really have a way to guarantee at this point that data was duped), then I think that it would be possible to strip away the other layers of shared and call free functions inside member functions. But that would be a pretty big restriction as well as probably a pain to code correctly in the compiler. I don't know. Some improvements may be possible there, but it's very tricky. You have to be able to guarantee that no data that ever has shared implicitly removed from it is ever accessed while the mutex isn't locked, and the more you try to allow, the harder it is to plug the holes. Much as I agree that the casting sucks, I'm increasingly of the opinion that the extra complications required to implicitly remove shared from even part of an object quickly become too much to be worth it. Ultimately, I think that the only real downside to the casting is that it requires that the programmer get it right, whereas any time we can automate it, the compiler guarantees it. Having the compiler guarantee it is very desirable, but the extra restrictions required to make that guarantee can't be too restrictive, or it quickly becomes saner to just do the cast even if it makes you verify it yourself. - Jonathan M Davis
Re: Why do core.atomic functions require shared
On Wednesday, 4 July 2018 at 10:47:12 UTC, Jonathan M Davis wrote: [cut] - Jonathan M Davis I think I've just read a similar explanation about shared written by you some months ago. It seems that a lot of users doesn't understand what shared really is. Probably a pinned article should be posted on dlang homepage :) Andrea
[Issue 19064] [REG2.081] Vibe.d's InterfaceProxy no longer works
https://issues.dlang.org/show_bug.cgi?id=19064 RazvanN changed: What|Removed |Added CC||razvan.nitu1...@gmail.com --- Comment #3 from RazvanN --- PR: https://github.com/dlang/dmd/pull/8456 --
Re: dmd optimizer now converted to D!
On Thursday, 5 July 2018 at 12:50:18 UTC, Ivan Kazmenko wrote: Is there any better way? To prevent introducing bugs when micro-optimizing, I'd like the loop body to remain as unchanged as it can be. foreach(j, ref piece; cast(int[4][]) a) { auto pieceI = j * 4; static foreach(i; 0 .. piece.length) piece[i] = pieceI + i; } Can probably be made even better by designing some template helper.
Re: Why is it hard to make Qt bindings?
On Thursday, July 05, 2018 11:42:39 drug via Digitalmars-d-learn wrote: > There were several attempts to make Qt binding for dlang, but either > they has failed or has been stalled. It would be nice to collect that > experience. Considering 2.081 supports C++ special member (not all but > majority) isn't it time to make another attempt or the problem is more > complex? > Could you publish your experience in making Qt bindings here? Qt takes advantage of just about every advanced C++98 feature under the sun, and on top of that, it uses its own preprocessor for stuff like signals and slots so that you can do signal: and slot: in your code and have the functions that follow treated as signals and slots, and various bits of code get generated to go with all of that. It also does some very specific stuff with how it handles memory which can be a bit entertaining to make work well with D code. And of course, Qt makes heavy use of multiple inheritance, and while that can be dealt with on some level with interfaces, all of the various issues combined make it particularly difficult if you want to be able to do the equivalent of new MyQWidget and have it work properly. There are ways to work around most of it in D, but it's hard - especially if you don't want to be generating C++ code as part of your D project that uses Qt. Binding to C++ is far harder than C, and with Qt being as complicated as it is with what it's done, it makes it very hard to make D bindings for - not impossible, but very hard. If someone were _trying_ to make a C++ project that was hard to bind to, they could probably make it much worse (e.g. much heavier use of templates), but Qt did a pretty amazing job of making it hard even without that being their goal. I actually started on creating bindings (more wrappers for it really) a while back, but I have a long way to go on it and have gotten sidetracked - e.g. one of the main reasons that I wrote dxml was because I'm using XML files to configure code generation for the bindings, and I didn't want to continue to use std.experimental.xml for that (not only is it unsupported, but I had to work around various issues while using it, so it clearly was unacceptable long term). - Jonathan M Davis
Re: Cleanup class after method?
On Thursday, July 05, 2018 05:47:20 Flaze07 via Digitalmars-d-learn wrote: > On Wednesday, 4 July 2018 at 16:02:25 UTC, Jonathan M Davis wrote: > > -dip1000 fully implements scope so that it verifies that no > > reference escapes, but it's not ready yet, let alone the > > default behavior. > > > > - Jonathan M Davis > > I read the proposal about -dip1000 ( not all, some ) and there is > also a scoped! template in std.typecons, so...is it better to use > the scope keyword, or scoped! template Long term, it will be better to use the scope keyword. Short term (i.e. until -dip1000 is the normal behavior or at least ready to use), it may be better to use scoped, since I think that the wrapper protects you at least somewhat - though the main reason that it was originally introduced is that scope on classes was going to deprecated, because we didn't want something that unsafe to be a keyword, but DIP 1000 is changing that. - Jonathan M Davis
Re: dmd optimizer now converted to D!
On Thursday, 5 July 2018 at 12:50:18 UTC, Ivan Kazmenko wrote: With D, I used mixins, and they were cumbersome. Now that we have static foreach, it's just this: for (int i = 0; i < 4 * n; i += 4) static foreach (k; 0..4) a[i + k] += i + k; This looks very nice to me, but still not ideal: a static-foreach argument cannot encapsulate a runtime variable, so we have to repeat "i + k" twice. This can get cumbersome for a more complex example. Is there any better way? To prevent introducing bugs when micro-optimizing, I'd like the loop body to remain as unchanged as it can be. Ivan Kazmenko. FYI: you can introduce scopes with static foreach to declare new variables: for (int i = 0; i < 4 * n; i += 4) { static foreach (k; 0..4) {{ auto idx = i + k a[idx] += idx; }} } However, LDC is pretty good at loop unrolling out of the box: https://godbolt.org/g/4nSWzQ (even though gdc is written there, it's "ldc" - known typo: https://github.com/mattgodbolt/compiler-explorer/pull/988)
Re: I have a plan.. I really DO
On Wednesday, 4 July 2018 at 19:29:55 UTC, Ecstatic Coder wrote: First, to be clear, I mainly use D as a scripting language for file processing, and for this use case, having a GC is a blessing. This is a non issue and a GC doesn't matter at all in this case. You could allocate all you wanted and never free and as long as there's enough memory to finish the script you couldn't tell the difference. Once a script or program is done the OS reclaims all memory. But memory leaks in software, running in some kind of main loop, become real performance bottlenecks eventually and a time sink to debug. You say that garbage collection is not a real problem for game development. No, what I'm saying is that I've hadn't had any issues with the GC so far and that I don't expect any. I'm also saying that I keep hearing this argument against using D but it was never backed up by anthing substantial so it sounds like an excuse by folks who never really considered D in the first place. Like, what does it matter if a collection cycle is triggered during a loading screen ? Performance aware C++ folks do have to do resource management at some point, too, and that's not free either and is usually done while the loading screen is displayed. For instance, have you read Unity's own official recommandations on how to overcome this problem ? No, I haven't. It probably boils down to pre-allocation, object pools, reusing objects, don't allocate in a loop, caching data, be mindful of what you do and when and how, etc, etc. Which would be good advice for game development in general and I'd do exactly that in C/C++, or any non-GC'd language, too. And about developing video games in C++, actually most studios use orthodox C++. This means no exceptions, no RTTI, few virtual methods, fast lightweight smart pointers and collections, etc. They could get that with -betterC which also does not use a GC. And about the scripting language, it's not my fault if some game engine developers don't care for the performance or GC issues when adding a scripting language to their game engine. Never said it was your fault, just pointed out the fact that it's a very common occurance. So, as I said, those who use C++ or Rust because D's GC is a problem for them, won't probably use D in its current state. Or any other language tagged GC for that matter, except maybe LUA. Nobody and nothing forces anyone to use the GC or features which use it. Just go ahead and manage your memory manually. They will not be using features like dynamic arrays, the standard library, and such but that's not a loss since they'd roll their own, more performant implementations, anyways. But I'm convinced that they wouldn't consider D - even if there was a GC-free Phobos. They would find the next excuse. Those who are willing find solutions, those who are not find excuses.
#dbugfix 13300
My vote for this one :)
Re: Why is it hard to make Qt bindings?
On Thursday, 5 July 2018 at 12:52:49 UTC, Steven Schveighoffer wrote: I remember there being a project for qt for D a long time ago. I think this is it: http://www.dsource.org/projects/qtd You may find some way to resurrect this. And QtE5 is still active. He announced support for QML not too long ago, I think. https://github.com/MGWL/QtE5
[Issue 19057] 2.079 changelog variadic template and default arguments
https://issues.dlang.org/show_bug.cgi?id=19057 Mike Franklin changed: What|Removed |Added CC||slavo5...@yahoo.com --- Comment #2 from Mike Franklin --- It appears the PR that implemented this was https://github.com/dlang/dmd/pull/7831 The changelog was then amended in https://github.com/dlang/dmd/pull/7875 A spec change was also made in https://github.com/dlang/dlang.org/pull/2169 --
Re: Safe to cast to immutable and return?
On Thursday, 5 July 2018 at 12:15:35 UTC, vit wrote: Try pure functions: class A {} A getA()pure @safe //pure whitout mutable parameters guarantees that function doesn't leak data. { A a; // .. do stuff with a // not leaking a to any functions // is this safe return a; } A getA2(A x)pure @safe //pure with mutable param { A a; // .. do stuff with a // not leaking a to any functions // is this safe return a; } void test()@safe{ immutable(A) a1 = getA();//ok immutable(A) a2 = getA2(null); //ok immutable(A) a3 = getA2(new A); //ok immutable(A) a4 = getA2(a3);//error in theory can leak } Very nice! I assume the @safe is not a must? Good read: https://dlang.org/spec/function.html#pure-functions
[Issue 19057] 2.079 changelog variadic template and default arguments
https://issues.dlang.org/show_bug.cgi?id=19057 Steven Schveighoffer changed: What|Removed |Added CC||schvei...@yahoo.com --- Comment #1 from Steven Schveighoffer --- IMO, this should either be reverted or go through a deprecation cycle. I'm not seeing what the pros/cons are of each mechanism. Is there a discussion somewhere? --
[Issue 19064] [REG2.081] Vibe.d's InterfaceProxy no longer works
https://issues.dlang.org/show_bug.cgi?id=19064 --- Comment #2 from Seb --- See also: https://github.com/vibe-d/vibe.d/issues/2181 --
[Issue 19064] [REG2.081] Vibe.d's InterfaceProxy no longer works
https://issues.dlang.org/show_bug.cgi?id=19064 --- Comment #1 from Seb --- Managed to find the root cause of the regression: cat << EOF > minimal.d enum IOMode { all} struct blocking {} interface InputStream { @safe: @property bool empty(); @property ulong leastSize(); @property bool dataAvailableForRead(); const(ubyte)[] peek(); size_t read(scope ubyte[] dst, IOMode mode); final void read(scope ubyte[] dst) { auto n = read(dst, IOMode.all); assert(n == dst.length); } } interface OutputStream { @safe: size_t write(in ubyte[] bytes, IOMode mode); final void write(in ubyte[] bytes) { auto n = write(bytes, IOMode.all); assert(n == bytes.length); } final void write(in char[] bytes) { write(cast(const(ubyte)[])bytes); } void flush(); void finalize(); } interface Stream : InputStream, OutputStream { } interface ConnectionStream : Stream { @safe: @property bool connected() const; void close(); } static foreach (member; __traits(allMembers, ConnectionStream)) { pragma(msg, __traits(getOverloads, ConnectionStream, member)); } EOF with 2.080.1: --- tuple(connected) tuple(close) tuple(empty) tuple(leastSize) tuple(dataAvailableForRead) tuple(peek) tuple(read, read) tuple(write, write, write) tuple(flush) tuple(finalize) --- with 2.081.0: --- tuple() tuple() tuple(empty) tuple(leastSize) tuple(dataAvailableForRead) tuple(peek) tuple(read, read) tuple(write, write, write) tuple(flush) tuple(finalize) --- That's why the proxy-wrapping doesn't work. --
Re: Why do core.atomic functions require shared
On Thursday, 5 July 2018 at 11:31:15 UTC, FeepingCreature wrote: On Wednesday, 4 July 2018 at 10:47:12 UTC, Jonathan M Davis wrote: [...] Once we have DIP1000, can accessing shared class members in a synchronized class (optionally? implicitly?) result in scoped rvalues? We already have DIP1000. I used it to avoid casting and bringing your own mutex here: https://github.com/atilaneves/fearless Atila
Re: dmd optimizer now converted to D!
On Wednesday, 4 July 2018 at 17:22:22 UTC, H. S. Teoh wrote: ... dmd *is* capable of things like strength reduction and code lifting, but as Walter himself has said, it does *not* implement loop unrolling. Ow! I always thought it did loop unrolling in some cases, I was just never lucky when I checked. And now you and Walter say its implementation started only recently. Good to know the actual state of things. Manual loop unrolling did help me a couple of times with C++ and D. - By the way, what's a relatively painless way to manually unroll a loop in D? As a simple example, consider: for (int i = 0; i < 4 * n; i++) a[i] += i; With C[++], I did simply like this: for (int j = 0; j < 4 * n; j += 4) { #define doit(i) a[i] += i doit(j + 0); doit(j + 1); doit(j + 2); doit(j + 3); } This looks long, but on the positive side, it does not actually alter the expression: however complex and obscure the "a[i] += i" would be in a real example, it can remain untouched. With D, I used mixins, and they were cumbersome. Now that we have static foreach, it's just this: for (int i = 0; i < 4 * n; i += 4) static foreach (k; 0..4) a[i + k] += i + k; This looks very nice to me, but still not ideal: a static-foreach argument cannot encapsulate a runtime variable, so we have to repeat "i + k" twice. This can get cumbersome for a more complex example. Is there any better way? To prevent introducing bugs when micro-optimizing, I'd like the loop body to remain as unchanged as it can be. Ivan Kazmenko.
Re: Why is it hard to make Qt bindings?
On 7/5/18 4:42 AM, drug wrote: There were several attempts to make Qt binding for dlang, but either they has failed or has been stalled. It would be nice to collect that experience. Considering 2.081 supports C++ special member (not all but majority) isn't it time to make another attempt or the problem is more complex? Could you publish your experience in making Qt bindings here? I'm not a Qt user, but doesn't Qt require a special pre-compiler, or even use the preprocessor in a way that is difficult to duplicate in D? I remember there being a project for qt for D a long time ago. I think this is it: http://www.dsource.org/projects/qtd You may find some way to resurrect this. -Steve
[Issue 19051] Undefined functions Set/GetWindowLongPtr in mingw libs
https://issues.dlang.org/show_bug.cgi?id=19051 --- Comment #5 from chrismohrf...@comcast.net --- Seems to have resolved my issue (originally found this when trying to build a vibe.d project), thanks! Out of curiosity, would there be plans to integrate the mingw-w64 libraries? --
Re: 'is(T==return)' How does is expression with return keyword as TypeSpecialization
On 7/5/18 6:32 AM, Timoses wrote: int fun(T)(T i) { static assert(is(typeof(return) == T)); //true This is the type of the return value for the function you are in. pragma(msg, is(T == return)); // false This is not a valid is expression, which is why it's false. IMO, I think this should be an error. Only is(T == struct), is(T == class), etc. works. static if (is(T ReturnType == return)) As you have surmised, if T is a function, function pointer, or delegate, then it evaluates to true, and ReturnType is set to the return type of that function. Note, it has nothing to do with the function you are in, unlike typeof(return). -Steve
[Issue 19064] New: [REG2.081] Vibe.d's InterfaceProxy no longer works
https://issues.dlang.org/show_bug.cgi?id=19064 Issue ID: 19064 Summary: [REG2.081] Vibe.d's InterfaceProxy no longer works Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: regression Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: greeen...@gmail.com Created attachment 1709 --> https://issues.dlang.org/attachment.cgi?id=1709=edit A half-reduced version of Vibe.d Introduced by https://github.com/dlang/dmd/pull/7959 I'm still trying to reduce vibe-core, it's a bit difficult because DustMite is pretty greedy and just removing the mixin methods would also lead to the attribute not being found. --
Re: 'is(T==return)' How does is expression with return keyword as TypeSpecialization
On Thursday, 5 July 2018 at 10:32:01 UTC, Timoses wrote: int fun(T)(T i) { static assert(is(typeof(return) == T)); //true pragma(msg, is(T == return)); // false static if (is(T ReturnType == return)) pragma(msg, ReturnType); // does not enter return i; } unittest { fun(3); } What's the purpose of 'is(T == return)' if not the above? Found it: http://ddili.org/ders/d.en/is_expr.html Section "is (T identifier == Specifier)" int fun() { return 1337; } template Temp(T) { //pragma(msg, typeof(T)); // is T a function, if so assign its return type to 'retType' static if (is(T retType == return)) { retType Temp(T func) { return func(); } } } void main() { int i = Temp!(typeof())(); assert(i == 1337); } So, 'return' checks if T is a callable and if so assigns its return type to 'identifier'.
Re: Safe to cast to immutable and return?
On 7/5/18 7:15 AM, Timoses wrote: Is this safe? class A {} immutable(A) getA() { A a; // .. do stuff with a // not leaking a to any functions // is this safe return cast(immutable A)a; } As in @safe? no. But it's safe in the fact that you aren't escaping any mutable references as immutable. However, casting is dangerous. It disables any checks about const safety that the compiler may do. If something happens to A where it all of a sudden gains a mutable reference, and the reference is to global data or has other references: class A { int *x; } int globalx; immutable(A) getA() { A a = new A; a.x = return cast(immutable A)a; } Now it's not safe, and the compiler won't tell you. What if A is replaced with A[] or A[int]? A[] should work very similarly to A A[int] I think will work, I don't think it stores any type info inside the AA. The rule is that if you *know* there are no other references to a mutable piece of data, it's OK to cast to immutable. If it's not safe, what would be the proper way to return an immutable instance from a function which needs to make adjustments to the instance before returning it as immutable? See vit's response, he covers it pretty well. -Steve
Re: 'is(T==return)' How does is expression with return keyword as TypeSpecialization
On Thursday, 5 July 2018 at 11:37:16 UTC, Timoses wrote: I think it refers to this section: https://dlang.org/spec/expression.html#is_expression should mention that I mean the 6th paragraph.
Re: Safe to cast to immutable and return?
On Thursday, 5 July 2018 at 11:15:03 UTC, Timoses wrote: Is this safe? class A {} immutable(A) getA() { A a; // .. do stuff with a // not leaking a to any functions // is this safe return cast(immutable A)a; } What if A is replaced with A[] or A[int]? If it's not safe, what would be the proper way to return an immutable instance from a function which needs to make adjustments to the instance before returning it as immutable? Try pure functions: class A {} A getA()pure @safe //pure whitout mutable parameters guarantees that function doesn't leak data. { A a; // .. do stuff with a // not leaking a to any functions // is this safe return a; } A getA2(A x)pure @safe //pure with mutable param { A a; // .. do stuff with a // not leaking a to any functions // is this safe return a; } void test()@safe{ immutable(A) a1 = getA();//ok immutable(A) a2 = getA2(null); //ok immutable(A) a3 = getA2(new A); //ok immutable(A) a4 = getA2(a3);//error in theory can leak }
Re: ranges.chunks and map! does not work
On Thursday, 5 July 2018 at 09:47:32 UTC, Andre Pany wrote: Hi, the purpose of this code is to generate CSV based on 3 double arrays. I wonder why map cannot directly use the result of the chunks function. import std.experimental.all; void main() { double[] timestamps = [1.1]; double[] temperatures = [2.2]; double[] pressures = [3.3]; string content = roundRobin(timestamps, temperatures, pressures) .chunks(3) //.map!(c => c.array) .map!(c => "%.10g,%.10g,%.10g".format(c[0],c[1],c[2])) .join("\n"); writeln(content); } The exact error message is (this line is 3 times repeated): app1.d(12): Error: no [] operator overload for type Take!(Result) app1.d(12): Error: no [] operator overload for type Take!(Result) app1.d(12): Error: no [] operator overload for type Take!(Result) C:\SAPDevelop\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\iteration.d(499): instantiated from here: MapResult!(__lambda1, Chunks!(Result)) app1.d(12):instantiated from here: map!(Chunks!(Result)) Is it correct that I need to call ".map!(c => c.array)"? Kind regards André roundRobin doesn't return RandomAccessRange => chunks doesn't return range of RandomAccessRange => Error: no [] operator overload try this: string content = roundRobin(timestamps, temperatures, pressures) .array .chunks(3) //.map!(c => c.array) .map!(c => "%.10g,%.10g,%.10g".format(c[0],c[1],c[2])) .join("\n");
[Issue 19059] Invalid integer literal 08 and 09 allowed
https://issues.dlang.org/show_bug.cgi?id=19059 --- Comment #5 from Hiroki Noda --- I am concerned about (2) and (3), is this behavior confusing with the use of std.conv. octal? --- assert(010 == 10); // Error: octal literals 010 are no longer supported, use std.conv.octal!10 instead assert(019 == 19); // Error: radix 8 digit expected, not 9 // Error: octal literals 021 are no longer supported, use std.conv.octal!21 instead --
Re: 'is(T==return)' How does is expression with return keyword as TypeSpecialization
On Thursday, 5 July 2018 at 11:37:16 UTC, Timoses wrote: I think it refers to this section: https://dlang.org/spec/expression.html#is_expression I don't remember where I read this usage (think it was in a book), but I noted it down and now I wonder how it can be used. I saw some usage cases, which are like "opposites" to auto fun() declarations: So either you can declare ´´´ auto fun() { int retVal; ... return retVal; } ´´´ or ´´´ int fun() { typeof(return) retVal; ... return retVal; } ´´´
Re: 'is(T==return)' How does is expression with return keyword as TypeSpecialization
On Thursday, 5 July 2018 at 11:21:41 UTC, Alex wrote: On Thursday, 5 July 2018 at 10:32:01 UTC, Timoses wrote: int fun(T)(T i) { static assert(is(typeof(return) == T)); //true pragma(msg, is(T == return)); // false static if (is(T ReturnType == return)) pragma(msg, ReturnType); // does not enter return i; } unittest { fun(3); } What's the purpose of 'is(T == return)' if not the above? I always thought that "return" is a keyword. https://dlang.org/spec/lex.html#keywords And the fact, that you can ask the keyword about its type is just a nice feature... ;) I think it refers to this section: https://dlang.org/spec/expression.html#is_expression I don't remember where I read this usage (think it was in a book), but I noted it down and now I wonder how it can be used.
Re: Why do core.atomic functions require shared
On Wednesday, 4 July 2018 at 10:47:12 UTC, Jonathan M Davis wrote: At this point, to operate on anything that's shared, either means using atomics or protecting the data with a mutex (be that with a synchronized block / function or a mutex object) and temporarily casting away shared while operating on the data. Afterwards, the mutex is released, and at that point, there should just be only shared references to the data. About the only time that operating directly on a shared object then makes sense is when it manages the atomics or mutex and associated cast internally. ... It's a very difficult problem. Synchronized classes were proposed in an attempt to solve it, but even if they were fully implemented, they'd only help partially, because they can only strip off the outermost layer of shared. In order for the compiler to cast away shared for you, it has to be able to guarantee that there are no unprotected references to that data, and because D doesn't have any kind of ownership system in the language, we don't have a clean way to do it. Once we have DIP1000, can accessing shared class members in a synchronized class (optionally? implicitly?) result in scoped rvalues?
[Issue 16479] Missing substitution while mangling C++ template parameter for functions
https://issues.dlang.org/show_bug.cgi?id=16479 Mathias LANG changed: What|Removed |Added Keywords||pull --- Comment #5 from Mathias LANG --- PR: https://github.com/dlang/dmd/pull/8455 --
Re: 'is(T==return)' How does is expression with return keyword as TypeSpecialization
On Thursday, 5 July 2018 at 10:32:01 UTC, Timoses wrote: int fun(T)(T i) { static assert(is(typeof(return) == T)); //true pragma(msg, is(T == return)); // false static if (is(T ReturnType == return)) pragma(msg, ReturnType); // does not enter return i; } unittest { fun(3); } What's the purpose of 'is(T == return)' if not the above? I always thought that "return" is a keyword. https://dlang.org/spec/lex.html#keywords And the fact, that you can ask the keyword about its type is just a nice feature... ;)
Re: ranges.chunks and map! does not work
On Thursday, 5 July 2018 at 09:47:32 UTC, Andre Pany wrote: Is it correct that I need to call ".map!(c => c.array)"? Kind regards André Well, no. It depends on how you define the formatting string. This would also work: ´´´ import std.experimental.all; void main() { double[] timestamps = [1.1]; double[] temperatures = [2.2]; double[] pressures = [3.3]; string content = roundRobin(timestamps, temperatures, pressures) .chunks(3) //.map!(c => c.array) .map!(c => "%(%g,%)".format(c)) .join("\n"); writeln(content); } ´´´
Safe to cast to immutable and return?
Is this safe? class A {} immutable(A) getA() { A a; // .. do stuff with a // not leaking a to any functions // is this safe return cast(immutable A)a; } What if A is replaced with A[] or A[int]? If it's not safe, what would be the proper way to return an immutable instance from a function which needs to make adjustments to the instance before returning it as immutable?
Alternative destructors, do/should we have them?
D does not have default constructors for structs, but I have thought that this might get around the problem: struct MallocedPtr() { void* location; ~this() { import core.stdc.stdlib; assert(location != null); free(location.ptr); } } Unlike a destructor which has a runtime check whether it's initialized, this has no performance cost over a C++-style default-initialized struct. I think "hand grenade RAII" is a perfect name for this idiom, because like a hand grenade, this struct asserts it is set somewhere else after initialization before it's destructor runs. But there is a problem. If you use std.algorithm.move to give a hand grenade to a function, it initializes another hand grenade for the calling function. I didn't come up with any way to defuse the initialized grenade without runtime cost. Granted, a runtime check at destructor is unlikely to be a major performance hit for any normal application, but D is a systems language, right? Do you have any ideas to get around this? If not, should we in your opinion have an ability to define an alternative destructor which runs only when explicitly requested?
Re: LDC 1.11.0 beta
On Thursday, 5 July 2018 at 09:40:46 UTC, kinke wrote: I failed to see a benefit from being able to use classes with static members only (abuse as namespace?) Yeah, pretty much, but also static inheritance. You can see the pattern where I use it at https://github.com/JinShil/stm32f42_discovery_demo/blob/c324bbf861cf258a819478481521528fca88dcb3/source/stm32f42/pwr.d#L24 It's for an ARM Cortex-M microcontroller. The structure, layout, and memory locations of all memory-mapped IO registers (there are 100s of them) are all known at compile-time, so there's no need for instances of anything. The static inheritance allows me to reuse implementation code and also model the hierarchy according to my mental model. After all that's one of the pillars of D, modeling power. Also, modeling them as static classes allows me to avoid the memory layout mess in the linker script (Yuck!), as all the memory addresses accompany the code itself. This also makes it much, much easier to cross-reference the code to the microcontroller's datasheet. D's the only language I know of that can do this; it's not a strength, not a weakness. Mike
Re: LDC 1.11.0 beta
On Thursday, 5 July 2018 at 10:57:17 UTC, Mike Franklin wrote: I failed to see a benefit from being able to use classes with static members only (abuse as namespace?) Yeah, pretty much, but also static inheritance. You can see the pattern where I use it at https://github.com/JinShil/stm32f42_discovery_demo/blob/c324bbf861cf258a819478481521528fca88dcb3/source/stm32f42/pwr.d#L24 Also, it allows me to dot-walk the hierarchy in my editor with code-completion and documentation comments. I describe this and illustrate with images in the readme. https://github.com/JinShil/stm32f42_discovery_demo Mike
[Issue 19059] Invalid integer literal 08 and 09 allowed
https://issues.dlang.org/show_bug.cgi?id=19059 Seb changed: What|Removed |Added CC||greeen...@gmail.com --
[Issue 19051] Undefined functions Set/GetWindowLongPtr in mingw libs
https://issues.dlang.org/show_bug.cgi?id=19051 Seb changed: What|Removed |Added CC||greeen...@gmail.com --
Re: Using C++ with D / returning a templated type from C++
On 2018-07-05 08:14:18 +, Seb said: On Thursday, 5 July 2018 at 06:35:01 UTC, Robert M. Münch wrote: So, the only difference left is the C++ static and the additional __ptr64 (whatever this is) on the D side. Any further ideas? Could you post your current C++ and D files? It's a big code base... that's a bit the problem why I try to strip things down. Maybe this is better: https://pastebin.com/dpQdAPye This is the demangled form from the C++ link library: public: static class b2d::Array __cdecl b2d::ImageCodec::builtinCodecs(void) With the D compiler I was able to generates these manglings: public: class b2d::Array * __ptr64 __cdecl b2d::ImageCodec::builtinCodecs(void) __ptr64 public: class b2d::Array __cdecl b2d::ImageCodec::builtinCodecs(void) __ptr64 -- Robert M. Münch http://www.saphirion.com smarter | better | faster
'is(T==return)' How does is expression with return keyword as TypeSpecialization
int fun(T)(T i) { static assert(is(typeof(return) == T)); //true pragma(msg, is(T == return)); // false static if (is(T ReturnType == return)) pragma(msg, ReturnType); // does not enter return i; } unittest { fun(3); } What's the purpose of 'is(T == return)' if not the above?
Re: DIP 1014--Hooking D's struct move semantics--Final Review
On Wednesday, 27 June 2018 at 07:13:14 UTC, Mike Parker wrote: DIP 1014, "Hooking D's struct move semantics", is now ready for final review. Structs are a low level feature that should be able to be used in any way programmer sees fit. This is just what is wrong with C# structs: In principle they're the same as D structs but disallow many things for no obvious reason, thus limiting their usability. See my question and it's answers at Stack overflow to see what I mean: https://stackoverflow.com/questions/51098690/assigning-value-to-member-of-nullable-struct-in-c-sharp This is a feature that is likely to be useful for low level programming, but is zero cost for those who don't need it. The DIP looks well written. I'm in favour of it.
Re: ranges.chunks and map! does not work
On Thursday, 5 July 2018 at 09:47:32 UTC, Andre Pany wrote: Hi, the purpose of this code is to generate CSV based on 3 double arrays. I wonder why map cannot directly use the result of the chunks function. import std.experimental.all; void main() { double[] timestamps = [1.1]; double[] temperatures = [2.2]; double[] pressures = [3.3]; string content = roundRobin(timestamps, temperatures, pressures) .chunks(3) //.map!(c => c.array) .map!(c => "%.10g,%.10g,%.10g".format(c[0],c[1],c[2])) .join("\n"); writeln(content); } I always find this kind of confusing as well. What kind of ranges are returned by functions handling ranges and returning another range? It is clear what type of range can be passed by looking at the constraint for chunks[1]: Chunks!Source chunks(Source)(Source source, size_t chunkSize) if (isInputRange!Source); It would be awesome to have something like and output constraint: out(Output; isForwardRange!Output && isInputRange!(ElementType!Output)) or something similar to know what the function will return.. In your case it seems like the typeof(c.front) is not a random access range: auto c = roundRobin(timestamps, temperatures, pressures) .chunks(3); pragma(msg, isRandomAccessRange!(typeof(c.front))); // prints false So you could do auto content = roundRobin(timestamps, temperatures, pressures) .evenChunks(timestamps.length) .map!(c => c.map!(a => format("%.10g", a)) .join(",") ) .join("\n"); although there might be more elegant solutions. [1]: https://dlang.org/phobos/std_range.html#chunks
Re: Parenthesis around if/for/while condition is not necessary
On Thursday, 5 July 2018 at 09:45:44 UTC, Basile B. wrote: On Wednesday, 4 July 2018 at 14:37:49 UTC, Timon Gehr wrote: On 24.06.2018 13:27, Basile B. wrote: FYI this works fine, as expected it's just some small parser changes. I didn't touch to for and foreach for now. I think that SwitchStatement is a candidate too. https://github.com/BBasile/dmd/commit/5455a65c8fdee5a6d198782d1f168906b59e6d3d if (a+b)*c == d { ... } right, maybe logic to apply here is : if the expression parses and no closing paren is found then it's not nececessary. Actually with the change the example doesn't parse and without it didn't either. The program meaning is not altered so it's fine.
Re: Parenthesis around if/for/while condition is not necessary
On Wednesday, 4 July 2018 at 14:37:49 UTC, Timon Gehr wrote: On 24.06.2018 13:27, Basile B. wrote: FYI this works fine, as expected it's just some small parser changes. I didn't touch to for and foreach for now. I think that SwitchStatement is a candidate too. https://github.com/BBasile/dmd/commit/5455a65c8fdee5a6d198782d1f168906b59e6d3d if (a+b)*c == d { ... } right, maybe logic to apply here is : if the expression parses and no closing paren is found then it's not nececessary.
ranges.chunks and map! does not work
Hi, the purpose of this code is to generate CSV based on 3 double arrays. I wonder why map cannot directly use the result of the chunks function. import std.experimental.all; void main() { double[] timestamps = [1.1]; double[] temperatures = [2.2]; double[] pressures = [3.3]; string content = roundRobin(timestamps, temperatures, pressures) .chunks(3) //.map!(c => c.array) .map!(c => "%.10g,%.10g,%.10g".format(c[0],c[1],c[2])) .join("\n"); writeln(content); } The exact error message is (this line is 3 times repeated): app1.d(12): Error: no [] operator overload for type Take!(Result) app1.d(12): Error: no [] operator overload for type Take!(Result) app1.d(12): Error: no [] operator overload for type Take!(Result) C:\SAPDevelop\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\iteration.d(499): instantiated from here: MapResult!(__lambda1, Chunks!(Result)) app1.d(12):instantiated from here: map!(Chunks!(Result)) Is it correct that I need to call ".map!(c => c.array)"? Kind regards André
Re: LDC 1.11.0 beta
On Thursday, 5 July 2018 at 08:55:00 UTC, Mike Franklin wrote: I notice the minimal2.d test from the DMD test suite is disabled: https://github.com/ldc-developers/dmd-testsuite/blob/977ef0696f7941357385925c07617544c3527f4c/runnable/minimal2.d#L5 How permanent/temporary is that? Is there something blocking the implementation? I failed to see a benefit from being able to use classes with static members only (abuse as namespace?) with a minimal druntime, hence no interest from my side to implement it for now.
Re: how to import file from another path in dub ?
On Thursday, 5 July 2018 at 08:55:13 UTC, Timoses wrote: Depending on your use case I see these options: - If you have a library that defines the symbols that you are using in the imported files you could use the dub `libs` setting - Otherwise, if you're just using the other folder to separate code you can redefine dub's `sourcePaths`. I believe it overwrites the previous, so you have to include your 'source' folder again: "sourcePaths": ["source", ""] When using sourcePaths, dub actually passes all files within all mentioned paths to dmd to compile. Hope I got it right : D. I see...so that means, I only need importPaths if I have compiled it to libs got it
Re: how to import file from another path in dub ?
On Thursday, 5 July 2018 at 05:38:29 UTC, Flaze07 wrote: I have a dub project, and I put the importPath to the path of the file I want to import and the source file to the source folder, and it appears that I have succeeded at importing the module, but there's one problem, it appears like I need to define some sort of thing, because the error says " Error 42: Symbol Undefined __D9animation12__ModuleInfoZ" ( I am using coedit ), do I need to compile the file into .lib ? You can follow what happens when you do `dub -v`. When using the `importPaths` the compiler will import the path during compilation, but not compile the files in importPath and put it in the object file. The call is something like this: dmd -I Afterwards the linker tries to find the function defined in import path, which however is not found as it was not compiled. My guess is that this could be useful when using something like interface files (in D .di files, or in C/C++ header files) which only has declarations). Then you would have to pass the linker the library or object file which actually contains the compiled functions. Otherwise you get an error like the one you have. Depending on your use case I see these options: - If you have a library that defines the symbols that you are using in the imported files you could use the dub `libs` setting - Otherwise, if you're just using the other folder to separate code you can redefine dub's `sourcePaths`. I believe it overwrites the previous, so you have to include your 'source' folder again: "sourcePaths": ["source", ""] When using sourcePaths, dub actually passes all files within all mentioned paths to dmd to compile. Hope I got it right : D.