Re: Mixin operator 'if' directly

2018-12-20 Thread bauss via Digitalmars-d-learn

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

2018-12-20 Thread MachineCode via Digitalmars-d-learn
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?

2018-12-20 Thread MachineCode via Digitalmars-d-learn

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

2018-12-20 Thread Marko via Digitalmars-d-learn
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

2018-12-20 Thread Marko via Digitalmars-d-learn
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

2018-12-20 Thread H. S. Teoh via Digitalmars-d-learn
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

2018-12-20 Thread Steven Schveighoffer via Digitalmars-d-learn

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

2018-12-20 Thread Andrea Fontana via Digitalmars-d-learn

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

2018-12-20 Thread Marko via Digitalmars-d-learn
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

2018-12-20 Thread Per Nordlöw via Digitalmars-d-learn

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

2018-12-20 Thread bauss via Digitalmars-d-learn
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!