continuing the discussion of aleph 0 - comments please!
chris hermansen
clhermansen@gmail.com
Tue Dec 30 17:41:04 GMT 2025
Good day everyone,
I have two brief questions / comments following Jose's very informative
responses to my points below.
On Sun, Dec 28, 2025, 07:10 Jose E. Marchesi <jemarch@gnu.org> wrote:
>
> Hi Chris.
>
> > Hello all, recently I wrote to the list as follows regarding ℵ0:
> >
> > For example, from RR § 25.3.1.1
> >> >
> >> > MODE ℵ0 BOOK =
> >> > STRUCT (FLEXTEXT text,
> >> > POS lpos ¢ logical end of book ¢,
> >> > STRING idf ¢ identification ¢,
> >> > BOOL putting ¢ TRUE if the book may be written to ¢,
> >> > INT users ¢ the number of times the book is opened ¢);
> >> >
> >> > So the RR 25.1.3 states, in Step 2:
> >> >
> >> > If, in some form, as possibly made in the step above, ℵ0 occurs
> followed
> >> by
> >> > an INDICATOR (a field-selector) I, then that occurrence of ℵ0 is
> deleted
> >> > and each INDICATOR (field-selector) akin {151 .1.3.2.k} to I
> contained in
> >> > any form is replaced by a copy of one same INDICATOR (field-selector)
> >> which
> >> > does not occur elsewhere in the program and Step 2 is taken again.
> >> >
> >> > [The RR] replaced the ℵ0 with the dash-question-mark symbol;
> >> > but as far as I can tell, ultimately it's not the symbol that's
> giving me
> >> > the heebiejeebies here, it's what do do about it.
> >> >
> >> > That is, I don't understand - at all - the significance of ℵ0 in the
> >> > definition of the BOOK mode above.
> >> >
> >> > For instance, "ℵ0 occurs followed by an INDICATOR (a field-selector)"
> -
> >> how
> >> > closely is "followed"? "FLEXTEXT text" follows ℵ0 (eventually); does
> >> that
> >> > count? Or does the intervening "STRUCT" "OPEN-SYMBOL" preclude the
> >> > deletion of ℵ0 in this case?
> >> >
> >> > Put another way, does
> >> >
> >> > MODE BOOK =
> >> > STRUCT (FLEXTEXT text,
> >> > POS lpos ¢ logical end of book ¢,
> >> > STRING idf ¢ identification ¢,
> >> > BOOL putting ¢ TRUE if the book may be written to ¢,
> >> > INT users ¢ the number of times the book is opened ¢);
> >> >
> >> > ie without the ℵ0, have the same semantic import?
> >
> >
> > Jose kindly responded:
> >
> > ℵ0 is just intended to describe "secret" or inaccessible entities. Any
> >> mode indicant (INDICATOR) or field selector (field-selector) marked by
> >> it is substituted by some mode indicant or field selector that only
> >> occur once (in their definition) in the program. i.e. they are
> >> conceptually replaced by some unique string that is not referred
> >> elsewhere in the program.
> >
> >
> > Ok, I think I understand, in general terms. "mode ℵ0" is a way of hiding
> > the details from users of the mode, similar to what we might call "opaque
> > types" in more recent programming languages.
>
> Yes. Same when applied to some other declared entity as a whole.
>
> > What's not completely obvious to me is that, whereas I think Book must
> be a
> > publicly known mode (even if its details are opaque), I'm pretty sure
> that
> > modes Flextext and Pos are not meant to be publicly known.
> >
> > Contrast the definition of Book with that of Channel, in the RR pp 141 -
> > 142:
> >
> > mode ℵ0 Book =
> > struct (Flextext text,
> > Pos lpos { logical end of book },
> > string idf { identification },
> > book putting { TRUE if the book may be written to },
> > int users { the number of times the book is opened });
> >
> > mode ℵ0 Text = ref [ ] [ ] [ ] char;
> > mode ℵ0 Flextext = ref flex [ ] flex [ ] flex [ ] char;
> > mode ℵ0 Pos = struct (int p, l, c);
> >
> > mode Channel =
> > struct (proc (ref Book) bool ℵ0 reset, ℵ0 set, ℵ0 get, ℵ0 put, ℵ0
> bin,
> > ℵ0 compress, ℵ0 reidf,
> > proc bool ℵ0 estab, proc Pos ℵ0 max pos,
> > proc (ref Book) Conv ℵ0 standconv, int ℵ0 channel number);
> >
> > mode ℵ0 Conv = struct ([1 : int (skip)] struct (char internal, external)
> F);
> > proc estab possible = (Channel chan) bool: estab of chan;
> > proc standconv = (Channel chan) proc (ref Book) Conv: standconv of chan;
> >
> > Starting with the definition of mode Channel and working back to the
> > definition of mode Book:
> >
> > 1. proc standconv has no ℵ0 so it is published, correct? and yet it is
> > only used elsewhere in the RR by proc establish and proc open
>
> Yes. standcov is visible to the user.
>
> > 2. proc estab possible has no ℵ0 so it is published, correct? and yet
> it
> > does not seem to be used anywhere else in the RR
>
> You are supposed to call estab_possible passing some channel, to
> determine whether you can "establish" files in that channel.
>
> > 3. mode Conv has ℵ0 so it is non-published, correct? by the way what
> is
> > that capital F? unusual to see a capital letter for a structure name
> in
> > the RR, is it not?
>
> The mode Conv is not published.
>
> > 4. mode Channel has no ℵ0 so it is published, correct? so in theory,
> we
> > know that it is a structure but its fields are non-published
>
> Right.
>
> > 5. modes Text, Flextext and Pos have ℵ0 so they are non-published,
> > correct?
>
> Right.
>
> > 6. mode Book has ℵ0 so it is non-published, correct? and because it
> has
> > ℵ0, the fact that it is a structure and the nature of its fields are
> also
> > non-published, correct?
>
> Right.
>
> > Now it seems to me that proc standconv is wrongly published since it
> > returns a result of proc (ref Book) Conv whereas both Book and Conv are
> > non-published.
>
> That's no matter. Algol 68 uses structural equivalence of modes, which
> is really orthogonal and simplifies a lot of things, including
> (ironically perhaps) effective hidding of information. If you have
> something like:
>
> module Transput =
> def
> mode Book = C whatever C, Conv = C whatever else C;
> pub mode Channel = struct ([...] proc(ref Book)Conv standconv);
>
> pub proc standconv = (Channel chan) proc(ref Book)Conv:
> standconv of chan;
>
> [...]
> fed
>
> As a user of the Transput module you cannot refer to a Book mode by
> name, but you can still call standconv and get a procedure that gets a
> ref to 'whatever' and then returns a 'whatever else'. Both 'whatever'
> and 'whatever else' modes, or their structure if you like, will be in
> the exports of the module, but not named as Book nor as Conv.
>
> So what structural equivalence achieves here is that, as a user, you
> know that standconv is returning the "standard conversion routine" to be
> used for books opened via that channel, but you cannot (easily) use the
> routine directly because you don't know how to interpret the result: it
> is to be used internally and all you are supposed to do is to get it and
> set it, from a list of pre-defined conversion routines provided by the
> same Transput module.
>
I think I get your points above, but given that I cannot use mode Book in a
declaration, then the only possible ways I can see using such a proc is: by
calling it as an argument to another proc call that can consume the value
yielded; or by passing it as an argument to another proc expecting such.
Is that clear? Am I missing something?
> > I also doubt that proc estab possible should be published, but since it
> > does not seem to be called... maybe I'm missing something.
>
> I would say it is the user that is supposed to use that routine.
>
> > Moving over to van Vliet's version, mode Book is defined as:
> >
> > mode ℵ0 Book =
> > Pseudo1 {Some mode, whose values contain at least the following
> > operating-system-dependent information:
> > - the identification string;
> > - some reference to the actual information, and some indication
> > where to read or write the next buffer (see also section
> 4.4.1);
> > - the logical end of the book ;
> > - information that tells whether the book may again be opened
> > for input or output. ;
> > - the maximum size of the book, as set by 'construct book' (f) or
> > 'find book in system' (e).
> > To avoid excessive copying of information, the implementer is
> > advised to define the mode {BOOK as a reference to the necessary
> > data. };
> >
> > mode ℵ0 Pos = struct (int p, l, c);
> >
> > Note that van Vliet avoids defining all structure within mode Book with
> the
> > exception of mode Pos which is used elsewhere.
>
> Note how, again, the user can use positions around with no problem,
> which are a struct with three integers, only not by name Pos.
>
> > mode Channel is defined as:
> >
> > mode Channel =
> > Pseudo6 {Some mode, whose values determine at least the
> > following information:
> > - the standard conversion key of the channel (d);
> > - the buffer primitives of the channel (m);
> > - the access properties of the channel (l);
> > - whether or not another file
> > may be "established" (5.2.a) on the channel (c);
> > - the (next) default identification
> > string of a book linked via this channel (4.1.2.g);
> > - the default size of a book linked via this channel (n);
> > - the maximum size of a book linked via this channel (4.1.2.f). };
> >
> > mode ℵ0 Conv =
> > struct (proc (ref File, char) void write char,
> > proc (ref File, Binchar) void write bin char,
> > proc (ref File, ref char) bool read char,
> > proc (ref file, ref Binchar) bool read bin char);
> > proc estab possible (Channel chan) bool:
> > bool(Pseudo7) { a routine which returns true if another file
> > may be "established" (5.2.a) on the channel 'chan' };
> > proc standconv = (Channel chan) proc (Book) Conv:
> > proc (Book) Conv(pseudo8) {a routine which may be used to obtain the
> > default
> > "conversion key"; note that the actual primitives are not
> obtained
> > until some specific book is provided also };
> >
> > Once again, both procs standconv and estab possible are to be published.
> > Also notice that, unlike the definition given by the RR, mode Conv is a
> > structure of read and write procedures that deal with reading a character
> > from or writing a character to a file.
> >
> > Given all of the foregoing, I don't see any reason why we cannot follow
> van
> > Vliet's code more closely than that of the RR.
>
> I agree. The van Vliet work was precisely to get something usable from
> the more "specification only" nature of the RR transput listings.
>
> >
> > I also asked
> >
> >
> >> > Moving on to a concrete question, Jose, do you see sppp dealing with
> >> these
> >> > ℵ0 things? Or will we need some other pre-processor to accomplish
> what
> >> is
> >> > needed? Or can we move to the super-language instead?
> >
> >
> > to which Jose responded
> >
> > In our case, in practice, this means that entities marked with ℵ0 should
> >> not be pub-licized in the module implementing the transput, so:
> >
> >
> >> module Transput =
> >> def
> >> [...]
> >
> >
> >> proc book_bounds = (ref File f) Pos: skip; { marked with ℵ0 }
> >> pub proc char_number = (ref File f) int: skip; { not marked with
> ℵ0 }
> >> fed
> >
> >
> >> Same for modes, priorities and operators.
> >
> >
> >> As for secret field names in structs... thats something not supported by
> >> Algol 68 even with the modules system: there are no secret fields and
> >> the user can always refer to them should she find out the names somehow.
> >> We can probably come with some extension for this if we wanted to, to
> >> improve security, but when it comes to implement the transput I think it
> >> is ok to just document these fields as non-public.
> >
> >
> > So in short, it seems we're not relying on sppp to deal with our ℵ0
> > occurrences, but rather using modules and published / non-published
> > components to accommodate this opaqueness, as best as possible.
>
> Right.
>
> > Thus I guess we can imagine, again following van Vliet's version, that
> >
> > 1. mode Book, mode Pos are not to be published;
> > 2. mode Channel and procs estab possible and standconv are to be
> > published;
> > 3. and similarly other modes, procs etc whose definition includes ℵ0
> are
> > not to be published;
> > 4. fields of published structures whose definition includes ℵ0 should
> > not be visible outside the module but, as far as current module
> features
> > go, we have no way of defining a published but opaque type, so we will
> > document the intended hidden nature of the fields.
>
> Yeah.
>
> An obvious solution would be to add a pragmat #<aleph> associated with
> struct fields so we can effectively hide them, but I am (vaguely as of
> yet) playing with the idea of introducing an actual aleph0 character
> usable in both tags and indicants, that compares false to any other
> character other than its particular instance, i.e. using some sort of
> globally-unique-id. This would be to be used to define "unique" modes
> in the existing frame of structural equivalence.
>
> This is all vague as of yet, but consider the typical algol68 situation
> where you have two different data structures, similar in structure but
> different in meaning:
>
> mode Point = [3]int, Vector = [3]int;
>
> Both points and vectors are structurally defined similarly, but they are
> different entities. If you then wanted to define operators like:
>
> op + = (Point a, b) Point: skip,
> (Vector a, b) Vector: skip;
>
> you will get a compile-time error, because Points and Vectors are firmly
> related (they are in fact the same mode). The traditional solution is
> to use structs instead, because the names of struct fiels are part of
> the mode:
>
> mode Point = struct (int a, b, c), Vector = struct (int x, y, z);
>
> Then Point and Vector are no longer structurally equivalent.
>
> This works well, but technically speaking there may be another struct
> (int a, b, c) that is not a Point. This may happen when importing
> modules for example.
>
> So my idea is to have a character allowed in tags that play exactly the
> role of Aleph0 in the RR: tags with this character are assured to appear
> only exactly once in any particular program. I thought about using
> leading underscores. So something like:
>
> mode Point = struct (int _a, _b, _c), Vector = struct (int _a, _b, _c);
>
> The first time _a is found the _ gets internally replaced by an
> globally-unique id. The second _a is found, this time in Vector, the
> same happen. Both ids are part of the modes, as part of the field tags.
>
> When you refer to an aleph0 endowed field:
>
> _a of x
>
> then you will be referring to the _a of Point if x is a Point or to the
> _a of Vector if x happens to be a Vector.
>
> This is all still flaky, but I am thinking in that direction...
>
I think this sounds pretty darned intriguing.
For what it's worth I think I would choose some character other than
underscore, because "everyone these days" seems to want to use a leading
underscore to indicate some kind of variable local to a method - for
example a parameter - and therefore using it as an aleph0 could raise some
serious cognitive dissonance.
Also, and perhaps I misunderstand but just to be certain, there is no need
for an aleph0 in front of a mode indicant or other declaration because not
prepending "pub" has a similar external effect - of hiding the declaration
from external users, correct?
>
> > By way of illustration of the latter, assuming that the eventual
> definition
> > of mode Channel follows that of the revised report (recognizing van Vliet
> > leaves that as an exercise for the implementor), we might expect to see
> >
> > pub mode Channel =
> > struct (proc (ref book) bool { hidden } reset, { hidden } set, {
> hidden
> > } get, { hidden } put,
> > { hidden } bin, { hidden } compress, { hidden } reidf,
> > proc bool { hidden } estab, proc pos { hidden } max pos,
> > proc (ref book) conv { hidden } standconv, int { hidden } channel
> > number);
> >
> > or perhaps
> >
> > pub mode Channel = { opaque }
> > struct (proc (ref book) bool reset, set, get, put,
> > bin, compress, reidf,
> > proc bool estab, proc pos max pos,
> > proc (ref book) conv standconv, int channel number);
> >
> > The latter appeals to me more than the former, but we may have modes with
> > some hidden and some published fields (which would be ugly and weird in
> > principle, but who knows).
>
> I prefer the later.
>
> > Comments, thoughts, criticisms much appreciated.
>
> Thank you for working on this! :)
>
Chris Hermansen · clhermansen "at" gmail "dot" com
C'est ma façon de parler.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/algol68/attachments/20251230/f0dccc6c/attachment-0001.htm>
More information about the Algol68
mailing list