[PROJ] Make push and pop FIFO?

Thomas Knudsen knudsen.thomas at gmail.com
Thu Feb 8 13:09:57 PST 2024


> I believe the main objection to named variable, was:
> what happens when one nests / copy-paste part of
> pipelines in a more complex pipelines.

@Even,

As I have already said earlier in this thread, this is
not a problem with nested pipelines (as they execute in
their own context).

But it might obviously be a problem (as you write) when
copy-pasting parts of other pipelines. But general
carelessness is very hard to guard against, and I do not
think we should try to walk down the alley of "the safe
knife": It leads to overengineered uselessness.

But obviously, I believe that stacks should - well: Not be
implemented in PROJ, because they are alredy, but
repaired, since the implementation is broken, or at least
unnecessarily limiting.

Also, I believe your latest syntactical suggestion over at
Github (reading the pop-args backwards) results in a very
readable mental model:

stack = [] operand = [10,20,30,40]
push=1,2
stack = [10, 20] operand = [10,20,30,40]
pop=1,2
stack = [] operand = [10,20,30,40]
push=1,2
stack = [10, 20] operand = [10,20,30,40]
pop=2,1
stack = [] operand = [20,10,30,40]

i.e. the push coordinates are placed on the stack (reading l->r
as bottom->top) in the same order as in the argument to push.

and the pop coordinates are pop'd such that the operand
dimensions get the stack element the corresponding pop arg
is placed "under", i.e quite graphically graspable.

Your alternative suggestion about scopes is interesting, but
(I believe) too little. Or too much...

Already, internal pipelines, when instantiated with init=foo,
execute in their own scope, so it will really just be a
matter of lifting the restriction that "pipelines cannot
contain pipelines", and introducing an "end-of-pipeline"
marker (perhaps "stop" as a nod to "step"), then gobbling
up everything up until the "stop" marker into an internal
buffer and treating that with the same code that now handles
init=foo.

Then there's the problem with an internal pipeline that
contains another internal pipeline. How is that handled?

By pushing it onto a stack! Scopes are really just stacks...

I think init=... handles internal inits by recursion, which
is also just a matter of stacks, although this time handled
by the compiler and the runtime. I'm not sure it's quite as
easy to implement without the overhead of the file system,
but it would be nice if not so.

But nevertheless, I think this will be too little, because
first, it is already somewhat orthogonal to the existing PROJ
architecture and second, it provides too little new
functionality, and third it is "just another programming
language".

So I think if the PROJ key=value syntax should be extended,
it should be be by internal bindings to a sandboxed "real"
programming language, making it possible to extend PROJ
with user defined operators, conditionals way beyond the
simple omit_fwd/omit_inv modifiers, and true branching.

On the other hand: The truly remarkable and unique feature
of the as-is PROJ syntax considered as a programming
language, is its ability to execute its programs both ways.

I do not think we will find many obvious candidates for a
PROJ internal extension language that will uphold this
quality unmodified. One of the only candidates I can see
at least might do it is the stack based Forth.

A minimal Forth interpreter can be implemented in a few
hundred bytes, and a more extensive, well documented one,
John Walker's "Atlast" (https://www.fourmilab.ch/atlast/)
is in the public domain, written in plain C, and weighs just
a single (albeit 4000 lines) source file, and a small header
file.

If I see correctly, any PROJ operator can be registered
as a Forth "word", with its key=value-arguments given as
a dictionary. I do however, think it will be quite slow, as
the dict will have to be reread at every invocation, i.e.
for every coordinate tuple handled.

This is part of the reason, I decided on (loosely speaking)
arrays of coordinate tuples as the basic operands of
Rust Geodesy (
https://github.com/busstoptaktik/geodesy/blob/main/ruminations/009-rumination.md)
- as a experiment for a
faster and simpler data flow for PROJ: Not having any
"per coordinate tuple" overheads, but only a "per (say)
100000 coordinate tuples" overhead is quite an optimization.

But nevertheless - PROJ is quite unique in its fundamental
features, and while I think the syntax can be cleaned up
for readability quite drastically (again: see the Rust
Geodesy text), I think messing with its semantics is a more
dragon laden exercise than worth it.

Hence also my sentiments primarily towards repairing the
existing stack implementation, rather than extending the
PROJ language and its unique omnidirectional feature, in
the direction of a more (Turing) complete language.

This said despite that I have been experimenting with a
feature of passing options to macros in Rust Geodesy.

But I think that feature is still too untested and immature
to be proposed for PROJ use.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/proj/attachments/20240208/df19a3fc/attachment.htm>


More information about the PROJ mailing list