Re: Mixin operator 'if' directly
On Thursday, 20 December 2018 at 16:23:39 UTC, H. S. Teoh wrote: On Thu, Dec 20, 2018 at 11:04:19AM +, bauss via Digitalmars-d-learn wrote: [...] [...] [...] Me too! This is awesome! This basically lets you insert arbitrary code via mixin templates with essentially no restrictions! You can even reuse the same ignore-identifiers in multiple instantiations of the same template, e.g.: [...] I have so many places where I created a function manually using mixin template, that I then call afterwards. I can save so many manual function calls, allowing for easier maintenance! I have no idea why I've never thought about that before.
Re: Doubt about this book: The D Programming Language
On Sunday, 16 December 2018 at 19:57:08 UTC, Steven Schveighoffer wrote: On 12/16/18 1:37 PM, Marko wrote: On Amazon The D Programming Language has good reviews but it's 8 years old. So is this book still relevant today? Mostly, yes. And it's a pretty good book, even if it has some outdated parts. There's errata somewhere too. Would you recommend another book? I highly recommend this book (available online for free or you can purchase a hard copy): http://ddili.org/ders/d.en/index.html It is continually updated by Ali, so it should be up to date with the latest compiler. PS: I am already a programmer writing mainly in C and C#. I hope you feel right at home here :) But I must warn you, if you're anything like me, you will hate having to go back to another language. -Steve Too bad when I need to go back to C# and/or C++ for a while. haha
Re: Checking if CTFE is used?
On Tuesday, 18 December 2018 at 14:23:38 UTC, berni wrote: 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. How is the items in the array generated? if the function can be called as following: enum myArr = generateArray(); then you know for sure you have a satic array of strings at compile time. I've used something similar, to generate a JSON string from all UDAs in a give class, which I needed to pass to a C# application (I made the D output a string from the request by command line option). I did something like this: string getAvailableForms() { import extensions.enumeration : staticMembers; import asdf; // JSON serializer import std.traits : getUDAs, hasUDA; import externalPaths : ExternalAppPath, DisplayName; import std.algorithm : startsWith; import std.conv : to; FormDisplayNameObj[] output; static foreach(string fieldName; staticMembers!ExternalAppPath) {{ static if(hasUDA!(__traits(getMember, ExternalAppPath, fieldName), DisplayName)) { if(fieldName.startsWith(startKey)) { DisplayName dn = getUDAs!(__traits(getMember, ExternalAppPath, fieldName), DisplayName)[0]; string id = extractDigits(fieldName[startKey.length - 1 .. $]); int i = to!int(id); auto o = new FormDisplayNameObj(); o.value = dn.value; o.index = i; output ~= o; } } }} return output.serializeToJson; } then: enum s = getAvailableForms; writeln(s); I did consider at first make a script to generate that string but I managed to make it work with CTFE that way.
Re: Weird const behavior
On Thursday, 20 December 2018 at 15:17:31 UTC, Steven Schveighoffer wrote: It's really how opEquals is marked. opEquals for structs (without a specific implementation), is marked as a combination of comparing all the fields, whatever they are marked. Any basic types are comparable whether they are const or not. So most likely the range struct's opEquals is marked const. However, popFront is likely not const. In some rare cases it can be (i.e. an infinite range of a single value). If the range cannot be operated, isInputRange returns false. -Steve I know about promotion / implicit casting, but I always find this is a but awkward when comparing objects or structs it's equal but acts differently. But I'm may be the minority. :) Marko.
Re: Weird const behavior
On Thursday, 20 December 2018 at 15:15:42 UTC, Andrea Fontana wrote: On Thursday, 20 December 2018 at 14:49:10 UTC, Marko wrote: But is this right? I mean if they are equal shouldn't they have the same behavior? I don't think so: float a = 1.0; long b = 1; writeln(a == b); writeln(a/2 == b/2); Of course you can play around: uint positive_one = 1; short minus_one = -1; uint max_int = 4294967295; writeln(minus_one > positive_one); // true writeln(minus_one == max_int); // true Because promotion and implicit casting. But like I said this is sometimes confusion, and on the OP example it's worth. Marko.
Re: Mixin operator 'if' directly
On Thu, Dec 20, 2018 at 11:04:19AM +, bauss via Digitalmars-d-learn wrote: > On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh wrote: [...] > > mixin template foo() > > { > > int _ignoreme() > > { > > if (readln.strip == "abort") throw new AbortException; > > return 1; > > } > > int _alsoIgnoreMe = _ignoreme(); > > } > > void main() > > { > > mixin foo; > > } > > That's a genius hack. > > I have to adapt this! Me too! This is awesome! This basically lets you insert arbitrary code via mixin templates with essentially no restrictions! You can even reuse the same ignore-identifiers in multiple instantiations of the same template, e.g.: import std.stdio; mixin template CodeMixin(int i) { int _impl() { static if (i == 0) { writeln("Haha, we inserted code via declarations!"); return int.init; } else static if (i == 1) { writeln("Well whaddya know, we can do multiple mixins!"); return int.init; } else static assert(0); } int _impl2 = _impl(); } void main() { writeln("Does it respect order?"); mixin CodeMixin!0; writeln("I should think so! But you never know..."); mixin CodeMixin!1; writeln("Wow, can we really do multiple mixins of this sort?"); } The output is: Does it respect order? Haha, we inserted code via declarations! I should think so! But you never know... Well whaddya know, we can do multiple mixins! Wow, can we really do multiple mixins of this sort? T -- If I were two-faced, would I be wearing this one? -- Abraham Lincoln
Re: Weird const behavior
On 12/20/18 9:49 AM, Marko wrote: On Thursday, 20 December 2018 at 02:05:53 UTC, Adam D. Ruppe wrote: On Thursday, 20 December 2018 at 01:37:59 UTC, Simón Oroño wrote: The only difference (code-wise) is the `const` keyword. I've tried with both `ldc` and `dmd` with same result. Why is the output different when the variable is `const`? A const range cannot be iterated by a generic template (without additional work, at least), so writeln just sees it as a blob instead of something it can loop over. I'm not the OP but I'd like to understand this: When he is comparing "a == b" it returns true, but then it diverges on the usability. So a == b compares just values without types? But is this right? I mean if they are equal shouldn't they have the same behavior? Marko. It's really how opEquals is marked. opEquals for structs (without a specific implementation), is marked as a combination of comparing all the fields, whatever they are marked. Any basic types are comparable whether they are const or not. So most likely the range struct's opEquals is marked const. However, popFront is likely not const. In some rare cases it can be (i.e. an infinite range of a single value). If the range cannot be operated, isInputRange returns false. -Steve
Re: Weird const behavior
On Thursday, 20 December 2018 at 14:49:10 UTC, Marko wrote: But is this right? I mean if they are equal shouldn't they have the same behavior? I don't think so: float a = 1.0; long b = 1; writeln(a == b); writeln(a/2 == b/2);
Re: Weird const behavior
On Thursday, 20 December 2018 at 02:05:53 UTC, Adam D. Ruppe wrote: On Thursday, 20 December 2018 at 01:37:59 UTC, Simón Oroño wrote: The only difference (code-wise) is the `const` keyword. I've tried with both `ldc` and `dmd` with same result. Why is the output different when the variable is `const`? A const range cannot be iterated by a generic template (without additional work, at least), so writeln just sees it as a blob instead of something it can loop over. I'm not the OP but I'd like to understand this: When he is comparing "a == b" it returns true, but then it diverges on the usability. So a == b compares just values without types? But is this right? I mean if they are equal shouldn't they have the same behavior? Marko.
Optimal implementation of identity function
For the default case (`return key`) in auto adjustKeyType(SomeKey)(const return scope SomeKey key) const @trusted { pragma(inline, true);// must be inlined static if (is(SomeKey : U[], U)) // is array { /* because return value is used only temporarily it's ok to cast to * `immutable` to prevent GC-allocations in types such as * `sso_string.SSOString` */ return cast(immutable(typeof(key[0]))[])key; } else { return key; } } I want this function to be optimized away completely when inlined in release mode. Is this the best of achieving this with regards to 1. its return type: auto (or is better auto ref) and 2. parameter `key` being qualified as `return scope` ?
Re: Mixin operator 'if' directly
On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh wrote: On Wed, 19 Dec 2018 15:12:14 +, bauss wrote: That's assuming that it's compile-time data though. If not then you can't do what you want to do. What you can do is wrap it in a function in the mixin template which you just call after instantiating it. Or while instantiating it: mixin template foo() { int _ignoreme() { if (readln.strip == "abort") throw new AbortException; return 1; } int _alsoIgnoreMe = _ignoreme(); } void main() { mixin foo; } That's a genius hack. I have to adapt this!