<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Thomas,<br>
    </p>
    | The main problem with PROJ's current push/pop functionality
    <blockquote type="cite"
cite="mid:CAH0YoEM66oNNHAZJbmHfksepMMpOB8YpWPM7tS++Tmm-jPZn0Q@mail.gmail.com">
      <div dir="ltr">
        <div>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>
        </div>
      </div>
    </blockquote>
    <p>While I agree with the theoretical problem, is it actually an
      issue in practice? I can't remember having been annoyed by that a
      single time. Axis swap issues mostly/only occur to get compliant
      with CRS official axis order, and that happens only at the early
      and final stages of a pipeline, whereas push/pop logic happens in
      between where we always speak longitude,latitude / easting,
      northing in that order. So during most of a pipeline execution,
      axis order remains quite stable. So while imperfect, I don't see a
      strong/immediate need to implement a new improved push/pop.</p>
    <blockquote type="cite"
cite="mid:CAH0YoEM66oNNHAZJbmHfksepMMpOB8YpWPM7tS++Tmm-jPZn0Q@mail.gmail.com">
      <div dir="ltr"><br>
        <div><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>
        </div>
      </div>
    </blockquote>
    <p>stack swap, flip: sorry but my own imperfect brain of a
      programmer not having coded in Forth, I will have a very hard time
      to remember what they do exactly without referring to the doc :-)</p>
    <br>
    <blockquote type="cite"
cite="mid:CAH0YoEM66oNNHAZJbmHfksepMMpOB8YpWPM7tS++Tmm-jPZn0Q@mail.gmail.com">
      <div dir="ltr">
        <div><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>
        </div>
      </div>
    </blockquote>
    <p>I would be interested in implementing just save/restore.</p>
    Why not having 2 separate operations, since (save,into) and
    (restore,from) are mutually exclusive parameters.
    <p>So</p>
    <p>- proj=save from=1,3 into=first,third</p>
    <p>- proj=restore into=1,3 from=first,third</p>
    So my pipeline would become:<br>
    <pre class="notranslate"><code class="notranslate">proj=pipeline 
    step proj=save from=3 into=etrs89_h omit_inv      # skipped on reverse path
    step inv proj=vgridshift grids=CR2005.tif multiplier=1
    step proj=save from=3 into=baltic57_h             # reversed as restore
    step proj=restore from=etrs89_h into=3 omit_inv   # skipped on reverse path
    step proj=cart ellps=GRS80                  
    step inv proj=helmert
             x=572.213  rx=-4.9732
             y=85.334   ry=-1.529
             z=461.94   rz=-5.2484
             s=3.5378   convention=coordinate_frame
    step inv proj=cart ellps=bessel 
    step proj=restore from=baltic57_h into=3    # reversed as a save</code></pre>
    <p></p>
    <p>I find it reasonably readable.<br>
    </p>
    <p>But I can also live with your proposed syntax.</p>
    <p></p>
    <p>~~~~~<br>
    </p>
    <p>Or... at least for the sake of brainstorming.... I've also
      imagined that we could extent the existing "set" operator with new
      capabilities, that would bring it even closer to the syntax of
      most programming languages (destination=source)<br>
    </p>
    <p>- proj=set first=v_1  : assign v_1 component to "first" variable<br>
    </p>
    <p>- proj=set v_1=first  : restore v_1 component from "first"
      variable<br>
    </p>
    <p>This causes a few departures from actual PROJ operator logic in,
      but none of them are actually implementation issues:<br>
    </p>
    <p>- the parameter name is actually a variable for the "save"
      semantics (so we have to iterate over the list of parameters,
      instead of just querying a fixed set of parameter names)<br>
    </p>
    <p>- for the restore case (ie v_1=), we need to look at the value to
      determine the semantics. If it is a number, then use the current
      semantics. If it is a string, then it is a variable name. But not
      different from programming language with A=1 and A=B...</p>
    In the reverse path, proj=set first=v_1 would be interpreted as
    proj=set v_1=first, and vice-verca. That part is admitedly a bit
    hard to swallow... especially since it wouldn't apply to when you do
    the regular v_1=numeric_value, and would be my main hesitation to
    implement that.<br>
    <p>If we'd go with the idea, we would likely need to exclude v_1,
      v_2, v_3, v_4 as valid variable names (that is assigning a
      component to another one, since that's generally the role of
      axisswap) 
      mostly because it is not intuitive to me what should be done in
      the reverse path. We's also need to exclude "proj" as a variable
      name to avoid awkward and unparseable things like "proj=set
      proj=v_1". </p>
    <p>~~~~~~~</p>
    <p>[ side remark: Actually I believe the push/pop stack logic could
      be entirely replaced by named registers. If you look at
      programming languages, you use more often named variables than
      stacks. And in actual PROJ pipelines, I believe you have rarely
      have patterns where you have nested pushes of the same variable,
      that is something like "push 1", do X, "push 1", do Y "pop 1", do
      Z, "pop 1". And even if you have, that can be easily replaced with
      "save 1 as first_one", do X, "save 1 as second_one", do Y,
      "restore 1 from second_one", do Z, "restore 1 from first_one".</p>
    <p>... but ... while my above remark is likely true for "optimized"
      / hand-written pipelines, looking at the code in
      createOperations() that compose pipelines, I wouldn't exclude that
      such situations could happen where it would generate a pipeline
      with nested pushes, some of them being likely redundant/no-op. I'm
      not sure really of what monstrosities that code can generate :-)
      Anyway the current push/pop will remain]<br>
    </p>
    <p><br>
    </p>
    <p></p>
    <p></p>
    <blockquote type="cite"
cite="mid:CAH0YoEM66oNNHAZJbmHfksepMMpOB8YpWPM7tS++Tmm-jPZn0Q@mail.gmail.com">
      <div dir="ltr">
        <div><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>
        </div>
      </div>
    </blockquote>
    <p>Understanding the inversion of a pipelines requires a fully
      awaken brain (Acually when you think of it, no programming
      language I'm aware of offers the possibility to execute a program
      in reverse order) - especially with omit_fwd/omit_inv, double
      negation of +inv, etc. , but the inverse of a save is a restore,
      and the inverse of into is from. So not terribly different from
      push / pop.<br>
    </p>
    Even
    <pre class="moz-signature" cols="72">-- 
<a class="moz-txt-link-freetext" href="http://www.spatialys.com">http://www.spatialys.com</a>
My software is free, but my time generally not.</pre>
  </body>
</html>