I'm still having to repeat the ../length - 20 expression twice, and the only way I can avoid that is by introducing a newVariableInstance to factor out the common subexpression which is not worth it in this case. (Or I suppose a new dfdl:valueCalc=... property which means to compute on both parse and unparse.) Whether the computed element appears in the infoset or not depends on whether it is hidden or not.
The above also solves the array-variables problem (separate problem - separate email thread to discuss this) as if there is an array of these things, the path to a specific instance of payloadLength within that array is effectively an array variable. (and would be hidden if you don't want the array variable in the infoset. )
Honestly, had we considered IVC/OVC both on the same hidden element, I might have advocated to have this in DFDL as a way to avoid having variables and especially newVariableInstance altogether.
The only drawback is that one cannot use them without a complex type being involved, which is an awkwardness we inherit from XML Schema which results in many elements named "value" that serve to carry a simple type within a complex type enclosure. I.e., <mySimpleElement><value>foo</value></mySimpleElement>. This has been discussed before, and we decided not to fix it for DFDL v1.0. (We will be experimenting with allowing a hidden group ref from a simple type definition as a way to fix this. )
Now, given all that discussion (and digression) ...
I do have a workaround in this case: as you suggested, I can just repeat the expression:
<element name="length" type="xs:int"
dfdl:outputValueCalc="{ dfdl:contentLength(../payload) + 20
}">
<element name="payloadLength" type="xs:int"
dfdl:inputValueCalc="{ ../length - 20 }" />
<element name="payload" dfdl:length="{
../length - 20 }">
<complexType>.....</complexType>
</element>
So that's what I will do for now.
Ultimately w.r.t. other needs that arise from IVC/OVC and unparsing, what I'd like to do is park this issue. As we flesh out more issues of IVC and OVC, we'll accumulate an experience document, a set of implementation techniques etc. Then we'll see what set of concrete proposals come out of this that need to be fixes to DFDL v1.0 as opposed to improvements for DFDL 2.0.