Post by Stephen HoffmanPost by o***@gmail.comThis is generally true for most OSes... OpenVMS is a bit different
though, as it has the ability to be distributed across multiple
"OpenVMS commercialized many features that are now considered standard
* Symmetrical, asymmetrical, and NUMA multiprocessing, including
clustering" - https://infogalactic.com/info/OpenVMS
"The system offers high availability through clustering and the ability
to distribute the system over multiple physical machines." -
https://en.wikipedia.org/wiki/OpenVMS
Nice history. Those capabilities are now available elsewhere, and can
variously be done differently, better, easier and/or cheaper.
Post by o***@gmail.comThis means that the OS absolutely needs a serialization/deserialization
methodology. This ability also needs to be both standardized and
internally accessible by the OS, which implies being available at the
OS level.
I have no idea why that list of OS features and capabilities and OS
history leads to this particular requirement; seems a non-sequitur?
You're obviously an intelligent man Mr. Hoffman, which is why your failure to see how it's needful (and on-topic) is both surprising and a bit of a dismay.
In any case, I'll attempt to enlighten you: if we have a distributed program running on separate machines (say #1, #2, and #3) then there must exist a way to communicate data between them. That *is* a marshaling system combined with the transmission/reception method; such a system is needed to handle more complex types than say INTEGER, things like STRING or a record.
For a string, you need a method for specifying the length, serializing that, and *then* serializing the string-contents; this allows the receiving end to read the string-length, reserve that required-space in memory, and read the deserialization of the string-contents into that memory. -- Similar happens for a record, say one for a doubly linked list (on positive numbers):
Type Node is record
Data : Positive;
Previous,
Next : access Node;
end record:
In this record we have two elements which are [essentially] pointers, we cannot therefore serialize and deserialize their values as the machines have their own address-spaces and such deserialization would essentially be pointing to a random location in memory on the remote machine. (Actually, that's not *entirely* true, some distributed networks have a shared/common address-space, IEEE1394 is an example.) -- The correct way to handle this is the serialization of the contents of the dereferenced fields, where the deserialization method would take care of generating pointers to the reconstituted records linking into the structure appropriately.
Post by Stephen HoffmanThere is certainly usefulness in the basic ability to store and
retrieve data and particularly object graphs, and preferably without
having to slog through RMS and records and the hassles involved when
upgrading applications or otherwise changing application data
structures. (Same hassles have been hitting OpenVMS itself for
decades, too.)
A lot of that "slogging through RMS and records" can be automated/made transparent, if I understand correctly. (IIRC, Ada's Direct_IO package was directly influenced/inspired by VMS's RMS/records.) -- That's where the Stream methods I mentioned awhile back come into play: they offer a standard interface/abstraction on data-flow.
Post by Stephen HoffmanApplication development which increasingly involves dragging some of
the old code base forward in specific areas, and also periodically
reviewing the application code base for latent bugs, and rewriting
parts and extending parts. This is what a ~forty year old operating
system means, where some few of the apps go back even further than
forty years; back into the PDP era.
True, that's where the SOM idea shines: it extends the CLE from procedural/imperative to OOP, even offering its objects to non-OOP languages:
* SOM works with procedural programming languages.
* SOM provides an object model for non-object-oriented languages.
(See: https://www.techopedia.com/definition/1315/system-object-model-som-ibm )
Post by Stephen HoffmanThere's seemingly little reason to create a design for marshaling and
unmarshaling that can't also store OO data structures and object
graphs, in addition to the sorts of traditional data structures typical
of C or BASIC or otherwise, as well as the whole and unfortunately
increasingly limited zoo of available OpenVMS descriptors, either.
Not in this era. Or preferences, as marshaling and unmarshaling data
is most of an application preferences mechanism, too. But I digress.
Except that the marshaling/unmarshaling *CAN* operate on OO data-structures and graphs. Here's an example using Ada's Stream attributes:
Pragma Ada_2012;
With
Ada.Text_IO.Text_Streams,
Ada.Integer_Text_IO;
Procedure IO_Example_3 is
-------------------------------
-- Object & Supporting Types --
-------------------------------
Package Objects is
Type Abstract_Object(Name_Length : Natural) is abstract tagged record
Name : String(1..Name_Length);
end record;
Function "+"(Left : Abstract_Object) return String is abstract;
Function "-"(Left : Abstract_Object'Class) return String is
(Left."+");
Type Fruit is new Abstract_Object with null record;
Type Animal_Noise is (Bark, Meow, Low, Quack);
Type Animal is new Abstract_Object with record
Noise : Animal_Noise;
end record;
Type Ship_Class is (Cutter, Destroyer, Battleship);
Type Ship_Tonnage is delta 10.0 range 4_600.0..45_000.0;
Type Ship( Class : not null access Ship_Class;
Name_Length : Natural ) is
new Abstract_Object(Name_Length) with record
Tonnage : Ship_Tonnage;
end record;
Private
Overriding Function "+"(Left : Fruit) Return String is
( '[' & Left.Name & ']' );
Overriding Function "+"(Left : Animal) Return String is
( '{' & Left.Name &
" / Says: " & Animal_Noise'Image(Left.Noise) & '}' );
Overriding Function "+"(Left : Ship) return String is
( '<' & Left.Name & " is a" & Ship_Tonnage'Image(Left.Tonnage) &
" ton " & Ship_Class'Image(Left.Class.All) & '>' );
End Objects;
Use Objects;
------------------------------------
-- File/Stream Types & Operations --
------------------------------------
Subtype File_Mode is Ada.Text_IO.File_Mode;
Subtype Text_File is Ada.Text_IO.File_Type;
Subtype Text_Stream is Ada.Text_IO.Text_Streams.Stream_Access;
Function File(Mode : File_Mode:= Ada.Text_IO.In_File) return Text_File is
Begin
Return Result : Text_File do
Ada.Text_IO.Open(
File => Result,
Mode => Mode,
Name => "Input.txt"
);
End return;
End File;
Begin
WRITE_OBJECTS:
Declare
Pear : Fruit := (Name_Length => 4, Name => "Pear");
New_Jersey : Ship := (Name_Length => 10, Name => "New Jersey",
Class => new Ship_Class'(Battleship),
Tonnage => 45_000.0);
Dog : Animal := (Name_Length => 3, Name => "Dog", Noise => Bark);
Cow : Animal := (Name_Length => 4, Name => "Bess", Noise => Low);
Strawberry : Fruit := (Name_Length => 4, Name => "Dave");
use Ada.Text_IO;
Output_File: Text_File := File(Out_File);
Output : Text_Stream := Text_Streams.Stream(Output_File);
Begin
Fruit'Output ( Output, Pear );
Ship'Output ( Output, New_Jersey );
Animal'Output( Output, Dog );
Animal'Output( Output, Cow );
Abstract_Object'Class'Output(Output, Abstract_Object(Strawberry));
Close(Output_File); -- Close the file.
End WRITE_OBJECTS;
READ_OBJECTS:
Declare
Use Ada.Text_IO;
Input_File : Text_File := File( In_File );
Input : Text_Stream := Text_Streams.Stream(Input_File);
Pear : Fruit := Fruit'Input( Input );
New_Jersey : Abstract_Object'Class := Ship'Input( Input );
Dog : Animal := Animal'Input(Input);
Cow : Animal := Animal'Input(Input);
Strawberry : Abstract_Object'Class := Abstract_Object'Class'Input(Input);
Begin
Put_Line( -Pear );
Put_Line( -New_Jersey );
Put_Line( -Dog );
Put_Line( -Cow );
Put_Line( +Strawberry );
Close(Input_File); -- Close file.
End READ_OBJECTS;
End IO_Example_3;
Program Output:
[Pear]
<New Jersey is a 45000.0 ton BATTLESHIP>
{Dog / Says: BARK}
{Bess / Says: LOW}
[Dave]
Post by Stephen HoffmanPost by o***@gmail.comIf you mean native libraries to support native applications shipping
with OS, then absolutely.
"SOM defines an interface between programs, or between libraries and
programs, so that an object's interface is separated from its
implementation. SOM allows classes of objects to be defined in one
programming language and used in another, and it allows libraries of
such classes to be updated without requiring client code to be
recompiled.
A SOM library consists of a set of classes, methods, static functions,
and data members. Programs that use a SOM library can create objects of
the types defined in the library, use the methods defined for an object
type, and derive subclasses from SOM classes, even if the language of
the program accessing the SOM library does not support class typing. A
SOM library and the programs that use objects and methods of that
library need not be written in the same programming language. SOM also
minimizes the impact of revisions to libraries. If a SOM library is
changed to add new classes or methods, or to change the internal
implementation of classes or methods, one can still run a program that
uses that library without recompiling. This is not the case for all
other C++ libraries, which in some cases require recompiling all
programs that use them whenever the libraries are changed." -
https://infogalactic.com/info/IBM_System_Object_Model
That could be worded better, but then that's a common local perception
whenever reading most IBM-related documentation. Adopting something
akin to SOM is a substantial overhaul of how applications interoperate
with OpenVMS. It's very much akin to the OO that I've occasionally
mentioned and discounted, and its how both macOS and Windows with .NET
are programmed.
True, but it was special-purpose made for libraries and *CAN* be used by non-OOP languages, and that's why extending the CLR with it could be so valuable.
Post by Stephen HoffmanNot only does any OO implementation work involve having databases
backing the archiving and restoration of objects and data structures —
relational databases aren't OS add-ons anymore — the rest of the
implementation of an OO "replacement" model for system services and
libraries would be a very large development effort for both VSI, with
slow adoption for most current end-user developers and partners from
there.
The previous example used streams on a text-file, there's no reason though that the stream can't be a database or a instantiation of direct-IO or a straight-up memory-dump: **THAT** is the whole purpose of their data-flow abstraction.
Post by Stephen HoffmanPost by o***@gmail.comPost by o***@gmail.comBesides, if you do as I've laid out you could use the ASN.1 machinery
to handle serialization/deserialization, using the particular encoder
as a parameter, and bang you've got XML (via XER encoding) or JSON (via
that JSON ASN.1 encoder referenced).
ASN.1 seems not to be what the market wants. That does not preclude it
from being a nice technology. But just not so intertesting from a
practical perspective.
If done as presented then ASN.1 is essentially invisible to the
programmers using the system, as it is interfaced/integrated on the
underlying SOM meta-types. (ie All they 'see' is that every type has
both a serialize and deserialize function.)
If the marshaling and unmarshaling is opaque, then ASN.1 or JSON or XML
or some local or binary encoding all works fine, and the appropriate
choice can be made as determined by the scale of the data, whether the
data will be exported, etc. But as soon as the adoption of OO
programming is in play — and that's what SOM would be, or
ObjC/Swift/Cocoa, or .NET et al — the marshaling and unmarshaling code
is a rounding error in the development effort involved. Or to
functional programming, for that matter.
A rounding error?
I don't understand what you're trying to say there.