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.

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.

My initial complex use cases (after simple tests) will be the following:

*function *Factorial(N: QWord): QWord; *pure*; *inline*;
*var*
  X: Integer;
*begin*
  Result := 1;
*if *N < 2 *then*
    Exit;

*for *X := 2 *to *N *do*
    Result := Result * N;
*end*;

*function *RecursiveFactorial(N: QWord): QWord; *pure*; /{ Cannot be inlined on account of the recursive call, but can be made pure }/
*begin*
*if *N < 2 *then*
*begin*
    Result := 1;
    Exit;
*end*;

  Result := Result * RecursiveFactorial(N - 1);
*end*;

*function *RoughExp(X: Double): Double; *pure*;
*var*
  Count: Integer;
  WorkingValue: Double;
*begin*
/{ Calculate RoughExp(X) as e^X = 1 + X + X^2/2! + X^3/3! + ... + X^8/8! }/
  Result := Exponent;

*for *Count := 2 *to *8 *do*
*begin*
    X := X * Exponent; { Contains "X^Count" }
    Result := Result + (X / RecursiveFactorial(Count));
*end*;
end;

*function *Bad(X: QWord): QWord; *pure*;
*begin*
  Result := 0;
*while *True *do*
/{ Run forever }/;
*end*;

*const*
  Factorial6 = Factorial(6);/{ Should convert the function call into the immediate value 720 }/   Factorial21 = Factorial(21); /{ Should return an error due to arithmetic overflow }/   BigNumber = BadCount(0); /{ Should return an error upon realising it's in an infinite loop }/

  RFactorial20: Double = 1 / Factorial(20); /{ Typed constant }/
  SqrtE = RoughExp(0.5); /{ This also tests compiler efficiency by remembering past results of RecursiveFactorial with identical inputs }/   ESquared = RoughExp(2); /{ ... as does this one if a non-recursive factorial is used, due to the previous call to RoughExp(0.5) }/

I may ask you guys for more complex examples down the line.  This is something I really want to get working!

Gareth aka. Kit

P.S. Just to clarify... we happy with the directive being '*pure*'?


On 25/06/2019 06:20, Sven Barth via fpc-devel wrote:
Am 25.06.2019 um 06:20 schrieb Marģers . via fpc-devel:

----- Reply to message -----
Subject: Re: [fpc-devel] XML node dump feature
Date: otrd., 25 jūn., 03:16
From:  Ben Grasset <operato...@gmail.com>
To:  FPC developers' list
<fpc-devel@lists.freepascal.org>

const
   A: TVec3F = (X: 1.2; Y: 2.4; Z: 3.8);
   B: TVec3F = (X: 2.1; Y: 4.2; Z: 8.3);
   // You can't do the next part currently, obviously
   C: TVec3F = A + B;
   D: TVec3F = A - B;
   E: TVec3F = A * B;
   F: TVec3F = A / B;

Sorry to say but, this should not work even with
*pure* function.  Typed constants are not truly
constants.
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.

Regards,
Sven
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel




---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to