Re: Move and CTFE

2018-06-21 Thread Per Nordlöw via Digitalmars-d-learn

On Thursday, 21 June 2018 at 20:15:42 UTC, Stefan Koch wrote:

To give some more context here:

CTFE is the most well tested feature in dmd.
So there is no room for sloppiness or functional differences!
As you previously mentioned the newCTFE engine works on a 
completely different basis then the old engine does.
This does provide both speed and better debugging support, but 
comes at the cost of having to re-implement a complete backend 
and some parts of semantic analysis.


Keep up the great work!


Re: Move and CTFE

2018-06-21 Thread Stefan Koch via Digitalmars-d-learn

On Wednesday, 30 May 2018 at 23:07:26 UTC, Jonathan M Davis wrote:


newCTFE is taking a very different approach to CTFE, and in 
theory, it will fix many of the problems that CTFE currently 
has, but it's taking Stefan quite a while to get it to where it 
needs to be to actually merge it.




To give some more context here:

I do intend newCTFE to be a drop-in replacement that offers the 
same functionality (including the very accurate error detection 
and precise error reporting)
Which was quite hard to achieve due to not being able of creating 
Error-Nodes from inside the interpreter.
I'd say for the amount of things that newCTFE currently 
_correctly_ handles it has been fast progress!


CTFE is the most well tested feature in dmd.
So there is no room for sloppiness or functional differences!
As you previously mentioned the newCTFE engine works on a 
completely different basis then the old engine does.
This does provide both speed and better debugging support, but 
comes at the cost of having to re-implement a complete backend 
and some parts of semantic analysis.




Re: Move and CTFE

2018-05-30 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, May 30, 2018 22:42:13 Q. Schroll via Digitalmars-d-learn 
wrote:
> On Wednesday, 30 May 2018 at 21:02:07 UTC, Jonathan M Davis wrote:
> > On Wednesday, May 30, 2018 20:42:38 Q. Schroll via
> >
> > Digitalmars-d-learn wrote:
> >> It seems one cannot std.algorithm.mutation.move objects
> >> explicitly. Say I have a non-copyable type
> >> [...]
> >> It fails because move() cannot be executed at compile time. The
> >> reason
> >>
> >>  "memcpy cannot be interpreted at compile time, because it
> >>
> >> has
> >> no available source code"
> >> sounds very suspicious.
> >
> > Why is it suspicious? memcpy is a C function, and you can't
> > call C functions during CTFE precisely because the compiler
> > doesn't have their source code. You can't call D functions
> > either if the compiler doesn't have their source (e.g. if
> > you're using a .di file to hide the implementation).
>
> I definitely do understand the error message and it makes sense
> that it fails the way it's implemented. However, it makes no
> sense that moving as a concept can fail at CTFE. That's what I
> find suspicious. [Maybe 'suspicious' isn't the right term; I
> couldn't express it better.] You can move rvalues at CTFE which
> proves that the compiler can do it.
>
> >> Shouldn't it be possible to move at CTFE,
> >> too, or does it mean, non-copyable types are practically
> >> unusable
> >> for CTFE?
> >
> > You can't do much in the way of pointer or memory manipulation
> > during CTFE (e.g. no pointer arithmetic or reinterpret casts).
> > So, I don't see how a move could be done during CTFE. Even if
> > the source for memcpy were available during CTFE, I suspect
> > that it wouldn't be allowed due to the lower level stuff that
> > it does.
>
> That's the explanation why probably all currently possible
> library alternatives to memcpy would fail. I suspected that when
> encountering the error, but still wonder why memcpy or other
> low-level stuff is even necessary to accomplish something the
> compiler is perfectly able to do.
>
>  From what I see, the reason for the hack is lack of
> expressiveness: We don't have rvalue-refs in D (which I find
> good) so, currently, there is no cast-solution as in C++. So for
> a proper move() that works at CTFE, we'd need some specific tool.
>
> I have no idea of the details on how the compiler handles
> lvalues. Would it make sense to add a compiler trait,
> specifically to solve moving? Like __traits(move,
> lvalue_expression) [name up for discussion] that is identical to
> lvalue_expression with the exception that the (lvalue/rvalue)
> flag (or whatever it is) is set to "rvalue". Basically, it's the
> C++ solution: After the "cast", the compiler will proceed and
> pretend it is an rvalue and therefore initiate moving.
>
> Do you think adding a trait to make move() and swap() work at
> CTFE is worth it?
>
> A quick search showed me the class "Expression" has "virtual bool
> isLvalue();" so it might be easy as wrapping and hooking that
> virtual method. To me, [1] highly suggests that it works.
>
> [1]
> https://github.com/dlang/dmd/blob/master/src/dmd/expression.d#L1219

I'm not sure that it really makes sense to worry about fixing stuff like
this in CTFE before newCTFE is actually merged.

For instance, as I understand it, current CTFE can't even really handle
mutation. Rather, it creates a new value every time you mutate a variable.
Don explained to me at one point about how even incrementing a variable
allocates memory so that you then have a new value to use. Stuff like that
is why CTFE is so slow and eats up so much memory. Much as it acts like it's
running your code in a normal fashion, it's really not implemented that way
(the reason that it works the way does having to do with how it grew into
existence out of other features rather than being designed up front). The
current CTFE implementation is incredibly hacky, and it's arguably a miracle
that it can do as much as it can.

newCTFE is taking a very different approach to CTFE, and in theory, it will
fix many of the problems that CTFE currently has, but it's taking Stefan
quite a while to get it to where it needs to be to actually merge it.

