October 01, 2012
On Monday, 1 October 2012 at 20:30:26 UTC, Tommi wrote:
> It's a lot less work to add one attribute to your function once, than to write something extra every time you call that function.

string exclaim(string v)() {
  return v ~ "!";
}

void main() {
  writeln(exclaim!("howdy"));
}

Graham

October 01, 2012
On Monday, 1 October 2012 at 20:33:29 UTC, Graham Fawcett wrote:
> string exclaim(string v)() {
>   return v ~ "!";
> }
>
> void main() {
>   writeln(exclaim!("howdy"));
> }

It doesn't scale well to have to write both compile-time and run-time versions of your functions.
October 01, 2012
On Mon, 01 Oct 2012 16:23:17 -0400, Tommi <tommitissari@hotmail.com> wrote:

> On Monday, 1 October 2012 at 20:16:09 UTC, Steven Schveighoffer wrote:
>> We already have that, use templates:
>>
>> private auto _funimpl(string s) {
>> /* what was previously in fun(string) */
>> }
>>
>> template fun(string s)
>> {
>>    enum fun = _funimpl(s);
>> }
>>
>> // usage:
>>
>> fun!("times"); // always executes _funimpl at compile time
>
> Yes, I know. And this helps even more:
>
> template ct(alias expr)
> {
>       enum ct = expr;
> }
>
> auto fun(string s)
> {
>       ...
> }
>
> // usage:
>
> ct!(fun("times"))
>
> But that's still a nuisance.

Hm... I was focusing on changing fun("times") into fun!("times") in order to make it always execute at compile time.  I think that is not so bad.

The idea is that _funimpl is implementation details for fun, and doesn't ever expect to be called at runtime.  In fact, you could do if(!_ctfe) throw Error();

-Steve
October 01, 2012
On Monday, 1 October 2012 at 20:41:53 UTC, Tommi wrote:
> On Monday, 1 October 2012 at 20:33:29 UTC, Graham Fawcett wrote:
>> string exclaim(string v)() {
>>  return v ~ "!";
>> }
>>
>> void main() {
>>  writeln(exclaim!("howdy"));
>> }
>
> It doesn't scale well to have to write both compile-time and run-time versions of your functions.

And how is your proposed @force_ctfe attribute going to solve this issue? If you're forcing CTFE, by definition you don't have runtime support.

As you clearly know, D already supports functions that can run at compile-time and run-time: that's the whole point of of CTFE.

Graham



October 01, 2012
On Monday, 1 October 2012 at 21:15:40 UTC, Graham Fawcett wrote:
> And how is your proposed @force_ctfe attribute going to solve this issue? If you're forcing CTFE, by definition you don't have runtime support.

Maybe the name @force_ctfe is misleading. But, like I said: "the attribute @asdf would make it so that the function is guaranteed to execute at compile-time when its arguments are compile-time constants". Never do I say that the attribute would prevent run-time evaluation. The function would behave just like constexpr functions do in c++ (although, in c++ what those functions can actually do is much more limited).
October 01, 2012
On Monday, October 01, 2012 23:15:55 Graham Fawcett wrote:
> On Monday, 1 October 2012 at 20:41:53 UTC, Tommi wrote:
> > On Monday, 1 October 2012 at 20:33:29 UTC, Graham Fawcett wrote:
> >> string exclaim(string v)() {
> >> 
> >> return v ~ "!";
> >> 
> >> }
> >> 
> >> void main() {
> >> 
> >> writeln(exclaim!("howdy"));
> >> 
> >> }
> > 
> > It doesn't scale well to have to write both compile-time and run-time versions of your functions.
> 
> And how is your proposed @force_ctfe attribute going to solve this issue? If you're forcing CTFE, by definition you don't have runtime support.
> 
> As you clearly know, D already supports functions that can run at compile-time and run-time: that's the whole point of of CTFE.

If I understand correctly, what he wants is for CTFE to be forced only in cases where all of the arguments are known at compile time (e.g. when you pass a string literal), so it wouldn't prevent anything from running at runtime.

