Closed Strilanc closed 3 years ago
So, after having completely confused myself due to a bug that resulted from doing this sort of thing, I have switched to thinking it's a terrible idea.
The basic problem is that this assumes that if you have a method like
operation E() : Unit is Adj {
Asymmetric();
Adjoint Asymmetric();
}
Where the operations applied within the body of Asymmetric
are self-inverse, then you want the inverse of E to be
Adjoint Asymmetric();
Asymmetric();
But it's actually, correctly, computed to be
Asymmetric();
Adjoint Asymmetric();
Basically it doesn't compose right.
Here is an operation that I've found myself defining:
So that I can write code like this:
The idea here is that reversible code often runs forwards and then backwards almost identically. The variations between the backward and forward pass are not always directly in the center of the execution. When that happens, being able to make a few tweaks between the forward and backward pass can allow significantly more code reuse.
It seems silly to define a custom operation for this. It feels like it should be a language feature. Perhaps I should be able to say something like:
This could also be used to make some manual adjoint implementations more compact, since they could be a slight
if runningbackward
tweak within the body.Affidavit (please fill out)
Please add ticks by placing a cross in the box:
Please tick all that apply: