<HTML>
To follow up on this, even if you rewrote the function to use a multiplicative formula (faster to compute overall):<br>
<div><br>
</div><div><span style="font-family: Courier New;"><span style="font-weight: bold;">function</span> Binomial(n, r: Cardinal): Cardinal; <span style="font-weight: bold;">pure</span>;</span></div><div><span style="font-family: Courier New; font-weight: bold;">var</span></div><div><span style="font-family: Courier New;">  c: Cardinal;<br>
</span></div><div><span style="font-family: Courier New;"><span style="font-weight: bold;">begin</span><br>
  <span style="font-weight: bold;">for </span>(r > n) <span style="font-weight: bold;">then</span><br>
    Result := 0<br>
  <span style="font-weight: bold;">else<br>
    begin</span><br>
      Result := 1;<br>
      <span style="font-weight: bold;">if</span> n <> r <span style="font-weight: bold;">then</span><br>
</span></div><div><span style="font-family: Courier New;">        <span style="font-weight: bold;">begin</span><br>
</span></div><div><span style="font-family: Courier New;">          Inc(n); { Only "n + 1" appears in the formula }<br>
          <span style="font-weight: bold;">for </span>c := 1 <span style="font-weight: bold;">to</span> r <span style="font-weight: bold;">do</span>            <span style="font-weight: bold;"><br>
</span></span></div><div><span style="font-family: Courier New;">            Result := (Result * (n - c)) <span style="font-weight: bold;">div</span> c; { Make sure the multiplication is evaluated first }<br>
</span></div><div><span style="font-family: Courier New; font-weight: bold;"><br>
</span></div><span style="font-family: Courier New; font-weight: bold;">        end;<br>
</span><div><span style="font-family: Courier New; font-weight: bold;">    end;<br>
</span></div><div><span style="font-family: Courier New;"><span style="font-weight: bold;">end</span>;<br>
</span><br>
I'm not saying it's impossible, but that's certainly slightly harder to propagate a constant through that, even with manual programmer optimisations like with Inc(n).<br>
<br>
Gareth aka. Kit<br>
</div> <br>
<br>
<span style="font-weight: bold;">On Sun 22/07/18 05:15 , "J. Gareth Moreton" gareth@moreton-family.com sent:<br>
</span><blockquote style="BORDER-LEFT: #F5F5F5 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT:0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px"> 
<div>Sorry for that mess of a formatting on the code sample, Here is a much nicer version!</div><div><br>
 
</div><div><span style="font-family: Courier New;"><span style="font-weight: bold;">function</span> Binomial(n, r: Cardinal): Cardinal; <span style="font-weight: bold;">pure</span>;</span></div><div><span style="font-family: Courier New;"><span style="font-weight: bold;">begin</span><br>
 
  <span style="font-weight: bold;">if </span>(r > n) <span style="font-weight: bold;">then</span><br>
 
    Result := 0<br>
 
  <span style="font-weight: bold;">else if </span>(r = n) <span style="font-weight: bold;">then</span><br>
 
    Result := 1 { Faster than calculating the factorials }<br>
 
  <span style="font-weight: bold;">else</span><br>
 
    Result := Factorial(n) <span style="font-weight: bold;">div </span>(Factorial(r) * Factorial(n - r));<br>
 
<span style="font-weight: bold;">end</span>;<br>
 
</span><br>
 
Gareth aka. Kit<br>
 
</div> <br>
 
<br>
 
<span style="font-weight: bold;">On Sun 22/07/18 05:03 , "J. Gareth Moreton" gareth@moreton-family.com sent:<br>
 
</span><blockquote style="BORDER-LEFT: #F5F5F5 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT: 0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">An interesting read. If you can collapse an inline function into a single 
<br>
 
 
assignment in most situations, then brilliant! Definitely keep that optimisation in. 
<br>
 
 
 
<br>
 
 
While there are many similarities and prerequisites between an inline function 
<br>
 
 
and a pure function, and many simple mathematical functions could easily carry 
<br>
 
 
both modifiers, they are not exactly the same. Pure functions cannot be 
<br>
 
 
evaluated at compile time if one of the arguments is a variable (or at the very 
<br>
 
 
least, not deterministic), but it might be inlined, while a function with 
<br>
 
 
recursion can't be reliably inlined, but might still be pure (e.g. factorial, 
<br>
 
 
assuming you don't rewrite it to use a for-loop), and not all recursive functions 
<br>
 
 
can be rewritten to use simpler loops (e.g. the infamous Ackermann function). It 
<br>
 
 
is true though... proper constant propagation would cover most situations, even 
<br>
 
 
when an inline function calls another inline function such as Max, although there 
<br>
 
 
might still be issues in exceptional conditions (e.g. division by zero or trying 
<br>
 
 
to calculate tan(pi/2), for example). 
<br>
 
 
 
<br>
 
 
The other point with a "pure" modifier is that, assuming the compiler determines 
<br>
 
 
that the function is indeed pure, it would permit their assignment to a constant. 
<br>
 
 
 True, you could replace the constant with the function call whenever it appears, 
