[fpc-devel] Compile time functions
J. Gareth Moreton
gareth at moreton-family.com
Sun Jul 22 18:05:19 CEST 2018
On Sun 22/07/18 14:57 , Martok
listbox at martoks-place.de sent:
> Am 22.07.2018 um 06:03 schrieb J. Gareth
Moreton:
>
> > Pure functions cannot be
>
> > evaluated at compile time if one of
the
> arguments is a variable (or at the very
> > least, not deterministic)
>
> Do you have an idea how to prove that
yet? The way I see it now, this is
> the
> only hard issue, every other component
is already present somewhere in some
> form.
This one is quite simple really. If what
you are passing into the function is
neither a constant nor a literal number,
then it is called like a regular function
with no hint or warning. If all the actual
parameters are constant, then the compiler
will attempt to evaluate it there and then
and replace the call with the result.
>
>
> > although there
>
> > might still be issues in exceptional
conditions
> (e.g. division by zero or trying
> > to calculate tan(pi/2), for example).
>
> Good point - what should happen in that
case?
>
> const
>
> x = Pi / 0;
>
> begin
>
> writeln(x);
>
> end.
>
> That writes "+Inf".
>
>
For integer division and explicit raise
statements, I plan to return a compile-
time error. With floating point, I'm
considering returning the relevant special
representations, since there are
constructs such as "const NaN = 0.0 /
0.0;", which in the mathematical sense is
a pure function. I'm not certain what
tan(Pi/2) returns, but going by the
identity tan = sin/cos, it would be +inf.
>
> > The other point with a "pure" modifier
> is that, assuming the compiler
determines
> > that the function is indeed pure, it
would
> permit their assignment to a constant.
> So: on processing a call to a pure
function,
>
> if arguments are constant, emit
(interpreted) result of function
>
> otherwise, emit regular call
>
> ?
>
> What would error/warning cases be? I'd
want to avoid a situation like that
> with
> the insightful, but unfixable and thus
spammy "06058_N_Call to
> subroutine "$1"
> marked as inline is not inlined"
message.
My plan with pure functions is that if the
compiler spots something that makes the
function impure, it returns a warning and
sets a flag to say it's ineligible, so it
won't attempt any further compile-time
evaluation. Unlike inline, which has
fairly arbitrary restrictions, the
definition of a pure function is fairly
concise and easy to understand. Triggering
the warning is usually the sign of a bug,
either in the function itself or has no
business being marked as pure (because it
reads from a file, for example). The
compiler might spot the function's
impurity during node construction or
during evaluation (the latter would
generally only happen if it suspects an
infinite loop and the like).
For the constant assignment, it will
return the error that is already thrown if
you try to assign a function result to a
constant. If the compiler only notices the
function's impurity while attempting to
evaluate the result for this assignment,
it will first throw the warning, then the
error.
>
>
> > The final issue is that while a
function might
> be pure, you might not want to
> > inline it because of its complexity,
especially
> if it's called multiple times
> > with variable arguments.
>
> That is very true. Should the
"interpretation complexity" be
> limited, or should
> the compiler keep going and maybe run
into a stack overflow?
>
>
>
>
>
> --
>
> Regards,
>
> Martok
>
>
This is actually why I keep bringing up
the Ackermann function as a test case, to
see how the compiler responds to extreme
situations, because there is no general
solution to determine if a function
actually completes (Turing's halting
problem)... then again, Ackermann's
function actually does complete - it just
takes a prohibitively long time for large
inputs.
To get around this, I'm considering a
limit of 4096 nodes that the compiler will
step through, and a stack depth limit of
64, before deciding that it's an infinite
loop or otherwise too complex to be pure,
and mark it as ineligible (and to stop the
compiler from crashing or taking longer
than the age of the Universe to build the
project). This would otherwise be the only
arbitrary restriction on pure functions
that can't easily be fixed, but you would
have to try quite hard to trigger it and
is more likely a bug such as an actual
infinite loop.
Thanks for the questions, Martok.
Gareth aka. Kit
More information about the fpc-devel
mailing list