Re: Checking if CTFE is used?

2018-12-18 Thread Jonathan M Davis via Digitalmars-d-learn
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

2018-12-18 Thread Jonathan M Davis via Digitalmars-d-learn
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

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

2018-12-18 Thread JN via Digitalmars-d-learn

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

2018-12-18 Thread Rainer Schuetze via Digitalmars-d-learn



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

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

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

2018-12-18 Thread aliak via Digitalmars-d-learn
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

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

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?

2018-12-18 Thread unDEFER via Digitalmars-d-learn

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?

2018-12-18 Thread berni via Digitalmars-d-learn

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?

2018-12-18 Thread unDEFER via Digitalmars-d-learn

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?

2018-12-18 Thread Seb via Digitalmars-d-learn

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

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

2018-12-18 Thread unDEFER via Digitalmars-d-learn

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

2018-12-18 Thread Per Nordlöw via Digitalmars-d-learn
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?

2018-12-18 Thread Adam D. Ruppe via Digitalmars-d-learn

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?

2018-12-18 Thread berni via Digitalmars-d-learn

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

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

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

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

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?

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

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

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

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?

2018-12-18 Thread Stefan Koch via Digitalmars-d-learn

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?

2018-12-18 Thread Daniel Kozak via Digitalmars-d-learn
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

2018-12-18 Thread Andrey via Digitalmars-d-learn

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

2018-12-18 Thread rikki cattermole via Digitalmars-d-learn

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

2018-12-18 Thread Simen Kjærås via Digitalmars-d-learn

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

2018-12-18 Thread angel via Digitalmars-d-learn

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

2018-12-18 Thread Per Nordlöw via Digitalmars-d-learn
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?

2018-12-18 Thread berni via Digitalmars-d-learn
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

2018-12-18 Thread Ron Tarrant via Digitalmars-d-learn

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

2018-12-18 Thread Andrey via Digitalmars-d-learn

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

2018-12-18 Thread Simen Kjærås via Digitalmars-d-learn

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

2018-12-18 Thread Jonathan M Davis via Digitalmars-d-learn
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

2018-12-18 Thread Per Nordlöw via Digitalmars-d-learn
What's the preferred way of creating a temporary @trusted scope 
without writing a separate  function?


Similar to Rust's

unsafe { /* unsafe stuff here */ }