<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>No-one said this would be an easy feature to implement.  This
      might be a step-by-step process, starting with simple function
      calls and building up to complex constant assignment. 
      Nevertheless, at least initially, I would prefer to avoid the
      creation of a pure function that deals with a pointer in any way,
      including objects, since their values or successful creation (e.g.
      out of memory errors or the calling of "Fail") cannot be
      determined at design time.</p>
    <p>Still, looking at your example, there's nothing to say that those
      record methods cannot be made pure, since the records already
      exist by the time they're called.  If anything, that looks like a
      relatively good use case to go on.</p>
    <p>My initial complex use cases (after simple tests) will be the
      following:</p>
    <p><tt><b>function </b>Factorial(N: QWord): QWord; <b>pure</b>; <b>inline</b>;</tt><tt><br>
      </tt><b><tt>var</tt></b><tt><br>
      </tt><tt>  X: Integer;</tt><tt><br>
      </tt><b><tt>begin</tt></b><tt><br>
      </tt><tt>  Result := 1;</tt><tt><br>
      </tt><tt>  <b>if </b>N < 2 <b>then</b></tt><tt><br>
      </tt><tt>    Exit;</tt><tt><br>
      </tt><tt><br>
      </tt><tt>  <b>for </b>X := 2 <b>to </b>N <b>do</b></tt><tt><br>
      </tt><tt>    Result := Result * N;</tt><tt><br>
      </tt><tt><b>end</b>;</tt><tt><br>
      </tt><tt><br>
      </tt><tt><b>function </b>RecursiveFactorial(N: QWord): QWord; <b>pure</b>;
        <i>{ Cannot be inlined on account of the recursive call, but can
          be made pure }</i></tt><tt><br>
      </tt><b><tt>begin</tt></b><tt><br>
      </tt><tt>  <b>if </b>N < 2 <b>then</b></tt><tt><br>
      </tt><tt>  <b>begin</b></tt><tt><br>
      </tt><tt>    Result := 1;</tt><tt><br>
      </tt><tt>    Exit;</tt><tt><br>
      </tt><tt>  <b>end</b>;</tt><tt><br>
      </tt><tt><br>
      </tt><tt>  Result := Result * RecursiveFactorial(N - 1);</tt><tt><br>
      </tt><tt><b>end</b>;</tt><tt><br>
      </tt><tt><br>
      </tt><tt><b>function </b>RoughExp(X: Double): Double; <b>pure</b>;</tt><tt><br>
      </tt><b><tt>var</tt></b><tt><br>
      </tt><tt>  Count: Integer;</tt><tt><br>
      </tt><tt>  WorkingValue: Double;</tt><tt><br>
      </tt><b><tt>begin</tt></b><tt><br>
      </tt><tt>  <i>{ Calculate RoughExp(X) as e^X = 1 + X + X^2/2! +
          X^3/3! + ... + X^8/8! }</i></tt><tt><br>
      </tt><tt>  Result := Exponent;</tt><tt><br>
      </tt><tt><br>
      </tt><tt>  <b>for </b>Count := 2 <b>to </b>8 <b>do</b></tt><tt><br>
      </tt><tt>  <b>begin</b></tt><tt><br>
      </tt><tt>    X := X * Exponent; { Contains "X^Count" }</tt><tt><br>
      </tt><tt>    Result := Result + (X / RecursiveFactorial(Count));</tt><tt><br>
      </tt><tt>  <b>end</b>;</tt><tt><br>
      </tt><tt>end;</tt><tt><br>
      </tt><tt><br>
      </tt><tt><b>function </b>Bad(X: QWord): QWord; <b>pure</b>;</tt><tt><br>
      </tt><b><tt>begin</tt></b><tt><br>
      </tt><tt>  Result := 0;</tt><tt><br>
      </tt><tt>  <b>while </b>True <b>do</b></tt><tt><br>
      </tt><tt>    <i>{ Run forever }</i>;</tt><tt><br>
      </tt><tt><b>end</b>;</tt><tt><br>
      </tt><tt><br>
      </tt><b><tt>const</tt></b><tt><br>
      </tt><tt>  Factorial6 = Factorial(6);</tt><tt> <i>{ Should
          convert the function call into the immediate value 720 }</i><br>
      </tt><tt>  Factorial21 = Factorial(21); <i>{ Should return an
          error due to arithmetic overflow }</i></tt><tt><br>
      </tt><tt>  BigNumber = BadCount(0); <i>{ Should return an error
          upon realising it's in an infinite loop }</i></tt><tt><br>
      </tt><tt><br>
      </tt><tt>  RFactorial20: Double = 1 / Factorial(20); <i>{ Typed
          constant }</i></tt><tt><br>
      </tt><tt>  SqrtE = RoughExp(0.5); <i>{ This also tests compiler
          efficiency by remembering past results of RecursiveFactorial
          with identical inputs }</i></tt><tt><br>
      </tt><tt>  ESquared = RoughExp(2); <i>{ ... as does this one if a
          non-recursive factorial is used, due to the previous call to
          RoughExp(0.5) }</i></tt><tt><br>
      </tt></p>
    <p>I may ask you guys for more complex examples down the line.  This
      is something I really want to get working!</p>
    <p>Gareth aka. Kit</p>
    <p>P.S. Just to clarify... we happy with the directive being '<b>pure</b>'?<br>
    </p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 25/06/2019 06:20, Sven Barth via
      fpc-devel wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:5abd8901-63c1-89f4-83e8-6dc60cd5b389@googlemail.com">Am
      25.06.2019 um 06:20 schrieb Marģers . via fpc-devel:
      <br>
      <blockquote type="cite">  <br>
        ----- Reply to message -----
        <br>
        Subject: Re: [fpc-devel] XML node dump feature
        <br>
        Date: otrd., 25 jūn., 03:16
        <br>
        From:  Ben Grasset <a class="moz-txt-link-rfc2396E" href="mailto:operator97@gmail.com"><operator97@gmail.com></a>
        <br>
        To:  FPC developers' list
        <br>
        <a class="moz-txt-link-rfc2396E" href="mailto:fpc-devel@lists.freepascal.org"><fpc-devel@lists.freepascal.org></a>
        <br>
        <br>
        <blockquote type="cite">const
          <br>
             A: TVec3F = (X: 1.2; Y: 2.4; Z: 3.8);
          <br>
             B: TVec3F = (X: 2.1; Y: 4.2; Z: 8.3);
          <br>
             // You can't do the next part currently, obviously
          <br>
             C: TVec3F = A + B;
          <br>
             D: TVec3F = A - B;
          <br>
             E: TVec3F = A * B;
          <br>
             F: TVec3F = A / B;
          <br>
          <br>
        </blockquote>
        Sorry to say but, this should not work even with
        <br>
        *pure* function.  Typed constants are not truly
        <br>
        constants.
        <br>
      </blockquote>
      Correct. Though considering that we're talking about *compile
      time* the compiler *could* treat consts (in {$J-} mode) as
      constants if pure functions are involved... Though it would need a
      bit more work as currently the compiler is "simply" piping the
      constant values of typed constants into the output assembly.
      <br>
      <br>
      Regards,
      <br>
      Sven
      <br>
      _______________________________________________
      <br>
      fpc-devel maillist  -  <a class="moz-txt-link-abbreviated" href="mailto:fpc-devel@lists.freepascal.org">fpc-devel@lists.freepascal.org</a>
      <br>
      <a class="moz-txt-link-freetext" href="https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel">https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel</a>
      <br>
      <br>
      <br>
    </blockquote>
  <div id="DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2"><br />
<table style="border-top: 1px solid #D3D4DE;">
        <tr>
        <td style="width: 55px; padding-top: 13px;"><a href="https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient" target="_blank"><img src="https://ipmcdn.avast.com/images/icons/icon-envelope-tick-round-orange-animated-no-repeat-v1.gif" alt="" width="46" height="29" style="width: 46px; height: 29px;" /></a></td>
                <td style="width: 470px; padding-top: 12px; color: #41424e; font-size: 13px; font-family: Arial, Helvetica, sans-serif; line-height: 18px;">Virus-free. <a href="https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient" target="_blank" style="color: #4453ea;">www.avast.com</a>
                </td>
        </tr>
</table><a href="#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2" width="1" height="1"> </a></div></body>
</html>