Re: Confusion/trying to understand CTFE keywords

2018-06-08 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, June 08, 2018 03:51:11 David Bennett via Digitalmars-d-learn 
wrote:
> On Thursday, 7 June 2018 at 04:58:40 UTC, Jonathan M Davis wrote:
> > It would be trivial enough to create a wrapper template so that
> > you can do something like
> >
> > immutable n = ctfe!(foo());
> >
> > e.g.
> >
> > template ctfe(alias value)
> > {
> >
> > enum ctfe = value;
> >
> > }
>
> Would this be equivalent to using static immutable?
>
> static immutable n = foo();
>
> In this case both the compiletime and runtime values were
> calculated using cfte.

No, they're not equivalent. That template definition just forces the value
to be calculated at compile time. It doesn't change anything about the
variable itself. Making the variable static means that there is only one
instance of the variable across all calls to the function. So, its address
is not within the stack of the function. Given that the variable is
immutable and thus cannot be changed means that that distinction doesn't
matter a lot in this case, but there's still a difference. And if you make
the variables mutable, it makes a huge difference. e.g

auto n = ctfe!(foo());

vs

static n = foo();

In both cases, the value is calculated at compile time, but in the first
case, you get a unique copy for each function call that does not exist
beyond that function call, whereas in the second case, it's reused for each
function call, so if you mutate it, subsequent calls will see the mutated
value (which would not be true if the variable weren't static).

> Also back to the OP the way I think of enum, static types is like
> this:
>
> alias and enum create compiletime stuff from compiletime stuff.
> static creates runtime stuff from compiletime stuff.
>
> Is that view valid in most cases?

Sort of but not really. enums are just names for compile-time values. As
such, they have to be calculated at compile time. static variables on the
other hand really have nothing to do with compile time per se. It's just
that they have a single location in memory for the entire thread of the
program. So, they get initialized when the thread is created and not when
the function is called and as such have to have their initial value known at
compile time unless a static constructor is used to initialize them. They're
either intialized with the init value for their type or the value that
they're given when declared. The exact same thing happens with member
variables. e.g.

struct S
{
int i = foo();
}

makes it so that S.init.i is whatever value was the result of foo. If the
struct has a constructor, then that's the value of i before the constructor
is called. The init value for the struct must be known at compile time, so
any direct initialization is done at compile time (whereas if none is done,
then the init value for the type of the member variable is used). If the
member variable is const or immutable, then if it's directly initialized,
then it can't be assigned in the constructor, and if it's not directly
initialized, its init value is overwritten by the constructor and isn't
really used. But regardless, the init value must be known at compile time,
which means that any direct initialization must be calculated at compile
time.

So, the fact that static variables get their intial values at compile time
is just because of how they're intialized, not because of static
specifically being designed with compile-time anything in mind. The result
is that you then have a variable whose initial value was determined at
compile time and then can be manipulated at runtime (assuming that it's
mutable), but the key thing about static variables is their lifetime, not
that they're initialized at compile time.

If what you're really looking for is to calculate the value of a local
variable at compile-time, you're better off using an enum and then
initializing the local variable with the enum than using a static variable.
The only reason to use a static variable is if you specifically want a
variable whose lifetime is for the duration of the thread rather than the
duration of the function call. If you're using static just to get the value
calculated at compile time, you're increasing how much memory your thread
takes up when there really isn't a good reason to do so.

- Jonathan M Davis



Re: Confusion/trying to understand CTFE keywords

2018-06-08 Thread jmh530 via Digitalmars-d-learn

On Friday, 8 June 2018 at 17:09:54 UTC, H. S. Teoh wrote:


I would, if I had the time to spare to make such a chart.  
Perhaps you (or somebody here) could do it?  It *is* a wiki, 
after all.  Y'all don't have to wait for me to get around to 
it, the edit button is right there.



T


Fair point.


Re: Confusion/trying to understand CTFE keywords

2018-06-08 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jun 08, 2018 at 02:57:26PM +, jmh530 via Digitalmars-d-learn wrote:
[...]
> May I suggest that you add a flow chart that gives a very high level
> understanding of the compiler steps. Like how Rust's introduction to
> MIR has:
> https://blog.rust-lang.org/2016/04/19/MIR.html

I would, if I had the time to spare to make such a chart.  Perhaps you
(or somebody here) could do it?  It *is* a wiki, after all.  Y'all don't
have to wait for me to get around to it, the edit button is right there.


T

-- 
Give a man a fish, and he eats once. Teach a man to fish, and he will sit 
forever.


Re: Confusion/trying to understand CTFE keywords

2018-06-08 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jun 08, 2018 at 02:36:01PM +, Gopan via Digitalmars-d-learn wrote:
> On Friday, 8 June 2018 at 05:10:16 UTC, H. S. Teoh wrote:
> > All this talk of CTFE and "compile-time", along with the confusion
> > that arises from conflating everything done by the compiler into the
> > blanket term "compile-time" makes me want to scream:
> > 
> > https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time
> > 
> > 
> 
> 
> Hi Teoh,  Your article is a killer!  A must read for all serious
> users.  Can't we navigate to this article from the DLang site?  (I
> mean, if I don't know the specific url, how can I reach there?)
[...]

The goal is to eventually put this article among the main articles on
the wiki, but there are some loose ends that I need to clean up, and I
just haven't had the time to work on it.

Perhaps I should just invite others here to edit the article, clean it
up, and publish it, instead of letting it linger forever as a userpage.
I just don't have enough spare time right now to do it justice.


T

-- 
What do you call optometrist jokes? Vitreous humor.


Re: Confusion/trying to understand CTFE keywords

2018-06-08 Thread jmh530 via Digitalmars-d-learn

On Friday, 8 June 2018 at 05:10:16 UTC, H. S. Teoh wrote:
All this talk of CTFE and "compile-time", along with the 
confusion that arises from conflating everything done by the 
compiler into the blanket term "compile-time" makes me want to 
scream:


https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time



;-)