- Jonathan M Davis



Re: Move and CTFE

2018-05-30 Thread Q. Schroll via Digitalmars-d-learn

On Wednesday, 30 May 2018 at 21:02:07 UTC, Jonathan M Davis wrote:
On Wednesday, May 30, 2018 20:42:38 Q. Schroll via 
Digitalmars-d-learn wrote:
It seems one cannot std.algorithm.mutation.move objects 
explicitly. Say I have a non-copyable type

[...]
It fails because move() cannot be executed at compile time. The
reason
 "memcpy cannot be interpreted at compile time, because it 
has

no available source code"
sounds very suspicious.


Why is it suspicious? memcpy is a C function, and you can't 
call C functions during CTFE precisely because the compiler 
doesn't have their source code. You can't call D functions 
either if the compiler doesn't have their source (e.g. if 
you're using a .di file to hide the implementation).


I definitely do understand the error message and it makes sense 
that it fails the way it's implemented. However, it makes no 
sense that moving as a concept can fail at CTFE. That's what I 
find suspicious. [Maybe 'suspicious' isn't the right term; I 
couldn't express it better.] You can move rvalues at CTFE which 
proves that the compiler can do it.



Shouldn't it be possible to move at CTFE,
too, or does it mean, non-copyable types are practically 
unusable

for CTFE?


You can't do much in the way of pointer or memory manipulation 
during CTFE (e.g. no pointer arithmetic or reinterpret casts). 
So, I don't see how a move could be done during CTFE. Even if 
the source for memcpy were available during CTFE, I suspect 
that it wouldn't be allowed due to the lower level stuff that 
it does.


That's the explanation why probably all currently possible 
library alternatives to memcpy would fail. I suspected that when 
encountering the error, but still wonder why memcpy or other 
low-level stuff is even necessary to accomplish something the 
compiler is perfectly able to do.


From what I see, the reason for the hack is lack of 
expressiveness: We don't have rvalue-refs in D (which I find 
good) so, currently, there is no cast-solution as in C++. So for 
a proper move() that works at CTFE, we'd need some specific tool.


I have no idea of the details on how the compiler handles 
lvalues. Would it make sense to add a compiler trait, 
specifically to solve moving? Like __traits(move, 
lvalue_expression) [name up for discussion] that is identical to 
lvalue_expression with the exception that the (lvalue/rvalue) 
flag (or whatever it is) is set to "rvalue". Basically, it's the 
C++ solution: After the "cast", the compiler will proceed and 
pretend it is an rvalue and therefore initiate moving.


Do you think adding a trait to make move() and swap() work at 
CTFE is worth it?


A quick search showed me the class "Expression" has "virtual bool 
isLvalue();" so it might be easy as wrapping and hooking that 
virtual method. To me, [1] highly suggests that it works.


[1] 
https://github.com/dlang/dmd/blob/master/src/dmd/expression.d#L1219




Re: Move and CTFE

2018-05-30 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, May 30, 2018 20:42:38 Q. Schroll via Digitalmars-d-learn 
wrote:
> It seems one cannot std.algorithm.mutation.move objects
> explicitly. Say I have a non-copyable type
>
>  struct NoCopy
>  {
>  int payload; // some payload
>  pure nothrow @nogc @safe @disable:
>  this(this); // make it non copyable
>  }
>
> that is being used in a compile-time function evaluation where
> values are being moved.
>
>  int f() pure nothrow @nogc @safe
>  {
>  import std.algorithm.mutation : move;
>  NoCopy nc = NoCopy(1), nc2 = NoCopy(3);
>  nc = move(nc2);
>  return 0;
>  }
>
>  static assert(f() == 0); // trigger CTFE
>
> It fails because move() cannot be executed at compile time. The
> reason
>  "memcpy cannot be interpreted at compile time, because it has
> no available source code"
> sounds very suspicious.

Why is it suspicious? memcpy is a C function, and you can't call C functions
during CTFE precisely because the compiler doesn't have their source code.
You can't call D functions either if the compiler doesn't have their source
(e.g. if you're using a .di file to hide the implementation).

> Shouldn't it be possible to move at CTFE,
> too, or does it mean, non-copyable types are practically unusable
> for CTFE?

You can't do much in the way of pointer or memory manipulation during CTFE
(e.g. no pointer arithmetic or reinterpret casts). So, I don't see how a
move could be done during CTFE. Even if the source for memcpy were available
during CTFE, I suspect that it wouldn't be allowed due to the lower level
stuff that it does.

Maybe the newCTFE stuff that Stefan is working on can do more in this area
(I don't know), but in general, anything that's at all low-level is
forbidden in CTFE.

- Jonathan M Davis



Move and CTFE

2018-05-30 Thread Q. Schroll via Digitalmars-d-learn
It seems one cannot std.algorithm.mutation.move objects 
explicitly. Say I have a non-copyable type


struct NoCopy
{
int payload; // some payload
pure nothrow @nogc @safe @disable:
this(this); // make it non copyable
}

that is being used in a compile-time function evaluation where 
values are being moved.


int f() pure nothrow @nogc @safe
{
import std.algorithm.mutation : move;
NoCopy nc = NoCopy(1), nc2 = NoCopy(3);
nc = move(nc2);
return 0;
}

static assert(f() == 0); // trigger CTFE

It fails because move() cannot be executed at compile time. The 
reason
"memcpy cannot be interpreted at compile time, because it has 
no available source code"
sounds very suspicious. Shouldn't it be possible to move at CTFE, 
too, or does it mean, non-copyable types are practically unusable 
for CTFE?