Re: Checking if CTFE is used?
On Tuesday, December 18, 2018 9:20:11 AM MST berni via Digitalmars-d-learn wrote: > On Tuesday, 18 December 2018 at 14:32:29 UTC, Adam D. Ruppe wrote: > > CTFE is used if and only if it MUST be used by context. That's > > a runtime function, so no ctfe. > > > > Do something like: > > > > int[4] generate() { > > > >int[4] tmp; > >foreach(i; 0..4) tmp[i] = i; > >return tmp; > > > > } > > > > > > static immutable int[4] clue = generate(); > > Great, that worked. :-) My reasoning was, that CTFE is somewhat > greedy, that is, everything that can be evaluated at compile time > will be evaluated at compile time... > > Many thanks for your replies. :-) It's pretty much the opposite. CTFE is only ever done when the compiler needs the result at compile-time, and it's never done as an optimization, if nothing else because the compiler has no way of knowing whether the function is even CTFE-able until it actually tries. Having it attempt CTFE in a bunch of places and then give up (to then call the function at runtime instead) would likely have a very negative impact on compilation time - especially since CTFE isn't very efficient at the moment (though whenever the newCTFE that Stefan is working on finally lands, that should improve significantly). As things stand, you have complete control over when CTFE occurs, and it's usually pretty easy to figure out if it's happening or not. As long as you understand which things must be known at compile-time, it's straightforward. - Jonathan M Davis
Re: Temporary @trusted scope
On Tuesday, December 18, 2018 5:42:12 AM MST rikki cattermole via Digitalmars-d-learn wrote: > On 19/12/2018 1:34 AM, Per Nordlöw wrote: > > On Tuesday, 18 December 2018 at 10:42:51 UTC, Jonathan M Davis wrote: > >> Unfortunately, D does not currently have a way to do that. Only > >> functions can be marked with @trusted. However, the typical approach > >> to this problem is to use a lambda, which is more or less > >> syntactically the same except that it has some extra parens. e.g. > >> > >> () @trusted { doUnsafe(); }(); > > > > Is there a performance hit when using this? > > Yes except for ldc with -O3. > But it is a function not a delegate so it should be all nicely > prefetched and ready to go. So I wouldn't worry about it too much. Really? I would have thought that that would be a pretty obvious optimization (especially if inlining is enabled). I suppose that it doesn't entirely surprise me if dmd does a poor job of it, but I would have expected ldc to do better than that. I would think that such an improvement would be pretty low-hanging fruit for adding to dmd's optimizer though. If not, it sounds like further justification for adding a feature for this rather than having to use a lambda. Aside from that though, the lambda trick is simple enough that it wouldn't surprise me if Walter and Andrei's response to such a DIP would be to just use the lambda trick. - Jonathan M Davis
Re: Tricky DMD bug, but I have no idea how to report
On Tue, Dec 18, 2018 at 10:29:07PM +, JN via Digitalmars-d-learn wrote: > On Monday, 17 December 2018 at 22:22:05 UTC, H. S. Teoh wrote: > > A less likely possibility might be an optimizer bug -- do you get > > different results if you add / remove '-O' (and/or '-inline') from > > your dmd command-line? If some combination of -O and -inline (or > > their removal thereof) "fixes" the problem, it could be an optimizer > > bug. But those are rare, and usually only show up when you use an > > obscure D feature combined with another obscure corner case, in a > > way that people haven't thought of. My bet is still on a pointer > > bug somewhere in your code. > > > > I played around with dmd commandline. It works with -O. Works with -O > -inline. As soon as I add -boundscheck=off it breaks. > > As I understand it, out of bounds access is UB. Which would fit my > problems because they look like UB. But if I run without > boundscheck=off, shouldn't I get a RangeError somewhere? In theory, yes. But I wonder if there's some corner case where some combination of -O or -inline may cause a bounds check to be elided, but still hit UB. Perhaps the optimizer skipped a bounds check even though it shouldn't have. What about compiling with -boundscheck=off but without -O -inline? Does that make a difference? Barring that, it might be one of those really evil pointer bugs where the problem has already happened far away from the site where the symptoms first appear, usually an undetected memory corruption that only shows up as invalid data long after the actual corruption happened. Very hard to trace. Are you sure you didn't accidentally do something like escape a pointer to a local variable, or a slice of a local static array that has since gone out of scope? Because that's what your symptoms most closely resemble. The last time I ran into this in my own D code, it was caused by D's really evil implicit conversion of static arrays to slices, where passing a local static array implicitly passes a slice instead, e.g.: SomeObject persistentStorage; auto someFunc(int[] data) { ... // stuff persistentStorage.insert(data); // retains reference to data ... } void buggyCode() { int[16] arr = ...; ... someFunc(arr); // <--- implicit conversion happens here ... // uh oh, arr is going out of scope, but // persistentStorage holds a reference to it } void main() { ... buggyCode(); // escaped reference to local variable ... // Crash when it tries to access the slice to // out-of-scope data: doSomething(persistentStorage); ... } Since no explicit slicing was done, there was no compiler error / warning of any sort, and it wasn't obvious from the code what had happened. By the time doSomething() was called, it was already long past the source of the problem in buggyCode(), and it was almost impossible to trace the problem back to its source. Theoretically, -dip25 and -dip1000 are supposed to prevent this sort of problem, but I don't know how fully-implemented they are, whether they would catch the specific instance in your code, or whether your code even compiles with these options. T -- There's light at the end of the tunnel. It's the oncoming train.
Re: Tricky DMD bug, but I have no idea how to report
On Monday, 17 December 2018 at 22:22:05 UTC, H. S. Teoh wrote: A less likely possibility might be an optimizer bug -- do you get different results if you add / remove '-O' (and/or '-inline') from your dmd command-line? If some combination of -O and -inline (or their removal thereof) "fixes" the problem, it could be an optimizer bug. But those are rare, and usually only show up when you use an obscure D feature combined with another obscure corner case, in a way that people haven't thought of. My bet is still on a pointer bug somewhere in your code. I played around with dmd commandline. It works with -O. Works with -O -inline. As soon as I add -boundscheck=off it breaks. As I understand it, out of bounds access is UB. Which would fit my problems because they look like UB. But if I run without boundscheck=off, shouldn't I get a RangeError somewhere?
Re: Bug in shifting
On 14/12/2018 02:56, Steven Schveighoffer wrote: > On 12/13/18 7:16 PM, Michelle Long wrote: >> byte x = 0xF; >> ulong y = x >> 60; > > Surely you meant x << 60? As x >> 60 is going to be 0, even with a ulong. It doesn't work as intuitive as you'd expect: void main() { int x = 256; int y = 36; int z = x >> y; writeln(z); } prints "16" without optimizations and "0" with optimizations. This happens for x86 architecture because the processor just uses the lower bits of the shift count. It is probably the reason why the language disallows shifting by more bits than the size of the operand.
Re: saving std.random RNG state
On 12/17/18 8:18 PM, Neia Neutuladh wrote: On Mon, 17 Dec 2018 22:20:54 +, harfel wrote: I am looking for a way to serialize/deserialize the state of the std.random.Random number generator, ideally using orange (https://github.com/jacob-carlborg/orange) or another serialization library. From looking at the module source code, I understand how to seed a random number generator with the state of another, but I do find a way to access the RNG's state, since it is hidden away in a private attribute. What is the recommended solution for this? Thanks in advance! The .tupleof field allows you to access private members. This behavior might eventually change, but probably not without a long deprecation period. If the struct stores everything by value: cast(ubyte[])&rng[0..1]; If you have typeinfo available, you can check if the thing has pointers with `(typeof(rng).flags & 1) == 0`. There's probably an equivalent in std.traits that works at compile time. std.traits.hasIndirections https://dlang.org/phobos/std_traits.html#hasIndirections In terms of storing the state, I find generally just using the same seed is best, but I can see use cases for storing the state for usage elsewhere. I don't see a better way than using a ubyte[] cast. -Steve
Re: Temporary @trusted scope
On Tuesday, 18 December 2018 at 13:52:29 UTC, Steven Schveighoffer wrote: On 12/18/18 6:29 AM, Simen Kjærås wrote: On Tuesday, 18 December 2018 at 10:14:50 UTC, Per Nordlöw wrote: What's the preferred way of creating a temporary @trusted scope without writing a separate function? Jonathan's idea might also be encapsulated in a function, just like assumeUnique in Phobos: import std.stdio; template unsafe(alias fn) { @trusted auto unsafe(T...)(T args) { return fn(args); } } @system void fun(int n) { writeln("foo!"); } @safe unittest { unsafe!({ fun(2); }); unsafe!fun(2); } Wow, I really like this. The only real problem is that one generally searches for @trusted when looking for unsafe code, but unsafe is pretty obvious too. Also, args should be auto ref. Only thing better I can think of (for the second example) is to define a prototype with the correct information, only with @trusted (and specify the mangle). But any decent compiler should get rid of any overhead there. -Steve I've been gathering assume related stuff like this in a lib under an "assume" template. You can generalize further with multiple attributes inside a non-eponymous thing and use them like: assume!fun.safe_(2); assume!fun.nogc_(2); I guess it's no very idiomatic D though, but I feel it reads better ... ok well maybe 🤷♂️: https://aliak00.github.io/bolts/bolts/assume/assume.html Easier to be more specific with searches for "assumeSafe" instead of just "assume!" though. Cheers, - Ali
Re: Temporary @trusted scope
On 12/18/18 10:53 AM, H. S. Teoh wrote: On Tue, Dec 18, 2018 at 08:52:29AM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote: On 12/18/18 6:29 AM, Simen Kjærås wrote: On Tuesday, 18 December 2018 at 10:14:50 UTC, Per Nordlöw wrote: What's the preferred way of creating a temporary @trusted scope without writing a separate function? Jonathan's idea might also be encapsulated in a function, just like assumeUnique in Phobos: import std.stdio; template unsafe(alias fn) { @trusted auto unsafe(T...)(T args) { return fn(args); } } @system void fun(int n) { writeln("foo!"); } @safe unittest { unsafe!({ fun(2); }); unsafe!fun(2); } Wow, I really like this. The only real problem is that one generally searches for @trusted when looking for unsafe code, but unsafe is pretty obvious too. Also, args should be auto ref. Only thing better I can think of (for the second example) is to define a prototype with the correct information, only with @trusted (and specify the mangle). But any decent compiler should get rid of any overhead there. [...] I'm not so sure I like this. @trusted bits of code really should have a safe API that cannot be called in a way that breaks @safe. Being able to essentially "cast away" @safe for arbitrary bits of code seems to me to be a rather scary, underhanded way of undermining @safe. You may not be realizing what the point of this is. Essentially, you replace your inline trusted lambda with this call. It's just nicer syntax/usage without all the extra parentheses. Other than that, every usage of it would need as much scrutiny as a trusted lambda. OTOH, if your function is very large and only isolated bits are non-@safe, then a construct like this one could help, by making the code less noisy, and ensuring that the other parts of the code still remain @safe. (Though IMO in such cases the function may be better refactored to encapsulate away the @trusted bits in functions with safe APIs, and keep the @safe code all in one place.) Yes, exactly. The point of trusted lambdas are so that only the parts you want to trust are actually trusted, the rest of the function is safe. It doesn't prevent you from having to locally verify that implementation leaks don't happen (for example, ()@trusted {free(ptr);}() can still leak dangling pointers out into the @safe portion), but it allows you to focus where your code is trusted. For more details, see this: https://dlang.org/blog/2016/09/28/how-to-write-trusted-code-in-d/ -Steve
Re: How to build dmd properly?
On Tuesday, 18 December 2018 at 16:19:33 UTC, unDEFER wrote: Yes, thank you for the hint. You are almost right. I did not ENABLE_DEBUG=1, but I also did not ENABLE_RELEASE=1 So it is the bug. I will report about it. https://issues.dlang.org/show_bug.cgi?id=19500
Re: Checking if CTFE is used?
On Tuesday, 18 December 2018 at 14:32:29 UTC, Adam D. Ruppe wrote: CTFE is used if and only if it MUST be used by context. That's a runtime function, so no ctfe. Do something like: int[4] generate() { int[4] tmp; foreach(i; 0..4) tmp[i] = i; return tmp; } static immutable int[4] clue = generate(); Great, that worked. :-) My reasoning was, that CTFE is somewhat greedy, that is, everything that can be evaluated at compile time will be evaluated at compile time... Many thanks for your replies. :-)
Re: How to build dmd properly?
On Tuesday, 18 December 2018 at 15:54:28 UTC, Seb wrote: On Tuesday, 18 December 2018 at 14:35:46 UTC, unDEFER wrote: What I could build wrong and how to build dmd properly? Maybe you built dmd.d with debug assertions? (ENABLE_DEBUG=1) You can build dmd with the `./build.d` script or `make -f posix.mak -j4` (assuming you are in `src). Anyway, the internal assertions should never fail, so this definitely deserves a bug report if that was the case. Yes, thank you for the hint. You are almost right. I did not ENABLE_DEBUG=1, but I also did not ENABLE_RELEASE=1 So it is the bug. I will report about it.
Re: How to build dmd properly?
On Tuesday, 18 December 2018 at 14:35:46 UTC, unDEFER wrote: What I could build wrong and how to build dmd properly? Maybe you built dmd.d with debug assertions? (ENABLE_DEBUG=1) You can build dmd with the `./build.d` script or `make -f posix.mak -j4` (assuming you are in `src). Anyway, the internal assertions should never fail, so this definitely deserves a bug report if that was the case.
Re: Temporary @trusted scope
On Tue, Dec 18, 2018 at 08:52:29AM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote: > On 12/18/18 6:29 AM, Simen Kjærås wrote: > > On Tuesday, 18 December 2018 at 10:14:50 UTC, Per Nordlöw wrote: > > > What's the preferred way of creating a temporary @trusted scope > > > without writing a separate function? > > > > Jonathan's idea might also be encapsulated in a function, just like > > assumeUnique in Phobos: > > > > import std.stdio; > > > > template unsafe(alias fn) { > > @trusted auto unsafe(T...)(T args) { > > return fn(args); > > } > > } > > > > @system void fun(int n) { > > writeln("foo!"); > > } > > > > @safe unittest { > > unsafe!({ > > fun(2); > > }); > > > > unsafe!fun(2); > > } > > Wow, I really like this. The only real problem is that one generally > searches for @trusted when looking for unsafe code, but unsafe is > pretty obvious too. Also, args should be auto ref. > > Only thing better I can think of (for the second example) is to define > a prototype with the correct information, only with @trusted (and > specify the mangle). But any decent compiler should get rid of any > overhead there. [...] I'm not so sure I like this. @trusted bits of code really should have a safe API that cannot be called in a way that breaks @safe. Being able to essentially "cast away" @safe for arbitrary bits of code seems to me to be a rather scary, underhanded way of undermining @safe. OTOH, if your function is very large and only isolated bits are non-@safe, then a construct like this one could help, by making the code less noisy, and ensuring that the other parts of the code still remain @safe. (Though IMO in such cases the function may be better refactored to encapsulate away the @trusted bits in functions with safe APIs, and keep the @safe code all in one place.) T -- MASM = Mana Ada Sistem, Man!
How to build dmd properly?
Hello, I have the next code (minimized with DustMite): struct Tup(T...) { bool opEquals() { foreach (i; T) static if (__traits(compiles, mixin("new InputRangeObject11261!(abs_class)"))) msg; } } /**/ void test3() { Tup!(int, double) ; } interface InputRange11261(E) { } template InputRangeObject11261(R) { alias typeof(init.front()) E; class InputRangeObject11261 : InputRange11261!E { } } class abs_class { } The problem that I'm compiling dmd v2.083.1 and the version which built I gives me the next error: --- ERROR: This is a compiler bug. Please report it via https://issues.dlang.org/enter_bug.cgi with, preferably, a reduced, reproducible example and the information below. DustMite (https://github.com/CyberShadow/DustMite/wiki) can help with the reduction. --- DMD v2.083.1 predefs DigitalMars Posix linux ELFv1 CRuntime_Glibc CppRuntime_Gcc LittleEndian D_Version2 all D_SIMD D_InlineAsm_X86_64 X86_64 D_LP64 D_PIC assert D_ModuleInfo D_Exceptions D_TypeInfo D_HardFloat binarydmd version v2.083.1 config /mnt/raid/system/home/undefer/MyFiles/Sources/D/dmd/generated/linux/release/64/dmd.conf DFLAGS -I/mnt/raid/system/home/undefer/MyFiles/Sources/D/dmd/generated/linux/release/64/../../../../../druntime/import -I/mnt/raid/system/home/undefer/MyFiles/Sources/D/dmd/generated/linux/release/64/../../../../../phobos -L-L/mnt/raid/system/home/undefer/MyFiles/Sources/D/dmd/generated/linux/release/64/../../../../../phobos/generated/linux/release/64 -L--export-dynamic -fPIC --- core.exception.AssertError@dmd/dsymbolsem.d(5356): Assertion failure ??:? _d_assertp [0xf0233ed] dmd/dsymbolsem.d:5356 _ZN22DsymbolSemanticVisitor5visitEP20InterfaceDeclaration [0xee4c9a0] dmd/dclass.d:1129 _ZN20InterfaceDeclaration6acceptEP7Visitor [0xee0a439] dmd/dsymbolsem.d:378 _Z15dsymbolSemanticP7DsymbolP5Scope [0xee3d538] dmd/dtemplate.d:7427 void dmd.dtemplate.TemplateInstance.expandMembers(dmd.dscope.Scope*) [0xee5ff53] dmd/dtemplate.d:7445 void dmd.dtemplate.TemplateInstance.tryExpandMembers(dmd.dscope.Scope*) [0xee5ffca] dmd/dsymbolsem.d:5671 void dmd.dsymbolsem.templateInstanceSemantic(dmd.dtemplate.TemplateInstance, dmd.dscope.Scope*, dmd.root.array.Array!(dmd.expression.Expression).Array*) [0xee4d3ce] dmd/dsymbolsem.d:2573 _ZN22DsymbolSemanticVisitor5visitEP16TemplateInstance [0xee443be] dmd/dtemplate.d:7474 _ZN16TemplateInstance6acceptEP7Visitor [0xee60085] dmd/dsymbolsem.d:378 _Z15dsymbolSemanticP7DsymbolP5Scope [0xee3d538] dmd/typesem.d:2676 _ZN14ResolveVisitor5visitEP12TypeInstance [0xef1399c] dmd/mtype.d:5189 _ZN12TypeInstance6acceptEP7Visitor [0xeee1519] dmd/typesem.d:2418 void dmd.typesem.resolve(dmd.mtype.Type, ref const(dmd.globals.Loc), dmd.dscope.Scope*, dmd.expression.Expression*, dmd.mtype.Type*, dmd.dsymbol.Dsymbol*, bool) [0xef12f1f] dmd/typesem.d:1608 _ZN19TypeSemanticVisitor5visitEP12TypeInstance [0xef113e8] dmd/mtype.d:5189 _ZN12TypeInstance6acceptEP7Visitor [0xeee1519] dmd/typesem.d:533 _Z12typeSemanticP4Type3LocP5Scope [0xef0e0b6] dmd/dsymbolsem.d:4515 pure @nogc @safe dmd.mtype.Type dmd.dsymbolsem.DsymbolSemanticVisitor.visit(dmd.dclass.ClassDeclaration).__dgliteral2() [0xee4ba59] dmd/dsymbolsem.d:4497 dmd.mtype.Type dmd.dsymbolsem.DsymbolSemanticVisitor.visit(dmd.dclass.ClassDeclaration).resolveBase!(dmd.mtype.Type).resolveBase(lazy dmd.mtype.Type) [0xee4e220] dmd/dsymbolsem.d:4515 _ZN22DsymbolSemanticVisitor5visitEP16ClassDeclaration [0xee49cc4] dmd/dclass.d:986 _ZN16ClassDeclaration6acceptEP7Visitor [0xee0a00d] dmd/dsymbolsem.d:378 _Z15dsymbolSemanticP7DsymbolP5Scope [0xee3d538] dmd/dtemplate.d:7427 void dmd.dtemplate.TemplateInstance.expandMembers(dmd.dscope.Scope*) [0xee5ff53] dmd/dtemplate.d:7445 void dmd.dtemplate.TemplateInstance.tryExpandMembers(dmd.dscope.Scope*) [0xee5ffca] dmd/dsymbolsem.d:5671 void dmd.dsymbolsem.templateInstanceSemantic(dmd.dtemplate.TemplateInstance, dmd.dscope.Scope*, dmd.root.array.Array!(dmd.expression.Expression).Array*) [0xee4d3ce] dmd/dsymbolsem.d:2573 _ZN22DsymbolSemanticVisitor5visitEP16TemplateInstance [0xee443be] dmd/dtemplate.d:7474 _ZN16TemplateInstance6acceptEP7Visitor [0xee60085] dmd/dsymbolsem.d:378 _Z15dsymbolSemanticP7DsymbolP5Scope [0xee3d538] dmd/typesem.d:2676 _ZN14ResolveVisitor5visitEP12TypeInstance [0xef1399c] dmd/mtype.d:5189 _ZN12TypeInstance6acceptEP7Visitor [0xeee1519] dmd/typesem.d:2418 void dmd.typesem.resolve(dmd.mtype.Type, ref const(dmd.globals.Loc), dmd.dscope.Scope*, dmd.expression.Expression*, dmd.mtype.Type*, dmd.dsymbol.Dsymbol*, bool) [0xef12f1f] dmd/typesem.d:1608 _ZN19TypeSemanticVisitor5visitEP12TypeInstance [0xef113e8] dmd/mtype.d:5189 _ZN12TypeInstance6acceptEP7Visitor [0xeee1519] dmd/typesem.d:533 _Z12typeSemanticP4Type3LocP5Scope [0xef0e0b6] dmd/expressionsem.d:3094 _ZN25ExpressionSemanticVisitor5visitEP6NewExp [0xee7cb92] dmd/expression.d:3171 _ZN6Ne
Re: Temporary @trusted scope
On Tuesday, 18 December 2018 at 13:52:29 UTC, Steven Schveighoffer wrote: template unsafe(alias fn) { @trusted auto unsafe(T...)(T args) { return fn(args); } } Very nice! What about proposing this for inclusion into `std.typecons` or `std.meta`?
Re: Checking if CTFE is used?
On Tuesday, 18 December 2018 at 14:23:38 UTC, berni wrote: import std.stdio; class A { static immutable int[4] clue; static this() { if(__ctfe) assert(0, "Yep, CTFE used"); foreach (i;0..4) clue[i] = i; } } CTFE is used if and only if it MUST be used by context. That's a runtime function, so no ctfe. Do something like: int[4] generate() { int[4] tmp; foreach(i; 0..4) tmp[i] = i; return tmp; } static immutable int[4] clue = generate(); Since it is an immediate static immutable assign, ctfe MUST be used, and thus will be used. With your code, you used a runtime constructor on all runtime variables, so it did it at program startup. Generally: static immutable something = something; // must be ctfe enum something = something; // makes a ctfe literal (but not necessarily static storage) so those patterns force ctfe. While static immutable something; something = something; // NOT ctfe because it is a separate statement!
Re: Checking if CTFE is used?
On Tuesday, 18 December 2018 at 13:53:01 UTC, Stefan Koch wrote: Why would you need to know? Well, first out of curiosity. But there are also other reasons: I've got a large immutable array. Without CTFE I'd use some php script and add it as a large literal. With CTFE I don't need that php script nor do I need to put that large literal in the source code. But I need to know, that indeed the array is calculated by the compiler, else the solution with the php script would result in faster code. if(__ctfe) assert(0, "Yep, CTFE used"); That seems to work, but unfortunately, my script seems not to be evaluated at compile time... Here is a small example, similar to my code, where CTFE is not used: import std.stdio; class A { static immutable int[4] clue; static this() { if(__ctfe) assert(0, "Yep, CTFE used"); foreach (i;0..4) clue[i] = i; } } void main() { auto tmp = new A(); writeln(tmp.clue[2]); } Can you help me, finding the problem here?
Re: Reverse and sort array elements
On Tuesday, 18 December 2018 at 12:47:59 UTC, Andrey wrote: On Tuesday, 18 December 2018 at 12:32:35 UTC, angel wrote: On Tuesday, 18 December 2018 at 12:07:37 UTC, Andrey wrote: Thank you everybody. Here was another problem that local variable 'array' shadows function 'array()' from std.array. You call "array" the enum just like the array() function. Change enum array into enum arr and array.map!... into arr.map!...
Re: Reverse JSON toPrettyString
On 12/17/18 5:09 PM, Anonymouse wrote: I have a JSON string[][string] associative array object that I want to take the .toPrettyString value of. However, it sorts the output alphabetically. string[][string] aa = [ "abc" : [], "def" : [], "ghi" : [] ]; auto asJSON = JSONValue(aa); writeln(asJSON.toPrettyString); Output: { "abc": [], "def": [], "ghi": [] } https://run.dlang.io/is/F85azk Is there a way to .retro the keys in the output so they appear in the reverse order? Sorting is done here: https://github.com/dlang/phobos/blob/21afd40c422efdb8483d15aa31a867b0cd69fa8b/std/json.d#L1416 I'm not exactly sure why it's sorted, possibly so unittests pass? It doesn't really need to be. But of course, then the order would depend on the hash algorithm. Only way to fix this would be to have a specialized "order-retaining" hash map that JSONValue used, which you could then rearrange as necessary. -Steve
Re: Checking if CTFE is used?
On 12/18/18 7:21 AM, berni wrote: Is there a way to check if a function is indeed executed at compile time or not? (Other than going through the whole executable binaries...) I tried static this() { if (__ctfe) pragma(msg,"works"); // some other stuff } but unfortunatley this "if" is also executed at compile time, when I put it into a function that is only called at runtime. When I try "static if" instead the compiler complains about "__ctfe" being not known at compile time. Well, asserting would at least tell you that it's used. if(__ctfe) assert(0, "Yep, CTFE used"); But obviously, it couldn't be there for release purposes :) -Steve
Re: Temporary @trusted scope
On 12/18/18 6:29 AM, Simen Kjærås wrote: On Tuesday, 18 December 2018 at 10:14:50 UTC, Per Nordlöw wrote: What's the preferred way of creating a temporary @trusted scope without writing a separate function? Jonathan's idea might also be encapsulated in a function, just like assumeUnique in Phobos: import std.stdio; template unsafe(alias fn) { @trusted auto unsafe(T...)(T args) { return fn(args); } } @system void fun(int n) { writeln("foo!"); } @safe unittest { unsafe!({ fun(2); }); unsafe!fun(2); } Wow, I really like this. The only real problem is that one generally searches for @trusted when looking for unsafe code, but unsafe is pretty obvious too. Also, args should be auto ref. Only thing better I can think of (for the second example) is to define a prototype with the correct information, only with @trusted (and specify the mangle). But any decent compiler should get rid of any overhead there. -Steve
Re: Checking if CTFE is used?
On Tuesday, 18 December 2018 at 12:21:44 UTC, berni wrote: Is there a way to check if a function is indeed executed at compile time or not? (Other than going through the whole executable binaries...) I tried static this() { if (__ctfe) pragma(msg,"works"); // some other stuff } but unfortunatley this "if" is also executed at compile time, when I put it into a function that is only called at runtime. When I try "static if" instead the compiler complains about "__ctfe" being not known at compile time. Why would you need to know?
Re: Checking if CTFE is used?
On Tue, Dec 18, 2018 at 1:25 PM berni via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > Is there a way to check if a function is indeed executed at > compile time or not? (Other than going through the whole > executable binaries...) > > I tried > > > static this() > > { > > if (__ctfe) pragma(msg,"works"); > > // some other stuff > > } > > but unfortunatley this "if" is also executed at compile time, > when I put it into a function that is only called at runtime. > When I try "static if" instead the compiler complains about > "__ctfe" being not known at compile time. > You could use __ctfeWrite But it seems __ctfe does not work anymore https://run.dlang.io/is/snckyV
Re: Reverse and sort array elements
On Tuesday, 18 December 2018 at 12:32:35 UTC, angel wrote: On Tuesday, 18 December 2018 at 12:07:37 UTC, Andrey wrote: Thank you everybody. Here was another problem that local variable 'array' shadows function 'array()' from std.array.
Re: Temporary @trusted scope
On 19/12/2018 1:34 AM, Per Nordlöw wrote: On Tuesday, 18 December 2018 at 10:42:51 UTC, Jonathan M Davis wrote: Unfortunately, D does not currently have a way to do that. Only functions can be marked with @trusted. However, the typical approach to this problem is to use a lambda, which is more or less syntactically the same except that it has some extra parens. e.g. () @trusted { doUnsafe(); }(); Is there a performance hit when using this? Yes except for ldc with -O3. But it is a function not a delegate so it should be all nicely prefetched and ready to go. So I wouldn't worry about it too much.
Re: Reverse and sort array elements
On Tuesday, 18 December 2018 at 12:07:37 UTC, Andrey wrote: Hi, Have array: enum array = ["qwerty", "a", "baz"]; Need to reverse and sort array elements to get this result: [a, ytrewq, zab] Did this: enum result = array.map!(value => value.retro()).sort(); Got: Error: template std.algorithm.sorting.sort cannot deduce function from argument types !()(MapResult!(__lambda1, string[])), candidates are: /usr/include/dmd/phobos/std/algorithm/sorting.d(1849,1): std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r) if ((ss == SwapStrategy.unstable && (hasSwappableElements!Range || hasAssignableElements!Range) || ss != SwapStrategy.unstable && hasAssignableElements!Range) && isRandomAccessRange!Range && hasSlicing!Range && hasLength!Range) How to solve the problem? There are in fact to instances of the same problem here: The problem is map and retro are lazy - they return an element at a time, and so can't be sorted. You will need to make a arrays from them: import std.array : array; import std.range : retro; import std.algorithm : map, sort; enum arr = ["qwerty", "a", "baz"]; enum result = arr .map!(value => value.retro().array) .array // This creates an array from map's result. .sort(); -- Simen
Re: Reverse and sort array elements
On Tuesday, 18 December 2018 at 12:07:37 UTC, Andrey wrote: Hi, Have array: enum array = ["qwerty", "a", "baz"]; Need to reverse and sort array elements to get this result: [a, ytrewq, zab] Did this: enum result = array.map!(value => value.retro()).sort(); Got: Error: template std.algorithm.sorting.sort cannot deduce function from argument types !()(MapResult!(__lambda1, string[])), candidates are: /usr/include/dmd/phobos/std/algorithm/sorting.d(1849,1): std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r) if ((ss == SwapStrategy.unstable && (hasSwappableElements!Range || hasAssignableElements!Range) || ss != SwapStrategy.unstable && hasAssignableElements!Range) && isRandomAccessRange!Range && hasSlicing!Range && hasLength!Range) How to solve the problem? Did you try this ? import std.stdio; import std.algorithm; import std.range; import std.conv; void main() { enum input = ["qwerty", "a", "baz"]; enum output = input.map!(value => value.retro().to!string()).array.sort(); writeln(input); writeln(output); }
Re: Temporary @trusted scope
On Tuesday, 18 December 2018 at 10:42:51 UTC, Jonathan M Davis wrote: Unfortunately, D does not currently have a way to do that. Only functions can be marked with @trusted. However, the typical approach to this problem is to use a lambda, which is more or less syntactically the same except that it has some extra parens. e.g. () @trusted { doUnsafe(); }(); Is there a performance hit when using this?
Checking if CTFE is used?
Is there a way to check if a function is indeed executed at compile time or not? (Other than going through the whole executable binaries...) I tried static this() { if (__ctfe) pragma(msg,"works"); // some other stuff } but unfortunatley this "if" is also executed at compile time, when I put it into a function that is only called at runtime. When I try "static if" instead the compiler complains about "__ctfe" being not known at compile time.
Re: Doubt about this book: The D Programming Language
On Tuesday, 18 December 2018 at 01:16:54 UTC, Adam D Ruppe wrote: They're obvious. Stuff like doubled ; at the end of lines in code samples, or curly quotes when they should be straight. (They are the result of me fighting Microsoft Word and the review process with the publisher.) A few other things have changed, like near the end, there is a sample of my terminal library and back then it was `import terminal;`. Now it is `import arsd.terminal;` if you use the newer version of the library. But the rest still works. Thanks, Adam. And I know what you mean about fighting MS Word. It's like trying to do a jigsaw puzzle while the cat keeps batting pieces onto the floor. Invariably, you're gonna end up diving for a piece and banging your head on the table.
Reverse and sort array elements
Hi, Have array: enum array = ["qwerty", "a", "baz"]; Need to reverse and sort array elements to get this result: [a, ytrewq, zab] Did this: enum result = array.map!(value => value.retro()).sort(); Got: Error: template std.algorithm.sorting.sort cannot deduce function from argument types !()(MapResult!(__lambda1, string[])), candidates are: /usr/include/dmd/phobos/std/algorithm/sorting.d(1849,1): std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r) if ((ss == SwapStrategy.unstable && (hasSwappableElements!Range || hasAssignableElements!Range) || ss != SwapStrategy.unstable && hasAssignableElements!Range) && isRandomAccessRange!Range && hasSlicing!Range && hasLength!Range) How to solve the problem?
Re: Temporary @trusted scope
On Tuesday, 18 December 2018 at 10:14:50 UTC, Per Nordlöw wrote: What's the preferred way of creating a temporary @trusted scope without writing a separate function? Jonathan's idea might also be encapsulated in a function, just like assumeUnique in Phobos: import std.stdio; template unsafe(alias fn) { @trusted auto unsafe(T...)(T args) { return fn(args); } } @system void fun(int n) { writeln("foo!"); } @safe unittest { unsafe!({ fun(2); }); unsafe!fun(2); } -- Simen
Re: Temporary @trusted scope
On Tuesday, December 18, 2018 3:14:50 AM MST Per Nordlöw via Digitalmars-d- learn wrote: > What's the preferred way of creating a temporary @trusted scope > without writing a separate function? > > Similar to Rust's > > unsafe { /* unsafe stuff here */ } Unfortunately, D does not currently have a way to do that. Only functions can be marked with @trusted. However, the typical approach to this problem is to use a lambda, which is more or less syntactically the same except that it has some extra parens. e.g. () @trusted { doUnsafe(); }(); or auto result = () @trusted { getUnsafe:() }(); So, it's less than ideal, but it gets us close, and unless the code is long enough that maybe it should be in its own function, it's better than declaring a nested function, let alone declaring an entirely separate function at module scope. - Jonathan M Davis
Temporary @trusted scope
What's the preferred way of creating a temporary @trusted scope without writing a separate function? Similar to Rust's unsafe { /* unsafe stuff here */ }