tl;dr: D's "compile-time" features consist of (at least) two 
distinct phases of code transformation: template expansion and 
CTFE, and having a proper understanding of exactly what they 
are and what the distinction between them is, will go a long 
way in clearing up a lot of the confusion commonly experienced 
by newcomers to D in regard to D's so-called "compile-time" 
features.



--T


May I suggest that you add a flow chart that gives a very high 
level understanding of the compiler steps. Like how Rust's 
introduction to MIR has:

https://blog.rust-lang.org/2016/04/19/MIR.html



Re: Confusion/trying to understand CTFE keywords

2018-06-08 Thread Gopan via Digitalmars-d-learn

On Friday, 8 June 2018 at 05:10:16 UTC, H. S. Teoh wrote:
All this talk of CTFE and "compile-time", along with the 
confusion that arises from conflating everything done by the 
compiler into the blanket term "compile-time" makes me want to 
scream:


https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time





Hi Teoh,  Your article is a killer!  A must read for all serious 
users.  Can't we navigate to this article from the DLang site?  
(I mean, if I don't know the specific url, how can I reach there?)


Thanks,
Gopan


Re: Confusion/trying to understand CTFE keywords

2018-06-07 Thread H. S. Teoh via Digitalmars-d-learn
All this talk of CTFE and "compile-time", along with the confusion that
arises from conflating everything done by the compiler into the blanket
term "compile-time" makes me want to scream:

https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time



;-)

tl;dr: D's "compile-time" features consist of (at least) two distinct
phases of code transformation: template expansion and CTFE, and having a
proper understanding of exactly what they are and what the distinction
between them is, will go a long way in clearing up a lot of the
confusion commonly experienced by newcomers to D in regard to D's
so-called "compile-time" features.


--T


Re: Confusion/trying to understand CTFE keywords

2018-06-07 Thread David Bennett via Digitalmars-d-learn

On Thursday, 7 June 2018 at 04:58:40 UTC, Jonathan M Davis wrote:


It would be trivial enough to create a wrapper template so that 
you can do something like


immutable n = ctfe!(foo());

e.g.

template ctfe(alias value)
{
enum ctfe = value;
}



Would this be equivalent to using static immutable?

static immutable n = foo();

In this case both the compiletime and runtime values were 
calculated using cfte.


Also back to the OP the way I think of enum, static types is like 
this:


alias and enum create compiletime stuff from compiletime stuff.
static creates runtime stuff from compiletime stuff.

Is that view valid in most cases?




Re: Confusion/trying to understand CTFE keywords

2018-06-07 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, June 07, 2018 11:31:13 jmh530 via Digitalmars-d-learn wrote:
> On Wednesday, 6 June 2018 at 22:19:58 UTC, Jonathan M Davis wrote:
> > On Wednesday, June 06, 2018 18:18:16 jmh530 via
> >
> > Digitalmars-d-learn wrote:
> >> On Monday, 4 June 2018 at 03:18:05 UTC, Jonathan M Davis wrote:
> >> > [snip]
> >> >
> >> > If you haven't yet, I'd suggest reading
> >>
> >> Would make a good blog series?
> >
> > What would make a good blog series? Something talking about
> > CTFE?
> >
> > - Jonathan M Davis
>
> I meant that stuff describing the nuances and motivations between
> static/enum/etc. Maybe more tutorial or something on the wiki
> than blog series? It's the type of thing that isn't obvious to
> someone new to D, but you explain very well. Better to save it in
> some place easy to find than let it get buried in Learn.

