new annotation or pragma to mark functions that are intended to be only used during compile time
Hipreme
msnmancini at hotmail.com
Sun Feb 23 17:57:58 UTC 2025
On Sunday, 23 February 2025 at 17:07:30 UTC, Ilya wrote:
> On Friday, 21 February 2025 at 14:04:41 UTC, Steven
> Schveighoffer wrote:
>> Paul Backus pointed out on discord, there is a very large
>> problem with this mechanism:
>>
>> importing a file with a function that is not a template nor an
>> auto function means the semantic is skipped for that function.
>> This means it would be impossible to know that this function
>> is ctfe-only. The only other solution there is to semantic
>> every function, which basically negates any wins we get from
>> not optimizing these functions.
>
> Yes, that's a good point, thanks.
>
>> So reading all the responses here, my impression is:
>>
>> 1. I think it's a necessary idea to have an attribute if we
>> want this feature. I like using `@__ctfe` as this requires no
>> new syntax, and actually already compiles (it just doesn't do
>> the thing expected). What remains to be seen is if we can hook
>> this properly. `@__ctfe` becomes `@(true)` currently. If not,
>> then a new attribute is trivial to add to core.attributes.
>
> I've already updated our internal version to use `@__ctfe`, it
> works just fine.
>
>> 2. If we are going to have a mechanism to flag that code
>> generation should be avoided, it would be good to also do this
>> for functions that begin with `assert(__ctfe)`. This at least
>> helps with existing uses of that mechanism.
>
> As I said in another reply, I think it can't (and shouldn't) be
> a plugin replacement for `assert(__ctfe)`. But we can do a
> small migration tool.
>
>> 3. I don't agree with the compiler errors for all uses of
>> ctfe-only functions at runtime. As you pointed out, this can
>> be valid for cases. I don't think it's worth the headache, and
>> I have learned in the past not to pre-optimize for rule
>> following especially in generic code. Just let the thing
>> happen as it would.
>
> Oh, so you are saying we will have to add an attribute (because
> of compiler implementation reasons), but we'll make it work as
> if it's an `assert(__ctfe)` in the first line anyway?
>
> I don't agree here. Static check allows us to simply drop these
> functions, without having to rewrite call sites, it plugs
> naturally into existing `skipCodegen` implementation and it
> provides faster feedback, helping to set the attributes
> correctly. It also lets dropping more functions, think
> templates. If you use `map!ctonly(xs)`, there is no point to
> codegen `MapResult!(ctonly, xs).front` for example.
>
> The check will reject some code that could be written with
> asserts, that's correct. But I don't see it as a problem. It's
> like static vs dynamic types. You can't put a string into an
> int in a typed language, but in Python you can. Does it make
> typed languages worse? I'm not sure.
>
> Since we are adding a new annotation, let's make it right. Such
> that we are absolutely sure we can omit the codegen and no
> surprises will happen in run time. And if someone wants to have
> a contrived behavior, like the one in my example, they are
> welcome to continue using asserts. We are not going to
> deprecate `assert(__ctfe)`, right?
>
>> 4. To that end, calling a known ctfe-only function should
>> result in an appropriate `assert(false, "cannot call ctfe-only
>> function blahblah at runtime")` when doing code generation
>> instead of the call to a non-existent function that has a
>> linker error.
>
> I honestly prefer a linker error over a run-time assert :)
> Sounds like a time bomb.
There are people out there which can't read linker errors,
contrary to that, I believe that an advanced feature anyway. To
be fair, nowadays, I understand them enough for that. Maybe we
could implement that behavior of no-codegen vs a stub with
assert(false) with the same strategy as `-check=`.
Since assert(`__ctfe`) is existing code, I would say that,
implementations that skip codegen because of `assert(__ctfe)`, we
could instead, we could do like `-ctfeskip=stub` and
`-ctfeskip=yes` or something like that.
While `@__ctfe` would altogether trigger the same behavior as no
codegen at all, like `-ctfeskip=yes`.
That would bring:
1. More control to one which understand what they're doing by
using either `@__ctfe` and `-ctfeskip=yes`.
2. Benefits existing code
3. Avoid breaking existing code since the default could be using
the stub.
More information about the dip.ideas
mailing list