RFC on matters related to straightening

chris hermansen clhermansen@gmail.com
Mon Jul 20 17:52:45 GMT 2026


Good morning everyone,

Back from meddling with a new proc whole and before I'm ready to start
on a new proc fixed and proc float, I had some late-evening thoughts
about straightening.  This is a lengthy epistle, so if the thought of
reading over my wanderings through this topic seems less than
desirable, I apologize!

There is a TL;DR down near the end of this message; please feel free
to skip there first.

As far as I can tell, in the RR and in van Vliet's transput, the only
reason for inventing the concept of straightening is the desire to be
able to pass a value of mode OutType to print, write, put, putf, etc,
and similarly a variable of mode InType to read, get, getf etc. and
have the procedure able to deal with writing or reading said value or
variable without the need for the programmer to provide directions on
how to convert complex data structures to a row of simple values (int,
real, compl, bool, bits, char, or []char) or references thereto.

In particular, the RR (and van Vliet follows the RR here), transput
operators STRAIGHTOUT and STRAIGHTIN "magically" convert values /
variables of mode OutType / InType to values / variables of mode
SimplOut and SimplIn, which are rows of simple types int, real, compl,
bool, bits, char or []char.

Any disagreements so far?

Moving along, and picking up a couple of threads from past
conversations on this list, I see this business of STRAIGHTOUT and
STRAIGHTIN as a limited form of what O-O people call "object
introspection", that is, the ability to examine the mode of an object
at runtime in order to decide what to do with it.

The conformity-clause is also a kind of introspection and we would use
it (for example) while handling the conversion of mode SimplOut to its
constituent bits, or the conversion of constituent bits into something
of mode SimplIn.  Something like:

proc so_to_string = (SimplOut so) string:
   case so
   in (int x): whole(x,int_default_width),
      (real x):
float(x,float_default_width,float_default_after,float_default_exp),
      (compl x): float(re OF
x,float_default_width,float_default_after,float_default_exp)
                 + "+i" +
                 float(im OF
x,float_default_width,float_default_after,float_default_exp),
      (bool x): (x | "t" | "f"),
      (bits x): bits_to_string(x),
      (char x): string(x),
      ([] x): x
   esac;

However, while the conformity-clause can work with rows, it doesn't
have the expressive power required to deal with arbitrary struct
values / variables.

And so we need STRAIGHTOUT and STRAIGHTIN to "de-structure" struct
values / variables into rows.

In sum, being able to code

struct (int int_part, real real_part, bool bool_part) s;
int_part OF s := 1;
real_part OF s := 1.5;
bool_part OF s := false;
print((s, new line))

requires:
- united modes
- conformity-clauses
- STRAIGHTOUT "magic"

Still OK here?

Since the RR, the concept of "introspection" has been formalized and
generalized beyond what can be achieved with
union-conformity-STRAIGHTOUT/IN.  Today, we see introspection used not
only to handle this specific transput issue, but other similar matters
including:
- general serialization / deserialization:
   - converting a native data structure to/from JSON or XML,  or
   - converting a native data structure to/from an object-relational database;
   - such converters are often called CODECs (COnverter-DEConverter);
- runtime mode checking:
   - united modes and conformity clauses provide a partial runtime mode
      checking capability, but as noted previously, conformity-clauses don't
      address structure modes;
- useful runtime testing and debugging capabilities;
- the ability to do other things with arbitrary data structures with "generic"
   code (building libraries that implement lists, sets, hash tables etc of
   arbitrary structured data).

One could argue that the last point above can be handled by
parameterized modes - and I would be sympathetic to that argument, as
I like parameterized modes, at least as implemented in Java generics.
But that's a bit off-topic right now.

Could union - conformity - STRAIGHTOUT/IN handle converting a native
data structure to/from JSON or XML?

As designed in the RR, I would say "no" - there's no way in
STRAIGHTOUT/IN to get the names of the fields in a structure.

Obviously, operators STRAIGHTOUTWITHFIELDNAMES and
STRAIGHTINWITHFIELDNAMES could be provided that would help with that.

On the other hand, I think that union - conformity - STRAIGHTOUT/IN
could be used to emulate at least some parameterized mode - related
tasks, by serializing / deserializing arbitrary data structures.  For
example, I could imagine

proc hash_put = (ref HashTable ht, OutType key, value) void: {... uses
STRAIGHTOUT};
proc hash_get = (HashTable ht, OutType key, InType value) void: {...
uses STRAIGHTIN};

The above creates the situation where a given HashTable can use keys,
and hold values, of any mode, which can be desirable, but also creates
run-time insecurity that could be eliminated with parameterized modes.

Still, better than nothing!  And anyway, one can argue that
serializing and deserializing inherently creates run-time insecurity,
since it's difficult to ensure that changes to data structures be
maintained across applications that serialize and other applications
that deserialize "the same stuff".

Still following?  Any thoughts?

TL;DR

Ok, so what I'm wondering is if the GNU Algol 68 provides:
- mode SimplOut;
- op STRAIGHTOUT;
- op STRAIGHTOUTWITHFIELDNAMES;
- mode SimplIn;
- op STRAIGHTIN;
- op STRAIGHTINWITHFIELDNAMES;

that we could address not only transput as envisioned by the RR, but
other interesting and useful capabilities that we have learned about
since Algol 68 was designed to be run on a mainframe computer.

What do you think?


-- 
Chris Hermansen · clhermansen "at" gmail "dot" com

C'est ma façon de parler.


More information about the Algol68 mailing list