<br>
 
 
but that's not exactly good coding practice. And that's sort of the other reason 
<br>
 
 
for the "pure" modifier. If you release a library of functions that a 
<br>
 
 
third-party then looks at, with no background knowledge of its inner workings, 
<br>
 
 
the appearance of the "pure" modifier would quickly clue them in in regards to 
<br>
 
 
the functions' intent. 
<br>
 
 
 
<br>
 
 
The final issue is that while a function might be pure, you might not want to 
<br>
 
 
inline it because of its complexity, especially if it's called multiple times 
<br>
 
 
with variable arguments. The simplest example I can think of is the two-argument 
<br>
 
 
binomial coefficient: 
<br>
 
 
 
<br>
 
 
function Binomial(n, r: Cardinal): Cardinal; pure; 
<br>
 
 
begin 
<br>
 
 
 if (r > n) then 
<br>
 
 
 Result := 0 
<br>
 
 
 else if (r = n) then 
<br>
 
 
 Result := 1 { Faster than calculating the factorials } 
<br>
 
 
 else 
<br>
 
 
 Result := Factorial(n) div (Factorial(r) * Factorial(n - r)); 
<br>
 
 
end; 
<br>
 
 
 
<br>
 
 
The alternative versions either require recursion, or for exceptionally large 
<br>
 
 
values of n and r, calculating the integral that defines the gamma function. 
<br>
 
 
 
<br>
 
 
Gareth aka. Kit 
<br>
 
 
 
<br>
 
 
 
<br>
 
 
On Sat 21/07/18 18:51 , Sven Barth via fpc-devel <a href="mailto:fpc-devel@lists.freepascal.org">fpc-devel@lists.freepascal.org</a> sent: 
<br>
 
 
<span style="color: rgb(102, 102, 102);">> Martok schrieb am Sa., 21. Juli 2018, 17:12: 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> Am 21.07.2018 um 02:08 schrieb Sven Barth via fpc-devel: 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> > The main problem is that not all functions that would be eligible for 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> your 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> > approach are also declared as inline thus their node trees would not be 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> stored 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> > inside the PPU and thus you could not work with them. 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> I'm not sure I understand. Isn't the same true, with a new feature? The 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> full 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> node tree must be available, which basically means "has inlineinfo". 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> Doesn't it? 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> Correct.  
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> > Additional benefit of the "pure" modifier: the compiler can check once 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> the 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> > method has been parsed whether it's pure or not and can thus error out 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> in the 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> > latter case. 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> That is true, it is a more explicit declaration of intent. 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> Maybe the codegen of pure can simply be implemented as generating inline 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> info, 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> but always replacing the calls with the simplified version. If it is 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> already 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> known that a function is pure, what I did with constexpr() would basically 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> be 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> guaranteed to work. 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> Pure functions would still have an ordinary generated body as there is no 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> reason that their address shouldn't be able to be taken (otherwise one 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> needs to declare wrappers for them). Other than that I personally favor the 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> explicit declaration of intent for such functions without the need for a 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> ConstExpr intrinsic.  
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> Regards, Sven  _______________________________________________ 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> fpc-devel maillist - <a href="mailto:fpc-devel@lists.freepascal.org">fpc-devel@lists.freepascal.org</a> 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> <a target="_blank" href="<a href=" http:="" lists.freepascal.org="" cgi-bin="" mailman="" listinfo="" fpc-devel"="">http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel</a>"><span style="color: red;">http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel</span> [1] 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> Links: 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> ------ 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> [1] 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> <a target="_blank" %3fredirect%3dhttp:="" lists.freepascal.org"="">http://secureweb.fast.net.uk/parse.php%3Fredirect%3D<a href="http://lists.freepascal.org">http://lists.freepascal.org</a></a>"><span style="color: red;">http://secureweb.fast.net.uk/parse.php?redirect=<a href="http://lists.freepascal.org">http://lists.freepascal.org</a></span> 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> /cgi-bin/mailman/listinfo/fpc-devel 
</span><br>
 
 
<span style="color: rgb(102, 102, 102);">> 
</span><br>
 
 
 
<br>
 
 
_______________________________________________ 
<br>
 
 
fpc-devel maillist - <a href="mailto:fpc-devel@lists.freepascal.org">fpc-devel@lists.freepascal.org</a> 
<br>
 
 
<a target="_blank" href="<a href=" http:="" lists.freepascal.org="" cgi-bin="" mailman="" listinfo="" fpc-devel"="">http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel</a>"><span style="color: red;">http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel</span> 
<br>
 
 
<br>
 
 
<br>
 
 
</blockquote> 

_______________________________________________<br>

fpc-devel maillist  -  <a href="mailto:fpc-devel@lists.freepascal.org">fpc-devel@lists.freepascal.org</a><br>

<a target="_blank" href="<a href="http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel">http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel</a>"><span style="color: red;">http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel</span></a><br>

<br>

</blockquote></HTML>