I probably should do more write-ups of stuff somewhere so that I can point
people to them, but for better or worse, I haven't done much of that. I've
mostly just answered questions here or at stackoverflow. I did finally get
my website set up though (http://jmdavisprog.com) so that I have somewhere
to post articles and whatnot, but I haven't done much with it yet. Sadly,
the only reason that I finally got around to setting it up was that I was
pretty much forced to in order to have a place to put the documentation for
dxml. Doing more useful write-ups has been on my todo list for ages but
mostly hasn't ended up as a priority with everything else on my plate -
which is arguably a bit dumb given how often I ultimately end up spending a
bunch of time answering questions on D.Learn even when I theoretically try
to not spend a lot of time replying to posts.

- Jonathan M Davis



Re: Confusion/trying to understand CTFE keywords

2018-06-07 Thread jmh530 via Digitalmars-d-learn

On Wednesday, 6 June 2018 at 22:19:58 UTC, Jonathan M Davis wrote:
On Wednesday, June 06, 2018 18:18:16 jmh530 via 
Digitalmars-d-learn wrote:

On Monday, 4 June 2018 at 03:18:05 UTC, Jonathan M Davis wrote:
> [snip]
>
> If you haven't yet, I'd suggest reading

Would make a good blog series?


What would make a good blog series? Something talking about 
CTFE?


- Jonathan M Davis


I meant that stuff describing the nuances and motivations between 
static/enum/etc. Maybe more tutorial or something on the wiki 
than blog series? It's the type of thing that isn't obvious to 
someone new to D, but you explain very well. Better to save it in 
some place easy to find than let it get buried in Learn.


Re: Confusion/trying to understand CTFE keywords

2018-06-06 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, June 07, 2018 04:41:35 Gopan via Digitalmars-d-learn wrote:
> On Tuesday, 5 June 2018 at 22:08:32 UTC, Stefan Koch wrote:
> > On Tuesday, 5 June 2018 at 18:00:05 UTC, Steven Schveighoffer
> >
> > wrote:
> >> No, it's definitely a bug. main is not being evaluated at
> >> compile time. The real result of this function should be a
> >> compile-time error -- __ctfe is a *runtime* value that is
> >> always defined based on whether you are __ctfe or not.
> >> Therefore, n must be a runtime value, and not usable as a
> >> static array dimension.
> >>
> >> If the posted code is valid, then this should be valid as well:
> >>
> >> static if(__ctfe)
> >>
> >>immutable n = 1;
> >>
> >> else
> >>
> >>immutable n = 2;
> >>
> >> But it's not.
> >>
> >> -Steve
> >
> > I see what you mean.
> > I fear fixing this bug will not be easy without breaking
> > arguably valid uses.
>
> Will it be feasible something like
>
> int n = CTFE(foo(3)); //dont limit CTFE to enum or immutable,
> etc.  You are calling explicitly.
> int[n] arr;
>
> So that, we can be explicit about when CTFE kicks in.  In that
> case, don't assign value to n at runtime as it has been
> initialized at compile time.  This way, we can get rid of the
> intermediate enums which are introduced just for the sake of
> inviting CTFE.  Also, this way, it will not silently break
> existing code; instead a compilation error must be thrown "value
> of n not known at compile time" for the below code.
>
> immutable n = foo();
> int[n] arr;
>
> Unless called throgh CTFE(), dont go for CTFE.
>
> Will this work?
>
> Just putting my thoughts... I am no expert.

The core problem with this is that it's using a runtime variable at compile
time, which doesn't normally work. The fact that it works with an immutable
variable is a weird quirk based on the fact that it was assumed that the
value would be identical at both runtime and compile time, and as already
shown in this thread, that results in other bugs.

It would be trivial enough to create a wrapper template so that you can do
something like

immutable n = ctfe!(foo());

e.g.

template ctfe(alias value)
{
enum ctfe = value;
}

The problem is the fact that a runtime variable is being allowed in a
context that requires a compile time value. That violates how CTFE normally
works, increasing the confusion about when CTFE kicks in, and as shown in
this thread, it can result in subtle bugs.

- Jonathan M Davis



Re: Confusion/trying to understand CTFE keywords

2018-06-06 Thread Gopan via Digitalmars-d-learn

On Tuesday, 5 June 2018 at 22:08:32 UTC, Stefan Koch wrote:
On Tuesday, 5 June 2018 at 18:00:05 UTC, Steven Schveighoffer 
wrote:


No, it's definitely a bug. main is not being evaluated at 
compile time. The real result of this function should be a 
compile-time error -- __ctfe is a *runtime* value that is 
always defined based on whether you are __ctfe or not. 
Therefore, n must be a runtime value, and not usable as a 
static array dimension.


If the posted code is valid, then this should be valid as well:

static if(__ctfe)
   immutable n = 1;
else
   immutable n = 2;

But it's not.

-Steve


I see what you mean.
I fear fixing this bug will not be easy without breaking 
arguably valid uses.


Will it be feasible something like

int n = CTFE(foo(3)); //dont limit CTFE to enum or immutable, 
etc.  You are calling explicitly.

int[n] arr;

So that, we can be explicit about when CTFE kicks in.  In that 
case, don't assign value to n at runtime as it has been 
initialized at compile time.  This way, we can get rid of the 
intermediate enums which are introduced just for the sake of 
inviting CTFE.  Also, this way, it will not silently break 
existing code; instead a compilation error must be thrown "value 
of n not known at compile time" for the below code.


immutable n = foo();
int[n] arr;

Unless called throgh CTFE(), dont go for CTFE.

Will this work?

Just putting my thoughts... I am no expert.


Re: Confusion/trying to understand CTFE keywords

2018-06-06 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, June 06, 2018 18:18:16 jmh530 via Digitalmars-d-learn wrote:
> On Monday, 4 June 2018 at 03:18:05 UTC, Jonathan M Davis wrote:
> > [snip]
> >
> > If you haven't yet, I'd suggest reading
>
> Would make a good blog series?

What would make a good blog series? Something talking about CTFE?

- Jonathan M Davis



Re: Confusion/trying to understand CTFE keywords

2018-06-06 Thread jmh530 via Digitalmars-d-learn

On Monday, 4 June 2018 at 03:18:05 UTC, Jonathan M Davis wrote:

[snip]

If you haven't yet, I'd suggest reading


Would make a good blog series?


Re: Confusion/trying to understand CTFE keywords

2018-06-05 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, June 05, 2018 22:08:32 Stefan Koch via Digitalmars-d-learn 
wrote:
> On Tuesday, 5 June 2018 at 18:00:05 UTC, Steven Schveighoffer
>
> wrote:
> > No, it's definitely a bug. main is not being evaluated at
> > compile time. The real result of this function should be a
> > compile-time error -- __ctfe is a *runtime* value that is
> > always defined based on whether you are __ctfe or not.
> > Therefore, n must be a runtime value, and not usable as a
> > static array dimension.
> >
> > If the posted code is valid, then this should be valid as well:
> >
> > static if(__ctfe)
> >
> >immutable n = 1;
> >
> > else
> >
> >immutable n = 2;
> >
> > But it's not.
> >
> > -Steve
>
> I see what you mean.
> I fear fixing this bug will not be easy without breaking arguably
> valid uses.

Any such case should work by either using an enum instead or using an enum
to have the value during CTFE and then initialize a const or immutable
variable with it. We'd likely need to deprecate the old behavior rather than
simply fixing it in order to avoid breaking code, but the result would
ultimately be cleaner, and it should be easy for any affected code to be
updated. As is standsw the fact that

immutable i = foo();
int[i] arr;

works and uses CTFE whereas

immutable i = foo();

doesn't do any CTFE just increases the confusion of how CTFE works. The fact
that __ctfe then affects things further just makes matters worse. CTFE
really should only kick in when it has to kick in. That way, it's clean and
understandable as to when it kicks in and when it doesn't, and anyone who
wants to initialize a local variable with CTFE can always just use an
intermediary enum. We have too much confusion over when CTFE kicks in even
without this quirk with immutable.

- Jonathan M Davis



Re: Confusion/trying to understand CTFE keywords

2018-06-05 Thread Stefan Koch via Digitalmars-d-learn
On Tuesday, 5 June 2018 at 18:00:05 UTC, Steven Schveighoffer 
wrote:


No, it's definitely a bug. main is not being evaluated at 
compile time. The real result of this function should be a 
compile-time error -- __ctfe is a *runtime* value that is 
always defined based on whether you are __ctfe or not. 
Therefore, n must be a runtime value, and not usable as a 
static array dimension.


If the posted code is valid, then this should be valid as well:

static if(__ctfe)
   immutable n = 1;
else
   immutable n = 2;

But it's not.

-Steve


I see what you mean.
I fear fixing this bug will not be easy without breaking arguably 
valid uses.




Re: Confusion/trying to understand CTFE keywords

2018-06-05 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/5/18 12:10 PM, Stefan Koch wrote:

This is not bug just not very intuitive.

Since you are declaring a static array the value of n needs to known at 
compiletime.

so it'll  try to evaluate n at an compile-time context in which n is 1.
however when code-generation for the function is done __ctfe will be false.
Causing the n variable to be initialized to 2.

Therefore n will not be equal to a.length.


No, it's definitely a bug. main is not being evaluated at compile time. 
The real result of this function should be a compile-time error -- 
__ctfe is a *runtime* value that is always defined based on whether you 
are __ctfe or not. Therefore, n must be a runtime value, and not usable 
as a static array dimension.


If the posted code is valid, then this should be valid as well:

static if(__ctfe)
   immutable n = 1;
else
   immutable n = 2;

But it's not.

-Steve


Re: Confusion/trying to understand CTFE keywords

2018-06-05 Thread Stefan Koch via Digitalmars-d-learn
On Tuesday, 5 June 2018 at 13:27:35 UTC, Steven Schveighoffer 
wrote:

On 6/5/18 6:40 AM, Simen Kjærås wrote:

On Tuesday, 5 June 2018 at 09:36:22 UTC, Gopan wrote:

void main()
{
    immutable n = __ctfe ? 1 : 2;
    int[n] a;
    assert(a.length == n); // fails, wat
}


That's gotta be a bug - that should give a 'variable n cannot 
be read at compile time' error. The fact that n is immutable 
shouldn't be enough to use it at compile time. Filed as 
https://issues.dlang.org/show_bug.cgi?id=18945.


Indeed it is a bug. Interesting to see what the compiler sees 
as its AST:


import object;
void main()
{
immutable immutable(int) n = __ctfe ? 1 : 2;
int[1] a = 0;
assert(1LU == cast(ulong)n);
return 0;
}

This is what -vcg-ast spits out.

Note the int[1].

-Steve

This is not bug just not very intuitive.

Since you are declaring a static array the value of n needs to 
known at compiletime.
so it'll  try to evaluate n at an compile-time context in which n 
is 1.
however when code-generation for the function is done __ctfe will 
be false.

Causing the n variable to be initialized to 2.

Therefore n will not be equal to a.length.


Re: Confusion/trying to understand CTFE keywords

2018-06-05 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/5/18 6:40 AM, Simen Kjærås wrote:

On Tuesday, 5 June 2018 at 09:36:22 UTC, Gopan wrote:

void main()
{
    immutable n = __ctfe ? 1 : 2;
    int[n] a;
    assert(a.length == n); // fails, wat
}


That's gotta be a bug - that should give a 'variable n cannot be read at 
compile time' error. The fact that n is immutable shouldn't be enough to 
use it at compile time. Filed as 
https://issues.dlang.org/show_bug.cgi?id=18945.


Indeed it is a bug. Interesting to see what the compiler sees as its AST:

import object;
void main()
{
immutable immutable(int) n = __ctfe ? 1 : 2;
int[1] a = 0;
assert(1LU == cast(ulong)n);
return 0;
}

This is what -vcg-ast spits out.

Note the int[1].

-Steve


Re: Confusion/trying to understand CTFE keywords

2018-06-05 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, June 05, 2018 11:18:05 Gopan via Digitalmars-d-learn wrote:
> On Tuesday, 5 June 2018 at 10:40:20 UTC, Simen Kjærås wrote:
> > On Tuesday, 5 June 2018 at 09:36:22 UTC, Gopan wrote:
> >> void main()
> >> {
> >>
> >> immutable n = __ctfe ? 1 : 2;
> >> int[n] a;
> >> assert(a.length == n); // fails, wat
> >>
> >> }
> >
> > That's gotta be a bug - that should give a 'variable n cannot
> > be read at compile time' error. The fact that n is immutable
> > shouldn't be enough to use it at compile time. Filed as
> > https://issues.dlang.org/show_bug.cgi?id=18945.
> >
> > --
> >
> >   Simen
>
> Not only immutable.  The behavior is same if you declare n as
> 'const int' also.

It's a bug either way. I suspect that someone made it work as an enhancement
request at some point on the theory that the variable was guaranteed to
always be the same, and they didn't take __ctfe into account. Regardless,
initializing a non-static, local variable shouldn't be triggering CTFE.

- Jonathan M Davis




Re: Confusion/trying to understand CTFE keywords

2018-06-05 Thread Gopan via Digitalmars-d-learn

On Tuesday, 5 June 2018 at 10:40:20 UTC, Simen Kjærås wrote:

On Tuesday, 5 June 2018 at 09:36:22 UTC, Gopan wrote:

void main()
{
immutable n = __ctfe ? 1 : 2;
int[n] a;
assert(a.length == n); // fails, wat
}


That's gotta be a bug - that should give a 'variable n cannot 
be read at compile time' error. The fact that n is immutable 
shouldn't be enough to use it at compile time. Filed as 
https://issues.dlang.org/show_bug.cgi?id=18945.


--
  Simen


Not only immutable.  The behavior is same if you declare n as 
'const int' also.





Re: Confusion/trying to understand CTFE keywords

2018-06-05 Thread Simen Kjærås via Digitalmars-d-learn

On Tuesday, 5 June 2018 at 09:36:22 UTC, Gopan wrote:

void main()
{
immutable n = __ctfe ? 1 : 2;
int[n] a;
assert(a.length == n); // fails, wat
}


That's gotta be a bug - that should give a 'variable n cannot be 
read at compile time' error. The fact that n is immutable 
shouldn't be enough to use it at compile time. Filed as 
https://issues.dlang.org/show_bug.cgi?id=18945.


--
  Simen


Re: Confusion/trying to understand CTFE keywords

2018-06-05 Thread Gopan via Digitalmars-d-learn

On Sunday, 3 June 2018 at 21:32:06 UTC, gdelazzari wrote:
Couldn't a keyword like "ctfe" (just making it up right now) 
exist? So that, when seeing something like


ctfe myNumber = 5;

ctfe if (myNumber + 2 == 7)
{
  // ...
}

one could immediately understand that the code is 
executed/evaluated at compile time. True, after someone knows 
that "static" and "enum" mean (in the above example) that some 
compile-time things are happening, it's fine. I just find it a 
bit confusing not having a dedicated keyword but re-using 
existing ones that also serve other purposes...




Hi gdelazzari,

While seeing your post, I just recollected my post 4 years ago. 
https://forum.dlang.org/post/wbfnvwulchrpnrxov...@forum.dlang.org
I recommend you to go through it.  Let me put here my thoughts 
again.


void main()
{
immutable n = __ctfe ? 1 : 2;
int[n] a;
assert(a.length == n); // fails, wat
}

Here, the declaration int[n] a forces n to be calculated during 
compile time.  During compile time, __ctfe is true (I dont know 
if it a variable or macro, etc).  Hence the value of n during 
compile time is 1.  So, size of the array a is 1.  Anyway, n is 
calculated during runtime too. At runtime, __ctfe is false.  n 
becomes 2.  Finally, at runtime a.length is 1 and n is 2.


This shocked me.  ie While reading a huge code, you need to check 
how you got the value of n, which I personally dont want to.


While this scared me away, I thought about it.  What is the 
underlying problem?  My immediate answer is that the same 
variable getting computed during both compile time and runtime 
caused this issue.  Why should a variable get a new value at 
runtime if it has already got a value during compile time, for 
the same statement?


May be I am less imaginative.  I still wish some could enlighten 
me to accept this behavior if everybody else thinks it is right.


Regards,
Gopan


Re: Confusion/trying to understand CTFE keywords

2018-06-04 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, June 04, 2018 14:05:28 gdelazzari via Digitalmars-d-learn wrote:
> On Monday, 4 June 2018 at 03:18:05 UTC, Jonathan M Davis wrote:
> > So, while static _seems_ somewhat inconsistent at first, the
> > way it's used is pretty consistent overall. The main
> > inconsistency is the places where static is essentially
> > implicit rather than explicit (such as module-level variables
> > or structs nested in other structs or classes).
>
> I'm not getting this however. I mean, sure, it's totally
> consistent if you consider the cases you described, but what I
> meant is that in a piece of code like
>
> static if (a == 3)
> {
>// stuff...
> }
> static else if (a == 2)
> {
>// other stuff...
> }
> else
> {
>// etc...
> }
>
> the "static" keyword has a different meaning, in this case it
> means that the if gets evaluated at compile time. This is the
> kind of inconsistency I was talking about.

Yeah, that would be inconsistent with the others. I'd forgotten about those
when I wrote my reply. Basically, in the case of static if, static foreach,
and static assert, it just means that it's the compile-time variant of the
construct in question. The keyword reuse works well, but it is inconsistent
with the other uses. I guess that it could be argued that they don't have a
context, because they're done at compile-time, whereas the runtime variants
are run within a specific context, but I think that that's stretching
things. However, static used with static if, static foreach, and static
assert seems to be very easy for people to understand, whereas some of the
other ways it's used often cause confusion at first. Certainly, it seems to
be far less confusing for folks than using enum for manifest constants has
been.

> Of course "static if" doesn't sound bad at all, it somehow
> conveys the idea of what it actually does. My confusion was
> regarding the fact that "static" is also used for other things
> (the ones you described) and then I would also expect that, to
> define a compile-time value, I would use the same keyword again,
> like
>
> static myCompileTimeValue = 5 * 2;
>
> instead of
>
> enum myCompileTimeValue = 5 * 2;
>
> of course this wouldn't be possible with the keyword "static",
> since `static val = 4;` would have a totally different meaning in
> the language, and that's why "enum" is used I guess. But then why
> not `enum if (...) { ... }`? Again, forget about the keywords
> themselves, I'm just talking about using the same one which is
> different from keywords that also do other different (or
> completely different, or slightly different, but still different)
> things. I get that "enum" has somewhat of a sense, when doing
> `enum val = 4;`, after reading the related book chapter, but
> yeah... that's not the problem, as I hope you now understood what
> I mean.

Using enum instead of static in contexts such as static if would be using
enum in a drastically different context from where enum is normally used
(the issue of manifest constants already causes a fair bit of confusion),
whereas static seems fairly natural there, and folks are used to static
meaning multiple things. In both C/C++ and D, static gets used in multiple
contexts where most folks would think that they were completely different
when in fact it's possible to come up with a definition that covers most or
all of the contexts in which it's used. So, regardless of whether static is
actually used consistently, it doesn't feel consistent. So, reusing it for
static if is likely to seem much more reasonable to many folks, whereas I
think that relatively few would think that reusing enum for that would have
made sense. But language design is a bit of an art. It's an interesting
combination of doing what makes sense from the standpoint of the compiler
writer and what makes sense from the standpoint of the programmer using the
language.

> This argument I started was kind of a first-impression as a
> newcomer to the language, with the hope of getting to better
> understand it. Also I thought it's beneficial for the community
> to have feedback from new users.

Constructive feedback is always welcome. And even if nothing in the language
gets changed because of feedback, it does help us understand where people
need help learning the language.

- Jonathan M Davis



Re: Confusion/trying to understand CTFE keywords

2018-06-04 Thread gdelazzari via Digitalmars-d-learn

On Monday, 4 June 2018 at 03:18:05 UTC, Jonathan M Davis wrote:


I think that part of your problem here comes from the fact that 
you think of enum or static are "CTFE keywords." That's not 
what they are at all. Yes, they can trigger CTFE, but they're 
not the only way.


...


Thank you very much for the extensive explanation, I really 
appreciate it. I'm slowly getting the point here, also by reading 
the relevant parts of the book you linked.


I was aware of the meaning of the static keyword (coming from 
other languages where it has similar meaning), but your re-cap 
was great anyway since I now have a clear view of how exactly 
works in D with the various features of the language.


So, while static _seems_ somewhat inconsistent at first, the 
way it's used is pretty consistent overall. The main 
inconsistency is the places where static is essentially 
implicit rather than explicit (such as module-level variables 
or structs nested in other structs or classes).


I'm not getting this however. I mean, sure, it's totally 
consistent if you consider the cases you described, but what I 
meant is that in a piece of code like


static if (a == 3)
{
  // stuff...
}
static else if (a == 2)
{
  // other stuff...
}
else
{
  // etc...
}

the "static" keyword has a different meaning, in this case it 
means that the if gets evaluated at compile time. This is the 
kind of inconsistency I was talking about.


Of course "static if" doesn't sound bad at all, it somehow 
conveys the idea of what it actually does. My confusion was 
regarding the fact that "static" is also used for other things 
(the ones you described) and then I would also expect that, to 
define a compile-time value, I would use the same keyword again, 
like


static myCompileTimeValue = 5 * 2;

instead of

enum myCompileTimeValue = 5 * 2;

of course this wouldn't be possible with the keyword "static", 
since `static val = 4;` would have a totally different meaning in 
the language, and that's why "enum" is used I guess. But then why 
not `enum if (...) { ... }`? Again, forget about the keywords 
themselves, I'm just talking about using the same one which is 
different from keywords that also do other different (or 
completely different, or slightly different, but still different) 
things. I get that "enum" has somewhat of a sense, when doing 
`enum val = 4;`, after reading the related book chapter, but 
yeah... that's not the problem, as I hope you now understood what 
I mean.



If you haven't yet, I'd suggest reading

http://ddili.org/ders/d.en/index.html

Even if you understand most of the content already, it will 
probably help fill in some of the holes you have in your 
understanding, and depending on how much you've done with D, it 
may contain quite a bit of new content that will help you out.


- Jonathan M Davis


Again, thank you very much for the time you took to answer with 
that amount of quality information, I really appreciate it. And I 
also appreciate the suggestion about the book, which I'll read as 
soon as I can. Maybe I'm missing somewhat of a broader view of 
the language that, once acquired, will make me understand the 
real meanings/reasons behind those keywords.


This argument I started was kind of a first-impression as a 
newcomer to the language, with the hope of getting to better 
understand it. Also I thought it's beneficial for the community 
to have feedback from new users.


Thank you very much again,
Giacomo




Re: Confusion/trying to understand CTFE keywords

2018-06-03 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, June 03, 2018 21:32:06 gdelazzari via Digitalmars-d-learn wrote:
> Hello everyone, I'm new here on the forum but I've been exploring
> D for quite a while. I'm not an expert programmer by any means,
> so this one may be a really silly question and, in that case,
> please forgive me.
>
> With the premise that I've still not looked a lot into "complex"
> compile time "stuff" (whether it's templates, CTFE, compile-time
> constants, etc...), so that may be the reason I may be missing
> the point... I'm trying to understand why keywords such as
> "static" or "enum" are used to denote compile time "things". What
> I mean is that those keywords are also used for other purposes,
> so I find it a bit confusing. Couldn't a keyword like "ctfe"
> (just making it up right now) exist? So that, when seeing
> something like
>
> ctfe myNumber = 5;
>
> ctfe if (myNumber + 2 == 7)
> {
>// ...
> }
>
> one could immediately understand that the code is
> executed/evaluated at compile time. True, after someone knows
> that "static" and "enum" mean (in the above example) that some
> compile-time things are happening, it's fine. I just find it a
> bit confusing not having a dedicated keyword but re-using
> existing ones that also serve other purposes...
>
> Note that this is not an attack to the language or anything (I
> actually really love it), I'm just trying to understand the
> reasoning behind this choice.
>
> Thank you very much in advance.

I think that part of your problem here comes from the fact that you think of
enum or static are "CTFE keywords." That's not what they are at all. Yes,
they can trigger CTFE, but they're not the only way.

Given how CTFE works in D, it really wouldn't make sense to have a keyword
for it. CTFE is simply what kicks in when you have an expression that _must_
be evaluated at compile time. e.g.

enum a = 42;

enum Foo
{
a = 42,
b = 92
c = 12
}

struct S
{
int i = 9;
}

all are cases where CTFE is used, because all of them require that the value
be known at compile time. In the example, they're just integers, so no
functions are called, but any one of them could be initialized with an
expression that involved calling a function. e.g.

struct S
{
int i = foo() + 7;
}

There is no special keyword here, and there is no need for one. By the
language's design, if i is directly initialized, its value must be known at
compile time, and so any expression that's used to directly initialize it
must be evaluated at compile time. The same goes for enums or static
variables. How would you expect something like this to even work with a
special keyword for CTFE?

Now, the fact that enum was used for manifest constants such as

enum foo = "hello";

in addition to actual enums such as

enum Color
{
red,
green,
blue,
orange,
yellow
}

is arguably unnecessary and confusing (and as some of the other posts in
this thread mention, this was done to avoid adding a new keyword). So,
maybe, we should have had something like

manifest foo = "hello";

and made

enum foo = "hello";

illegal, but even if we had done something like that, it would not have had
any effect on how CTFE works. It would have just clarified the difference
between manifest constants and proper enums. As for why enum was reused for
manifest constants, it was not only to save a keyword but because they
bascially act like anonymous enums (and in fact, that's what the spec calls
them) in that how they act is exactly like enums except for the fact that
they don't declare a new type. So, whether it would have been better to use
a new keyword is a matter of debate.

As for static, most of what it does is inherited from C/C++ and Java, and
while does get used in several contexts, it's actually used quite
consistantly, much as it might not seem that way at first.

When talking about a static variable, the key difference between a static
variable and an enum (be it a manifest constant or an actual enum) is that a
static variable is an actual variable with a location in memory, whereas an
enum is just a value that you can refer to by name. The value of the enum is
basically copy-pasted wherever it it is used. It's not legal to take the
address of an enum, and in fact, that means that if you do something like

enum arr = [1, 2, 3];

then every time you use arr, you're potentially allocating a new dynamic
array, because foo(arr) is the same as foo([1, 2, 3]) except for two things:

1. If you change the value of arr, it changes its value everywhere, wheres
if you use [1, 2, 3] directly, you'd have to change every place that you
used it if you wanted to change it.

2. The value of arr is copied, not the expression used to initialize it. So,
if you had

enum arr = [1, 2, bar()];

and bar() resulted in 42, then foo(arr) would be the same as foo([1, 2, 42])
and not foo([1, 2, bar()]).

However, static variables are actually variables. The key difference between
them and other variables at the same scope is that 

Re: Confusion/trying to understand CTFE keywords

2018-06-03 Thread Dave Jones via Digitalmars-d-learn

On Sunday, 3 June 2018 at 21:32:06 UTC, gdelazzari wrote:


Note that this is not an attack to the language or anything (I 
actually really love it), I'm just trying to understand the 
reasoning behind this choice.


Because they have a thing about not adding new keywords, 
apparently it's more important that people dont lose a word they 
can use for a variable name than it is for expressive non context 
dependent keywords.









Re: Confusion/trying to understand CTFE keywords

2018-06-03 Thread Computermatronic via Digitalmars-d-learn

On Sunday, 3 June 2018 at 21:32:06 UTC, gdelazzari wrote:
I'm trying to understand why
keywords such as "static" or "enum" are used to denote compile 
time "things". What I mean is that those keywords are also used 
for other purposes, so I find it a bit confusing. Couldn't a 
keyword like "ctfe" (just making it up right now) exist?


I believe the enum was chosen over a dedicated keyword for 
compile-time constants to prevent adding another keyword, as D 
already has quite a few.


Confusion/trying to understand CTFE keywords

2018-06-03 Thread gdelazzari via Digitalmars-d-learn
Hello everyone, I'm new here on the forum but I've been exploring 
D for quite a while. I'm not an expert programmer by any means, 
so this one may be a really silly question and, in that case, 
please forgive me.


With the premise that I've still not looked a lot into "complex" 
compile time "stuff" (whether it's templates, CTFE, compile-time 
constants, etc...), so that may be the reason I may be missing 
the point... I'm trying to understand why keywords such as 
"static" or "enum" are used to denote compile time "things". What 
I mean is that those keywords are also used for other purposes, 
so I find it a bit confusing. Couldn't a keyword like "ctfe" 
(just making it up right now) exist? So that, when seeing 
something like


ctfe myNumber = 5;

ctfe if (myNumber + 2 == 7)
{
  // ...
}

one could immediately understand that the code is 
executed/evaluated at compile time. True, after someone knows 
that "static" and "enum" mean (in the above example) that some 
compile-time things are happening, it's fine. I just find it a 
bit confusing not having a dedicated keyword but re-using 
existing ones that also serve other purposes...


Note that this is not an attack to the language or anything (I 
actually really love it), I'm just trying to understand the 
reasoning behind this choice.


Thank you very much in advance.