<HTML>
<div><style> finitionsBODY { font-family:Arial, Helvetica, sans-serif;font-size:12px; }</style>Limiting pure functions to the definitions of constants severely limits their usefulness, and programmers may just ignore them completely and calculate their results by hand where needed (e.g. replacing ln(2) with 0.69 etc.).  They're designed to replace entire function calls with pre-calculated results at compile-time, thereby providing a massive speed and size saving, and in places where you might least expect, depending on how functions are expanded recursively.  For example, say you have a binary search function that's declared "inline", and you pass in a constant array of a static size.  The function call is expanded and the parameter propagated.  You may then call a function that calculates the base-2 logarithm of the array's size, rounded down, as this is equal to the maximum number of iterations required in the search loop.  Since the size is a constant (since the parameter is propagated unchanged), so too will its logarithm, so the call is replaced with the pre-calculated result.  Since this logarithm is relatively small (e.g. a list of size 200 will return a value of 7), this may cause the loop to be unrolled, providing yet more speed boosts by removing the need for branch prediction.  That's in a very ideal world, of course, where all the optimisations work in unison.</div><div><br>
</div><div>Also, even with your suggestion, there are some cases where the programmer can be deliberately malicious, such as defining a constant to equal the result of a pure function, and then referencing the constant inside the function itself.  I do have an idea though: I may treat them as a kind of inline expression that references are replaced with (e.g. with "const LN2 = ln(2)", replacing references to LN2 with the actual ln(2) call) until it's been successfully evaluated, after which the constant can just be replaced with its value.  If a function turns out to be impure during evaluation of the constant, or appears to have an infinite loop (the compiler will fail the evaluation if it reaches an upper limit on node count or stack depth), then an error is thrown and the constant marked invalid, hence the compiler will fail cleanly.<br>
<br>
Granted, I may put constant evaluation on the side for the moment and actually get the compile-time evaluation to work first.  I'm just trying to think of every possible eventuality and cleanly cover the all.<br>
</div><div><br>
</div><div>Gareth aka. Kit<br>
</div> <br>
<br>
<span style="font-weight: bold;">On Sun 12/08/18 15:28 , "Dmitry Boyarintsev" skalogryz.lists@gmail.com sent:<br>
</span><blockquote style="BORDER-LEFT: #F5F5F5 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT:0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px"><div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Sat, Aug 11, 2018 at 8:50 PM J. Gareth Moreton <<a href="javascript:top.opencompose('gareth@moreton-family.com','','','')">gareth@moreton-family.com</a>> wrote:<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">How and when is the constant defined? Should such constructs be disallowed and constants only allowed to be declared in other units that use the unit that contains the pure functions in its interface section? What would be the ideal and cleanest behaviour?<br>

<br>
</blockquote><div>Why don't you limit the purity only for expressions explicitly defined at "const" section?</div><div>If the function call is found at any place other than "const" section, the function would be executed as a regular run-time function.</div><div>Pretty clean.<br>
</div><div><br>
</div><div>thanks,</div><div>Dmitry</div><div><br>
</div></div></div> 
 

</blockquote></HTML>