Skip to content

Commit a0185b1

Browse files
authored
Tighten requirements for pure call memoization (#3546)
A pure function must have only immutable indirections (or none) in its arguments to memoize calls. Taking a parameter with const indirections is OK iff the argument has only immutable indirections.
1 parent a0a0b57 commit a0185b1

File tree

1 file changed

+32
-4
lines changed

1 file changed

+32
-4
lines changed

spec/function.dd

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -582,18 +582,46 @@ $(H3 $(LNAME2 pure-factory-functions, Pure Factory Functions))
582582
$(H3 $(LNAME2 pure-optimization, Optimization))
583583

584584
$(IMPLEMENTATION_DEFINED An implementation may assume that a strongly pure
585-
function that returns a result
585+
function called with arguments that have only immutable indirections (or none)
586+
that returns a result
586587
without mutable indirections will have the same effect for all invocations
587588
with equivalent arguments. It is allowed to memoize the result of the
588-
function under the assumption that equivalent parameters always produce
589+
function under the assumption that equivalent arguments always produce
589590
equivalent results.)
590591

592+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
593+
---
594+
int a(int) pure; // no mutable indirections
595+
int b(const Object) pure; // depends on argument passed
596+
immutable(Object) c(immutable Object) pure; // always memoizable
597+
598+
void g();
599+
600+
void f(int n, const Object co, immutable Object io)
601+
{
602+
const int x = a(n);
603+
g(); // `n` does not change between calls to `a`
604+
int i = a(n); // same as `i = x`
605+
606+
const int y = b(co);
607+
// `co` may have mutable indirection
608+
g(); // may change fields of `co` through another reference
609+
i = b(co); // call is not memoizable, result may differ
610+
611+
const int z = b(io);
612+
i = b(io); // same as `i = z`
613+
}
614+
---
615+
)
616+
591617
$(P
592-
A strongly pure function may still have behavior
618+
Such a function may still have behavior
593619
inconsistent with memoization by e.g. using `cast`s or by changing behavior
594620
depending on the address of its parameters. An implementation is currently
595621
not required to enforce validity of memoization in all cases.
596-
If a strongly pure function throws an *Exception* or an *Error*, the
622+
)
623+
$(P
624+
If a function throws an *Exception* or an *Error*, the
597625
assumptions related to memoization do not carry to the thrown
598626
exception.)
599627

0 commit comments

Comments
 (0)