The purity of the noticed functions in D

Are there any smart ways to keep clean when memoizing functions in D?

I need this when caching SHA1 calculations of large data sets stored in RAM.

+6
source share
2 answers

Short answer: Choose a memorandum or cleanliness. Do not try to use both.

Long answer: I don’t see how it would be possible to preserve purity with memoization if you did not use casts for compilation and claim that the function is pure when it isn’t because for memoize you need to save the arguments and the result, which violates cleanliness, since the number one guarantee for pure functions is that they do not have access to mutable global or static variables (which is the only way that you can memoir something).

So, if you did something like

 alias pure nothrow Foo function() FuncType; auto result = (cast(FuncType)&theFunc)(); 

then you can handle theFunc as if it were pure , when it is not, but then you need to make sure that the function acts pure from the outside - including the fact that the compiler thinks that it can change the variability of the return type of a strongly pure function, which returns a mutable type. For example, this code will compile only thin

 char[] makeString(size_t len) pure { return new char[](len); } void main() { char[] a = makeString(5); const(char)[] b = makeString(5); const(char[]) c = makeString(5); immutable(char)[] d = makeString(5); immutable(char[]) e = makeString(5); } 

although the return type is always changed. And this is because the compiler knows that makeString very pure and returns a value that could not be passed to it, so it will always be a new value every time and, therefore, changes the change in the variability of the returned type to const or immutable does not violate the type system.

If you have to do something inside makeString that included the function of the pure function when it violated the guarantee that makeString always returns a new value, then you would break the type system and you'd risk having very buggy code depending on what you are done with the values ​​returned from makeString .

The only way I know to get clean when you don't have one is by casting a pointer to a function so that it is pure , but if you do, then you must fully understand what pure guarantees and that the compiler believes that he can handle this so that you fully imitate this behavior. It is easier if you return immutable data or a value type, because then you have no problem with a compiler changing the variability of the return type, but it is still a very complicated business.

So, if you are thinking about distinguishing something from pure , think again. Yes, it can be done so that you could not otherwise, but it was very risky. Personally, I would advise you to decide whether cleanliness is important to you, or whether memories are more important to you, and that you are throwing another. Everything else is very risky.

+6
source

What D allows you to express inside a type system is an unclean function that remembers pure.

Conceptually, the memoizer is also clean, but the type system is not expressive enough to allow this. You need to fool something.

0
source

Source: https://habr.com/ru/post/957792/


All Articles