This would be a complete disaster if it were done in the general case. For instance, writeln("hello") can't be executed at compile time, and since the only way for the compiler to know that in most cases is to run the function, compile times would tank and probably cause other entertaining issues. So, a compiler flag like was previously suggested in this thread would be a _very_ bad idea.

On the other hand, if a function attribute were introduced where the programmer indicated that they wanted that function to execute at compile time as long as all of the arguments were known at compile time, that would work just fine (as long as it really _could_ be executed at compile time - but we already have that issue when assigning the results of functions to enums). The question is whether it's worth adding such an attribute to the language, and clearly, most of us think that explicitly using enum suffices whereas Tommi wants such a function attribute.

- Jonathan M Davis
October 01, 2012
On Monday, 1 October 2012 at 21:29:33 UTC, Tommi wrote:
> Maybe the name @force_ctfe is misleading. But, like I said: "the attribute @asdf would make it so that the function is guaranteed to execute at compile-time when its arguments are compile-time constants".

Oh, wait. Now I understand why that sentence is misleading. It should be:

The function attribute @asdf would guarantee compile-time evaluation of all such calls to that function, where all arguments (that you pass into the function), of which the function's output depends on, are compile-time evaluable.


October 01, 2012
On Monday, 1 October 2012 at 21:35:16 UTC, Jonathan M Davis wrote:
> The question is whether it's worth adding such an attribute to
> the language, and clearly, most of us think that explicitly
> using enum suffices whereas Tommi wants such a function
> attribute.

You'd get simpler syntax at the cost of just one lousy new keyword. It's a once in a life time deal! Any takers?

October 01, 2012
On Monday, October 01, 2012 23:55:11 Tommi wrote:
> On Monday, 1 October 2012 at 21:35:16 UTC, Jonathan M Davis wrote:
> > The question is whether it's worth adding such an attribute to the language, and clearly, most of us think that explicitly using enum suffices whereas Tommi wants such a function attribute.
> 
> You'd get simpler syntax at the cost of just one lousy new keyword. It's a once in a life time deal! Any takers?

Keywords are considered to be incredibly expensive. Being able to use a name starting with @ rather than a keyword does reduce the cost, but you're still going to have to drive a very hard bargain to talk Walter into adding anything like that to the language at this point. Adding much of _anything_ to the language is generally considered expensive.

- Jonathan M Davis
October 01, 2012
On 10/01/2012 08:02 PM, foobar wrote:
> On Monday, 1 October 2012 at 17:46:00 UTC, Tommi wrote:
>> On Monday, 1 October 2012 at 08:04:49 UTC, Jonathan M Davis wrote:
>>> And you _can't_ determine ahead of time which functions can be safely
>>> executed at compile time either, because that's an
>>> instance of the halting problem.
>>
>> I don't understand (I did read what "halting problem" means just now,
>> but I still don't understand). If there was no __ctfe variable, and
>> thus a guarantee that all functions do the same thing at compile-time
>> and run-time, couldn't the compiler just try aggressively to execute
>> all function calls at compile-time? Obviously it wouldn't bother
>> trying CTFE for function calls that had arguments which weren't
>> evaluable at compile-time. Nor would it bother with functions that it
>> knows have memory allocations or other limitations of CTFE.
>>
>> If not a compiler flag, then it could be a function attribute. Just
>> like c++ function attribute constexpr, which guarantees that the
>> function executes at compile time given you provide it with
>> compile-time evaluable arguments (and there are limitations to what
>> the function can do). Why wouldn't this attribute be possible with D?
>
> __ctfe is a horrible yet very useful hack to address the underlying
> issue - the execution model for CTFE, which I personally do not agree
> with. Adding a compiler flag for the existing model, makes no sense
> whatsoever. Functions are essentially a run-time abstraction and the
> compiler generally speaking has no business trying to execute them at
> compile-time. The compiler is after all *not* an interpreter.
>

A D compiler is also a D interpreter. I wouldn't even bother with D if this wasn't the case.

> Besides, what would be the use case for such a flag anyway? If you
> already know that all parameters are known at compile-time, you can
> already "tell" the compiler to execute the function by assigning to a
> static/enum variable.
>
> IMO, this mixing of code for various stages of execution is bad design
> but this cannot be changed in a backwards compatible way.