• Algol 68 (or generally) - arbitrarily nested arrays of arrays

    From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.misc on Fri Dec 26 12:25:32 2025
    From Newsgroup: comp.lang.misc

    Occasionally I had the demand to create arbitrarily nested arrays of
    arrays (similar to the question in [*]). This requires something like
    [][]...[] SOMETYPE and the corresponding nested loops for processing
    FOR i ...
    ...
    FOR j ...
    FOR k ...
    But these are static definitions and don't scale for arbitrary depth.
    (The dimension/depth of nesting is defined during runtime at start!)

    In the context of another language I had implemented such logic simply
    by linearizing the arrays and the associated array index calculation.

    An alternative approach could be to build the structures recursively
    (with linked data structures) and with a recursive set of functions.

    Now pondering what to do in Algol 68...
    The linearization appears to be the most simple (yet effective) way.
    The recursive one may be conceptually cleaner (but has more overhead).

    Or is there some code pattern [in Algol 68] that would simplify the
    task without muddying the clarity of the algorithms?

    Janis

    PS: In my Algol 68 context the above written [][]...[] SOMETYPE is
    actually rather a more coherent [ , ,... , ] SOMETYPE sort of array
    (which makes the index-flattening simple).

    [*] https://stackoverflow.com/questions/17479241/how-to-create-a-nested-array-of-arbitrary-depth-in-java

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Andy Walker@anw@cuboid.co.uk to comp.lang.misc on Sun Dec 28 12:53:34 2025
    From Newsgroup: comp.lang.misc

    On 26/12/2025 11:25, Janis Papanagnou wrote:
    Occasionally I had the demand to create arbitrarily nested arrays of
    arrays (similar to the question in [*]). This requires something like [][]...[] SOMETYPE and the corresponding nested loops for processing
    -a FOR i ...
    -a-a-a ...
    -a-a-a-a-a FOR j ...
    -a-a-a-a-a-a-a FOR k ...
    But these are static definitions and don't scale for arbitrary depth.
    (The dimension/depth of nesting is defined during runtime at start!)

    See below!

    In the context of another language I had implemented such logic simply
    by linearizing the arrays and the associated array index calculation.
    An alternative approach could be to build the structures recursively
    (with linked data structures) and with a recursive set of functions.
    Now pondering what to do in Algol 68...

    I don't see how anyone can advise without knowing more about
    what the actual, underlying, problem is. My personal inclination, from
    a position of complete ignorance about what you're really trying to do,
    would be to go for a recursive solution.

    [...]
    Or is there some code pattern [in Algol 68] that would simplify the
    task without muddying the clarity of the algorithms?

    [This is the "See below"!] You say that the depth is determined
    at "start". An alternative could be to construct an A68 program of the
    right depth "on the fly". A simple program goes through constructing
    the right number of nested "FOR" loops, or whatever. You write [eg]

    {FOR iN DO} ... {OD}

    and a pre-processor, called with parameter [say] "3", outputs

    FOR i1 DO FOR i2 DO FOR i3 DO ... OD OD OD

    Details left to the imagination.

    I should add that my advice is worth no more than yourCOre paying
    for it, and also that my charges are tripled over the holiday period.
    Merry New Year!
    --
    Andy Walker, Nottingham.
    Andy's music pages: www.cuboid.me.uk/andy/Music
    Composer of the day: www.cuboid.me.uk/andy/Music/Composers/Kirnberger
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From ram@ram@zedat.fu-berlin.de (Stefan Ram) to comp.lang.misc on Sun Dec 28 14:13:03 2025
    From Newsgroup: comp.lang.misc

    Andy Walker <anw@cuboid.co.uk> wrote or quoted:
    I don't see how anyone can advise without knowing more about
    what the actual, underlying, problem is. My personal inclination, from
    a position of complete ignorance about what you're really trying to do,
    would be to go for a recursive solution.

    Dynamically nesting n counting loops is the equivalent of counting
    in a "mixed base". So, it can be transformed to a single counting
    loop and then a transformation to a mixed base.

    See the source code [0] with the output [1]. Of course, the line

    print '(I0,",",I0,",",I0,",",I0)', digits(4), digits(3), digits(2), digits(1)

    is still not dynamic, it's fixed to four digits, but that's just
    for debugging and demonstration and also could be made dynamic . . .

    [0] source code

    module counter_module
    implicit none
    contains

    subroutine count_to_product(sequence)
    integer, intent(in) :: sequence(:)
    integer :: product, count, i
    integer :: temp
    integer :: digits(size(sequence))

    ! Compute product
    product = 1
    do i = 1, size(sequence)
    product = product * sequence(i)
    end do

    ! Count from 0 to product-1 (mixed radix covers 0 to 23 for product=24)
    do count = 0, product - 1
    temp = count ! Already 0-based

    ! Extract digits right-to-left (least to most significant)
    do i = 1, size(sequence)
    digits(i) = mod(temp, sequence(i))
    temp = temp / sequence(i)
    end do

    print '(I0,",",I0,",",I0,",",I0)', digits(4), digits(3), digits(2), digits(1)

    end do

    end subroutine count_to_product

    end module counter_module

    program product_counter
    use counter_module
    implicit none
    integer, allocatable :: nums(:)
    integer :: n, i

    ! Runtime-determined size example
    n = 4
    ! allocate(nums(n))
    ! nums = [2, 3, 2, 2] ! Product = 24
    ! F90:
    allocate(nums(n))
    nums(1) = 2; nums(2) = 3; nums(3) = 2; nums(4) = 2

    call count_to_product(nums)

    deallocate(nums)
    end program product_counter

    [1] output

    0,0,0,0
    0,0,0,1
    0,0,1,0
    0,0,1,1
    0,0,2,0
    0,0,2,1
    0,1,0,0
    0,1,0,1
    0,1,1,0
    0,1,1,1
    0,1,2,0
    0,1,2,1
    1,0,0,0
    1,0,0,1
    1,0,1,0
    1,0,1,1
    1,0,2,0
    1,0,2,1
    1,1,0,0
    1,1,0,1
    1,1,1,0
    1,1,1,1
    1,1,2,0
    1,1,2,1

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From ram@ram@zedat.fu-berlin.de (Stefan Ram) to comp.lang.misc on Sun Dec 28 14:29:15 2025
    From Newsgroup: comp.lang.misc

    ram@zedat.fu-berlin.de (Stefan Ram) wrote or quoted:
    module counter_module

    So, I was, like, thinking you guys were using FORTRAN.
    But now I see "Algol" in the subject!

    BEGIN
    INT n = 4;
    [1:4]INT bases;
    bases := (2,3,2,2);
    INT product := 1;

    # Standard for loop #
    FOR i FROM 1 TO n DO product := product * bases[i] OD;

    FOR count FROM 0 TO product - 1 DO
    INT temp := count;
    [1:4]INT digits := (0,0,0,0);

    INT j := 1;
    WHILE j <= n DO
    digits[j] := temp MOD bases[j];
    temp := temp OVER bases[j];
    j +:= 1
    OD;

    print((whole(digits[4], 0), " ", whole(digits[3], 0), " ",
    whole(digits[2], 0), " ", whole(digits[1], 0), newline))

    OD;

    END


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From ram@ram@zedat.fu-berlin.de (Stefan Ram) to comp.lang.misc on Sun Dec 28 14:41:31 2025
    From Newsgroup: comp.lang.misc

    ram@zedat.fu-berlin.de (Stefan Ram) wrote or quoted:
    So, I was, like, thinking you guys were using FORTRAN.
    But now I see "Algol" in the subject!

    Of course, in Python, it's just,

    import itertools
    import math

    bases =[ 2, 3, 2, 2 ]
    total_product = math.prod( bases )
    ranges =[ range( b ) for b in bases ]
    for digits in itertools.product( *reversed( ranges )):
    print( *digits )

    . You don't need the "trick" with the numerical base conversation,
    but can directly loop in the cartesian product "itertools.product".
    This is what Bjarne calls, "express ideas directly in code".

    There's even a name for this kind of counting, it's "odometer style"!


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From ram@ram@zedat.fu-berlin.de (Stefan Ram) to comp.lang.misc on Sun Dec 28 14:45:37 2025
    From Newsgroup: comp.lang.misc

    ram@zedat.fu-berlin.de (Stefan Ram) wrote or quoted:
    import itertools
    import math
    bases =[ 2, 3, 2, 2 ]
    total_product = math.prod( bases )
    ranges =[ range( b ) for b in bases ]
    for digits in itertools.product( *reversed( ranges )):
    print( *digits )

    "total_product" is not used, so it can be boiled down
    to two lines (plus imports):

    import itertools
    import math

    ranges =[ range( b ) for b in [ 2, 3, 2, 2 ]]
    for digits in itertools.product( *reversed( ranges )): print( *digits )

    .


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.misc on Sun Dec 28 15:47:46 2025
    From Newsgroup: comp.lang.misc

    On 2025-12-28 13:53, Andy Walker wrote:
    On 26/12/2025 11:25, Janis Papanagnou wrote:
    Occasionally I had the demand to create arbitrarily nested arrays of
    arrays (similar to the question in [*]). This requires something like
    [][]...[] SOMETYPE and the corresponding nested loops for processing
    -a-a FOR i ...
    -a-a-a-a ...
    -a-a-a-a-a-a FOR j ...
    -a-a-a-a-a-a-a-a FOR k ...
    But these are static definitions and don't scale for arbitrary depth.
    (The dimension/depth of nesting is defined during runtime at start!)

    -a-a-a-aSee below!

    In the context of another language I had implemented such logic simply
    by linearizing the arrays and the associated array index calculation.
    An alternative approach could be to build the structures recursively
    (with linked data structures) and with a recursive set of functions.
    Now pondering what to do in Algol 68...

    -a-a-a-aI don't see how anyone can advise without knowing more about
    what the actual, underlying, problem is.

    Sorry. I thought the abstraction would be sufficiently clear. :-/

    (Especially since the Stackoverflow link I posted described it as
    well. - I admit with a similar abstraction grade, but clear enough
    for me at least; I've met that task in the past already, so it's
    not new for me. - I seem to recall that I've done something like
    that in C++ with template-meta-programming.)

    My personal inclination, from
    a position of complete ignorance about what you're really trying to do,
    would be to go for a recursive solution.

    Yes, that's an option. - My own thoughts with recursive functions
    were along using them with recursive (linked) data structures. But
    that would bloat the simple structure and I was reluctant to take
    that path.


    [...]
    Or is there some code pattern [in Algol 68] that would simplify the
    task without muddying the clarity of the algorithms?

    -a-a-a-a[This is the "See below"!]-a You say that the depth is determined
    at "start".-a An alternative could be to construct an A68 program of the right depth "on the fly".-a A simple program goes through constructing
    the right number of nested "FOR" loops, or whatever.-a [...]

    Thanks. But Yuck! - I'd prefer static Algol 68 code to introducing
    another level of software generation with dynamic creation of code.

    Why I was asking - I probably should have mentioned that explicitly,
    though I didn't want to restrict possible solutions! - was to get to
    know whether there's some, say, functional or meta-programming options
    with Algol 68 that I didn't yet have noticed.

    Meanwhile I've resorted to the index-linearizing approach, by the way.


    -a-a-a-aI should add that my advice is worth no more than yourCOre paying for it, and also that my charges are tripled over the holiday period.

    I'm glad that three times 0 is still 0. :-)

    OTOH, if you're inclined to read Usenet on a Sunday your potential fees
    might be unjustified anyway. ;-)

    Merry New Year!

    And all the best!

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.misc on Sun Dec 28 15:53:50 2025
    From Newsgroup: comp.lang.misc

    On 2025-12-28 15:29, Stefan Ram wrote:
    ram@zedat.fu-berlin.de (Stefan Ram) wrote or quoted:

    So, I was, like, thinking you guys were using FORTRAN.
    But now I see "Algol" in the subject!

    Yeah, an old language but not *that* old! ;-)

    BEGIN
    INT n = 4;
    [1:4]INT bases;
    bases := (2,3,2,2);
    INT product := 1;

    # Standard for loop #
    FOR i FROM 1 TO n DO product := product * bases[i] OD;

    FOR count FROM 0 TO product - 1 DO
    INT temp := count;
    [1:4]INT digits := (0,0,0,0);

    INT j := 1;
    WHILE j <= n DO
    digits[j] := temp MOD bases[j];
    temp := temp OVER bases[j];
    j +:= 1
    OD;

    print((whole(digits[4], 0), " ", whole(digits[3], 0), " ",
    whole(digits[2], 0), " ", whole(digits[1], 0), newline))

    OD;

    END

    I'm delighted to see there's still people around that are "speaking"
    Algol 68. :-)

    Thanks.

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From bart@bc@freeuk.com to comp.lang.misc on Sun Dec 28 15:32:36 2025
    From Newsgroup: comp.lang.misc

    On 26/12/2025 11:25, Janis Papanagnou wrote:
    Occasionally I had the demand to create arbitrarily nested arrays of
    arrays (similar to the question in [*]). This requires something like [][]...[] SOMETYPE and the corresponding nested loops for processing
    -a FOR i ...
    -a-a-a ...
    -a-a-a-a-a FOR j ...
    -a-a-a-a-a-a-a FOR k ...
    But these are static definitions and don't scale for arbitrary depth.
    (The dimension/depth of nesting is defined during runtime at start!)

    In the context of another language I had implemented such logic simply
    by linearizing the arrays and the associated array index calculation.

    An alternative approach could be to build the structures recursively
    (with linked data structures) and with a recursive set of functions.

    Now pondering what to do in Algol 68...
    The linearization appears to be the most simple (yet effective) way.
    The recursive one may be conceptually cleaner (but has more overhead).

    Or is there some code pattern [in Algol 68] that would simplify the
    task without muddying the clarity of the algorithms?

    Janis

    PS: In my Algol 68 context the above written-a [][]...[] SOMETYPE-a is actually rather a more coherent-a [ , ,... , ] SOMETYPE-a sort of array (which makes the index-flattening simple).

    [*] https://stackoverflow.com/questions/17479241/how-to-create-a-nested- array-of-arbitrary-depth-in-java



    This looked an intriguing problem for my dynamic language.

    In the experiment below, such an array of considered an N-dimensional
    cuboid. Its size and shape is described by an N-element vector giving
    the bounds of each dimension (assumed to be 1-based; N must be at least
    1, and no bounds are empty).

    The example uses a 6-dimensional array. A generic routine is used to
    loop over all elements, and to perform some action based on a supplied anonymous function.

    To allow both getting and setting of elements, this example passes a
    reference to the element to the supplied function, plus a vector of the indices it corresponds to.

    Here, the elements are first set to some incrementing value, then they
    are printed out.

    Ad-hoc access can be done by calling 'getref' directly, or dedicated
    'getset' and 'setelem' routines can be used.


    At first it didn't look like this was a practical approach for Algol68
    or any statically typed language.

    But I think that once you recourse to 'getset' and 'setelem' routines
    that take a vector of indices, then this can work elsewhere. Maybe this
    is the linearising you refered to. In any case, it all looks messy,
    whatever the language.



    --------------------------------------------------
    var count = 0

    proc main =
    v := (2, 3, 4, 5, 6)
    x := maketable(v)

    loopover(x, v, {p, i: p^ := ++count}) # {} is anon. func
    loopover(x, v, {p, i: println i, ":", p^; 0})
    end

    func getref(data, indices)=
    x:=data
    for i in 1..indices.len-1 do
    x := x[indices[i]]
    end
    ^x[indices[$]] # $ is final index
    end

    proc loopover(data, vec, fn) =
    dim := vec.len

    iter := (1,)*dim !start at (1,1,1,...)

    do
    fn(getref(data, iter), iter)

    exit when iter = vec

    ++iter[dim]
    for i := dim downto 2 do
    if iter[i] > vec[i] then
    iter[i] := 1
    ++iter[i-1]
    end
    end
    end
    end

    func maketable(vec) =
    if vec.len = 1 then
    new(list, head(vec), 0)
    else
    a := new(list, head(vec), maketable(tail(vec)))

    for i, x in a do
    a[i] := copy(x)
    end
    a
    end
    end
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.lang.misc on Sun Dec 28 21:43:55 2025
    From Newsgroup: comp.lang.misc

    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
    Occasionally I had the demand to create arbitrarily nested arrays of
    arrays (similar to the question in [*]). This requires something like [][]...[] SOMETYPE and the corresponding nested loops for processing
    FOR i ...
    ...
    FOR j ...
    FOR k ...
    But these are static definitions and don't scale for arbitrary depth.
    (The dimension/depth of nesting is defined during runtime at start!)

    In the context of another language I had implemented such logic simply
    by linearizing the arrays and the associated array index calculation.

    An alternative approach could be to build the structures recursively
    (with linked data structures) and with a recursive set of functions.

    Linearization seem to be best as implementaition. For typed
    interface nice way is to use list (or vectors) as indices. If a
    language has simple way of creating lists you could have code like

    a([1, 2, 3, 4])

    for accessing elements. Concerning iteration, simple in-order
    iteration basically needs to implement multiposition counter
    with carries at appropriate points. Or you could expose
    undelying linear structure. For exmple in Lisp there is
    ROW-MAJOR-AREF to access elements of possibly multidimensional
    array in lineare order and there is ARRAY-ROW-MAJOR-INDEX
    to get linear index corresponding to given tuple of indices
    (useful when one wants to deal with slices).
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.misc on Sun Dec 28 23:48:16 2025
    From Newsgroup: comp.lang.misc

    On 2025-12-28 16:32, bart wrote:
    On 26/12/2025 11:25, Janis Papanagnou wrote:
    [...]

    This looked an intriguing problem for my dynamic language.

    Yeah, that matches my feeling that "dynamic languages" might have
    a point here. Or languages with some meta-programming capabilities.

    Though my question here is indeed asking for an Algol 68 approach
    or some "general" algorithmic approach (that I could implement in
    Algol 68).


    In the experiment below, such an array of considered an N-dimensional cuboid. Its size and shape is described by an N-element vector giving
    the bounds of each dimension (assumed to be 1-based; N must be at least
    1, and no bounds are empty).

    (I think you basically understood the problem structure.)

    Algol 68 supports arrays-of-arrays and implicit bounds information.
    But it's lacking, if I'm not mistaken, dynamic array composition;
    unless building own dynamic/referenced structures, which I'd avoid.
    As you said; it might get messy.

    [...]

    At first it didn't look like this was a practical approach for Algol68
    or any statically typed language.

    Maybe. (But as I said already, I suspect that meta-programming in
    a statically typed language (like C++) might also suffice; but
    it's certainly of no use here if the language doesn't support it.)

    Thanks.

    Janis

    [...]

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.misc on Sun Dec 28 23:50:03 2025
    From Newsgroup: comp.lang.misc

    On 2025-12-28 22:43, Waldek Hebisch wrote:
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
    [...]

    Linearization seem to be best as implementaition. For typed
    interface nice way is to use list (or vectors) as indices. If a
    language has simple way of creating lists you could have code like

    a([1, 2, 3, 4])

    for accessing elements.

    Hmm.. - I'll have to ponder about that. There's a chance that I
    can model not exactly that but "something like that" in Algol 68.

    Concerning iteration, simple in-order
    iteration basically needs to implement multiposition counter
    with carries at appropriate points. Or you could expose
    undelying linear structure. For exmple in Lisp there is
    ROW-MAJOR-AREF to access elements of possibly multidimensional
    array in lineare order and there is ARRAY-ROW-MAJOR-INDEX
    to get linear index corresponding to given tuple of indices
    (useful when one wants to deal with slices).

    Yeah, I thought that Lisp might be an appropriate language for
    things like that. (Too bad that I don't like that language, and
    I anyway need some method here that I can realize in Algol 68.)

    Thanks.

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.misc on Sun Dec 28 22:54:14 2025
    From Newsgroup: comp.lang.misc

    On Sun, 28 Dec 2025 15:32:36 +0000, bart wrote:

    In any case, it all looks messy, whatever the language.

    Look at the rCLodometer stylerCY example that Stefan Ram posted.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From bart@bc@freeuk.com to comp.lang.misc on Sun Dec 28 23:07:02 2025
    From Newsgroup: comp.lang.misc

    On 28/12/2025 22:54, Lawrence DrCOOliveiro wrote:
    On Sun, 28 Dec 2025 15:32:36 +0000, bart wrote:

    In any case, it all looks messy, whatever the language.

    Look at the rCLodometer stylerCY example that Stefan Ram posted.

    That 'odometer' method was also used in the example I posted.

    That's part of what I consider messy.

    But solutions really depend on the problem space and the sorts of things
    you want to with this data structure.

    Maybe a 'dict' is better approach, especially if the structure can be irregular and/or sparse.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From ram@ram@zedat.fu-berlin.de (Stefan Ram) to comp.lang.misc on Sun Dec 28 23:22:27 2025
    From Newsgroup: comp.lang.misc

    ram@zedat.fu-berlin.de (Stefan Ram) wrote or quoted:
    ranges =[ range( b ) for b in [ 2, 3, 2, 2 ]]
    for digits in itertools.product( *reversed( ranges )): print( *digits )

    And readers who do not know Python well might think:
    "There are surely some large data structures created
    there. Could this go out of memory?"

    But Python generates everything only on demand, so the
    expressions just denote /algorithms/, not data structures!
    Or, algorithms disguised as data structures.

    (For example, when you write "range(1000)" in Python, it's
    a kind of sequence of 1000 numbers you can iterate through
    as if it was an array of 1000 numbers, but this is just
    an illusion; in fact, it only needs much less memory than
    an array of 1000 numbers would need.)

    It's a bit like in SQL where executing a JOIN also
    does not mean the cartesian product it is based on
    is actually generated as data in memory or on disk.

    In C++, templates are executed at compile time,
    so they cannot be used to implement algorithms
    that are intended to be based on run-time data.


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.misc on Sun Dec 28 23:29:20 2025
    From Newsgroup: comp.lang.misc

    On Sun, 28 Dec 2025 23:07:02 +0000, bart wrote:

    On 28/12/2025 22:54, Lawrence DrCOOliveiro wrote:

    On Sun, 28 Dec 2025 15:32:36 +0000, bart wrote:

    In any case, it all looks messy, whatever the language.

    Look at the rCLodometer stylerCY example that Stefan Ram posted.

    That 'odometer' method was also used in the example I posted.

    That's part of what I consider messy.

    In a true dynamic language, the successive odometer digits can be
    generated recursively. With the iterator paradigm, you can produce the successive permutations on demand, without having to fill up memory
    with the whole lot at once.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Andy Walker@anw@cuboid.co.uk to comp.lang.misc on Tue Dec 30 16:29:26 2025
    From Newsgroup: comp.lang.misc

    On 28/12/2025 14:47, Janis Papanagnou wrote:
    [...] I thought the abstraction would be sufficiently clear. :-/
    (Especially since the Stackoverflow link I posted described it as
    well.

    Sorry -- I didn't realise its importance! Thunderbird makes
    following links a somewhat tedious process -- since an upgrade a while
    back [perhaps when it became a "snap" (grr!)] it no longer follows
    things I click on, so I have to copy the link, switch to a browser,
    paste the link, press "Enter" and switch back when finished -- so I do
    it only when "necessary".

    [...]
    Or is there some code pattern [in Algol 68] that would simplify the
    task without muddying the clarity of the algorithms?

    I don't know of one. You can use operators and unions to
    make some things more transparent, but you still can't, as far as I
    can see, get to arbitrary numbers of subscripts. OTOH, if you're
    going the "odometer" route, operators to transform arbitrary arrays
    of pseudo-subscripts into one "real" subscript or vv could be useful.

    -a-a-a-a-a[This is the "See below"!]-a You say that the depth is determined >> at "start".-a An alternative could be to construct an A68 program of the
    right depth "on the fly".-a A simple program goes through constructing
    the right number of nested "FOR" loops, or whatever.-a [...]
    Thanks. But Yuck! - I'd prefer static Algol 68 code to introducing
    another level of software generation with dynamic creation of code.

    Well, yes. But I've become quite used to using A68G as a
    "shell" language -- it takes a small fraction of a second to compile
    and run a reasonable script. If we can have two-level grammars, we can
    surely have two-level programs!

    [...]
    OTOH, if you're inclined to read Usenet on a Sunday your potential fees
    might be unjustified anyway. ;-)

    This time of year, the endless round of "fun" palls a bit, and
    it's a relief to turn to something "intellectual".
    --
    Andy Walker, Nottingham.
    Andy's music pages: www.cuboid.me.uk/andy/Music
    Composer of the day: www.cuboid.me.uk/andy/Music/Composers/Joplin
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.misc on Thu Jan 1 12:21:13 2026
    From Newsgroup: comp.lang.misc

    On 2025-12-30 17:29, Andy Walker wrote:
    On 28/12/2025 14:47, Janis Papanagnou wrote:
    [...]

    -a-a-a-a[...] Thunderbird makes
    following links a somewhat tedious process -- since an upgrade a while
    back [perhaps when it became a "snap" (grr!)] it no longer follows
    things I click on, so I have to copy the link, switch to a browser,
    paste the link, press "Enter" and switch back when finished -- so I do
    it only when "necessary".

    This is bad behavior [of Thunderbird]. Actually, I have all sorts of
    issues with my new (snap-based) version of TB. Half of the issues is
    directly related to snap and wrong design. But the links-thing works
    in my TB; it opens a new tab in the last Firefox instance I used.


    [...]
    Or is there some code pattern [in Algol 68] that would simplify the
    task without muddying the clarity of the algorithms?

    -a-a-a-aI don't know of one.-a You can use operators and unions to
    make some things more transparent, but you still can't, as far as I
    can see, get to arbitrary numbers of subscripts.

    Okay.

    OTOH, if you're
    going the "odometer" route, operators to transform arbitrary arrays
    of pseudo-subscripts into one "real" subscript or vv could be useful.

    I actually use 'OP's already to convert the indices forth and back.


    -a-a-a-a-a[This is the "See below"!]-a You say that the depth is determined >>> at "start".-a An alternative could be to construct an A68 program of the >>> right depth "on the fly".-a A simple program goes through constructing
    the right number of nested "FOR" loops, or whatever.-a [...]
    Thanks. But Yuck! - I'd prefer static Algol 68 code to introducing
    another level of software generation with dynamic creation of code.

    -a-a-a-aWell, yes.-a But I've become quite used to using A68G as a
    "shell" language -- it takes a small fraction of a second to compile
    and run a reasonable script.-a If we can have two-level grammars, we can surely have two-level programs!

    Ah, okay. Myself I have different requirements on shell programs and
    scripting. Algol isn't well suited for that from my perspective. (I
    wanted to post about a specific detail on that topic, probably coming
    soon.)

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.misc on Thu Jan 1 17:18:14 2026
    From Newsgroup: comp.lang.misc

    On 01/01/2026 12:21, Janis Papanagnou wrote:
    On 2025-12-30 17:29, Andy Walker wrote:
    On 28/12/2025 14:47, Janis Papanagnou wrote:
    [...]

    -a-a-a-a-a[...] Thunderbird makes
    following links a somewhat tedious process -- since an upgrade a while
    back [perhaps when it became a "snap" (grr!)] it no longer follows
    things I click on, so I have to copy the link, switch to a browser,
    paste the link, press "Enter" and switch back when finished -- so I do
    it only when "necessary".

    This is bad behavior [of Thunderbird]. Actually, I have all sorts of
    issues with my new (snap-based) version of TB. Half of the issues is
    directly related to snap and wrong design. But the links-thing works
    in my TB; it opens a new tab in the last Firefox instance I used.

    This is a off-topic, but many people find snaps to be a source of
    problems - both technical (speed issues, mount list messes, application interaction issues) and non-technical (such as it being basically a proprietary tie-in to Canonical with limited freedom or user control). However, I don't know if flatpack (the obvious alternative) Thunderbird
    has the same problem here as snap Thunderbird, since Thunderbird is a
    normal deb on my system (Mint). It must also surely be possible to find
    a PPA with Thunderbird debs for Ubuntu.



    --- Synchronet 3.21a-Linux NewsLink 1.2