The main concept of pure functions is that they have no side-effects (e.g. don't affect a global state or rely on I/O) and are analogous to a mathematical function.  The main things to draw from it are that for constant inputs, the output is deterministic and can be calculated at compile time (thus replacing the entire call with the result), and for the same inputs, it always produces the same output.

For example, if you have something like: "if (purefunc(X) > Y) and (purefunc(X) < Z) then"... if Z > Y then, even if X is an unknown variable, this can be restructured by the compiler so "purefunc(X)" is only called once (to something akin to "if (purefunc(X) - Y) < (Z - Y) then").

I'm not sure how practical it is for Free Pascal to implement a JIT compiler, but currently there's no support for it.

There is an overhead with pure functions, so you don't really want to mark all functions as pure and let the compiler work it out.

Kit

On 01/07/2024 01:34, Hairy Pixels via fpc-devel wrote:
I had a question about pure functions. I'm seeing some newer languages have a JIT 
built-in so they can run any function at compile time. To get results at compile time you 
probably need to use a constant for the parameters but in theory it could read/write to 
global variables so it's not really "pure" but still makes it possible to run 
functions at compile time.

How does this compare to pure functions? It seems like the JIT is actually 
easier to implement than all this complicated node analysis, but probably 
slower to run I may guess. I think the LLVM backend could do this but the main 
code generator I'm not sure.

On Jun 30, 2024, at 9:17 AM, J. Gareth Moreton via fpc-devel 
<fpc-devel@lists.freepascal.org> wrote:

Fixed 2 and 3.
- 2 was due to not handling block nodes properly when they didn't have any 
statements (data-flow analysis stripped the procedure completely clean since no 
result was set), hence an access violation occurred while accessing a node that 
was nil.
- 3 was a two-fold problem:
     • The functiuon being ineligible was because a typeconv node couldn't be 
stripped out and so the final assignment tree wasn't in an expected format.  
The analysis code now specifically permits this form of type conversion 
(convtype = tc_equal and identical resultdefs between the typeconv and the load 
nodes).
     • The second problem was due to a small hack where implicit Result 
parameters were converted from var to out so data-flow analysis worked 
properly, but they weren't converted back to var parameters afterwards, causing 
an access violation elsewhere in the code.
Merge request has been updated - I have also added two new tests based on your 
examples.  Thanks again Marģers.
Kit
On 28/06/2024 13:24, J. Gareth Moreton via fpc-devel wrote:
Hi Marģers,

Thanks for the feedback!

Assigning the results of pure functions to constants has not yet been 
developed.  I had planned to add it once the bulk of pure functions (i.e. the 
current merge request) had been approved since it requires some additional work 
(specifically what happens if the function is not actually pure or otherwise 
can't return a straightforward result).

2 and 3 are definite bugs though.  The second case should at the very least 
make the function impure, while the third case should indeed not disqualify the 
function.  I'll see what I can do. Thanks again.

Kit

On 28/06/2024 09:35, Marģers . via fpc-devel wrote:
1. pure function value to constants

function foo(i:longword):longword; pure;
begin
   foo:=9;
end;

const bar = foo( 8 );  //-- not allowed.. but i expect this to work!
          jar : longword = foo( 7 ); //-- and this as well


2. this does not end grasefully

function foo (i:longword):shortstring; pure;
var s : shortstring;
       n : longword;
begin
   s:=''';
   for n:=1 to i do s:=s +'a';
   //-- not assing return value
end;
begin writeln(foo(9)); end.

3.
function foo (i:longword):ansistring; pure;
var s : shortstring;
       n : longword;
begin
   s:=''';
   for n:=1 to i do s:=s +'a';
   foo:=s; //-- this makes function not pure, but why whould it!
end;
begin writeln(foo(9)); end.


_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Virus-free.www.avast.com _______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Regards,
Ryan Joseph

_______________________________________________
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.
www.avast.com
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to