<div dir="ltr"><br>Jochem, Even:<div><br></div><div>The main problem with PROJ's current push/pop functionality<br>is that the four-stack implementation makes it impossible<br>to push one dimension of a coordinate-tuple and pop it into<br>another, without an elaborate axisswap dance at both ends<br>of the push/pop-pair.<br><br>This is a consequence of the v_1 ... v_4 syntax used: Since<br>the order of operator arguments is not necessarily preserved<br>during the parsing process, a pair specified as "v_1 v_2"<br>may appear as "v_2 v_1" at parsing time.<br><br>A more axisswap-like syntax would have eliminated this - e.g.<br><br></div><div>    proj=push items=1,3<br><br></div><div>to push dimensions 1 and 3 of the coordinate tuple onto the<br>stack, and<br><br></div><div>    proj=pop items=3,1<br><br></div><div>to pop them back into swapped dimensions.<br><br>But since the obvious names of push and pop is now taken,<br>let's make a virtue out of necessity by adding a little<br>more encapsulation by introducing the "stack subsystem",<br>giving this syntax:<br><br></div><div>    proj=stack push=1,3<br><br></div><div>and<br><br></div><div>    proj=stack pop=3,1<br><br></div><div>The implementation will still mimick that of push/pop (i.e<br>being handled as part of the pipeline machinery, rather<br>than as ordinary proj=foo-operators), but it will not stomp<br>on the existing unfortunate push/pop-implementation, and it<br>leaves room for extension, e.g. by introducing the swap and<br>flip operators mused over earlier in this thread:<br><br></div><div>    proj=stack push=1,3<br>    proj=stack swap<br>    proj=stack pop=1,3<br><br></div><div>to essentially do the same as above and:<br><br></div><div>    proj=stack push=1,3<br>    proj=stack flip=3,1<br><br></div><div>although I believe the need for these will be limited, once<br>we have a push/pop pair actually working like a stack.<br><br>The wish for named registers mentioned earlier in the<br>thread may be introduced using a similar syntax, where:<br><br></div><div>    proj=reg save=1,3 into=first,third<br>    proj=reg restore=1,3 from=third,first<br><br></div><div>will do the same swapping of first and third dimension as<br>above, but using named registers instead of stack slots.<br><br>I see the potential for improved clarity when using named<br>registers instead of stack slots, by using meaningful<br>names for the registers (e.g. ellipsoidal_height and<br>orthometric_height, to take the obvious use case).<br><br>The problem, however, is when trying to interpret the<br>workings of a pipeline running in inverse mode:<br><br>In the inverse stack-case, we only need to flip the<br>abstract concepts of stack slots, and swap push for pop.<br><br>Whereas in the register case, we also need to "abstractly<br>swap the concrete concepts behind the concrete register<br>names" which, at least to my imperfect brain, is much<br>harder.<br><br>But while not personally seeing the need for registers,<br>I acknowledge the wish for them, and to make this work<br>in a fairly backwards compatible way, I suggest the<br>solution outlined above, i.e. two new, and well<br>encapsulated subsystems in the pipeline implementation.<br>And once they are well established: Deprecation of the<br>current push/pop pair.<br></div></div>