• Algol 68 / Genie - scripting language and exit status codes

    From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.misc on Thu Jan 1 13:31:52 2026
    From Newsgroup: comp.lang.misc

    The documentation of the Algol 68 Genie interpreter starts with:

    "Learning Algol 68 Genie is distributed with Algol 68 Genie,
    an open source Algol 68 hybrid compiler-interpreter that can
    be used for executing Algol 68 programs or scripts."

    which seems to suggest that it's useful to write "scripts" with
    it. Part of that valuation is probably the way how Genie operates
    programs by interpretation of the Algol 68 source code (needing
    no explicit compile step). This is probably the most important (or
    maybe even the only?) fact that makes it suitable for scripting
    (IMO).

    One essential thing for scripting is IME the processual character
    of script based systems; controlling script-based processes e.g.
    by exit codes.

    The Algol 68 language has the interesting property that basically
    every "block" has a value that is passed to the outer block level.
    This is actually perfect if we consider the outmost (top-level)
    block as the place where its value could be passed as exit-code
    to the environment.

    But (if I'm not mistaken) that seems to be explicitly forbidden
    by the language! I.e. they defined the outmost block as a special
    case, not allowing to specify a value as final unit. And thereby
    they make it impossible to transfer the exit-code to the calling
    process (the shell or other processes) to control a scripting
    process.[*]

    I think it would be a sensible "extension" to remove that special
    case and allow returning an exit status; for Algol 68 it's too
    late but in Genie it might be useful.

    If there's no value specified the outer block would be "voided"
    and returning 0 to the environment. And an integer value could
    be passed through to the caller's environment as exit-code.[**]

    Opinions?

    Janis

    [*] Well, not impossible; there could also be, like in "C" etc,
    an 'exit()' or 'return' mechanism, for example. But using the
    designed built-in mechanism would be much neater, of course.

    [**] Actually an integer value within an OS-defined range.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Andy Walker@anw@cuboid.co.uk to comp.lang.misc on Sat Jan 3 22:17:13 2026
    From Newsgroup: comp.lang.misc

    On 01/01/2026 12:31, Janis Papanagnou wrote:
    [...]
    The Algol 68 language has the interesting property that basically
    every "block" has a value that is passed to the outer block level.
    This is actually perfect if we consider the outmost (top-level)
    block as the place where its value could be passed as exit-code
    to the environment.
    But (if I'm not mistaken) that seems to be explicitly forbidden
    by the language!

    I think that's an exaggeration. The RR essentially describes
    your program as being "embedded" in a collection of preludes/postludes
    that define the standard environment and also in some way [not defined
    by the RR] the interaction of your program with the OS. I don't see
    anything that forbids that interaction from including an exit code.

    [...]
    I think it would be a sensible "extension" to remove that special
    case and allow returning an exit status; for Algol 68 it's too
    late but in Genie it might be useful.

    I wouldn't have any objection to some sucn extension, but I
    also wouldn't have any great use for it. YMMV.
    --
    Andy Walker, Nottingham.
    Andy's music pages: www.cuboid.me.uk/andy/Music
    Composer of the day: www.cuboid.me.uk/andy/Music/Composers/Kinross
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.misc on Sun Jan 4 01:42:45 2026
    From Newsgroup: comp.lang.misc

    On 2026-01-03 23:17, Andy Walker wrote:
    On 01/01/2026 12:31, Janis Papanagnou wrote:
    [...]
    The Algol 68 language has the interesting property that basically
    every "block" has a value that is passed to the outer block level.
    This is actually perfect if we consider the outmost (top-level)
    block as the place where its value could be passed as exit-code
    to the environment.
    But (if I'm not mistaken) that seems to be explicitly forbidden
    by the language!

    -a-a-a-aI think that's an exaggeration.-a The RR essentially describes
    your program as being "embedded" in a collection of preludes/postludes
    that define the standard environment and also in some way [not defined
    by the RR] the interaction of your program with the OS.-a I don't see anything that forbids that interaction from including an exit code.

    I seem to recall to have read it somewhere (forgot where) and stumbled
    across it again in the previously quoted Lindsey paper (see APPENDIX 6.
    "Syntax Charts", pp. 353f) in a more formalized way. It first explains:

    "Above some of the rectangles there appears an indication of the
    mode that the construct inside is expected to yield, [...]"

    where for the "Particular Program" the Enclosed Clause is marked as
    "strong void" in the respective syntax chart.

    So, as to my suggestion, to formulate something like

    BEGIN
    INT rc = 1;
    rc
    END

    would (as to my understanding) not be allowed in the outmost enclosed
    clause.

    Genie reports that it will void the expression:

    $ genie -x '( 1 )'

    a68g: warning: 1: value of INT denotation will be voided,
    in closed-clause starting at "(" in this line.

    The _Genie interpreter_ doesn't "forbid" it (just warns), but you also
    cannot take any advantage from the exit value; it's not getting passed.
    OTOH, the Lindsey paper seems to say that it's even wrong?


    [...]
    I think it would be a sensible "extension" to remove that special
    case and allow returning an exit status; for Algol 68 it's too
    late but in Genie it might be useful.

    -a-a-a-aI wouldn't have any objection to some sucn extension, but I
    also wouldn't have any great use for it.-a YMMV.

    That's the standard way of passing status between different interacting programs in process-oriented (scripted) systems. (I use this standard
    mechanism with every language I program in.)

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Andy Walker@anw@cuboid.co.uk to comp.lang.misc on Sun Jan 4 23:57:43 2026
    From Newsgroup: comp.lang.misc

    On 04/01/2026 00:42, Janis Papanagnou wrote:
    [...] I don't see
    anything that forbids that interaction from including an exit code.
    I seem to recall to have read it somewhere (forgot where) and stumbled
    across it again in the previously quoted Lindsey paper (see APPENDIX 6. "Syntax Charts", pp. 353f) in a more formalized way. It first explains:
    -a"Above some of the rectangles there appears an indication of the
    -a mode that the construct inside is expected to yield, [...]"
    where for the "Particular Program" the Enclosed Clause is marked as
    "strong void" in the respective syntax chart.
    So, as to my suggestion, to formulate something like
    -a BEGIN
    -a-a-a INT rc = 1;
    -a-a-a rc
    -a END
    would (as to my understanding) not be allowed in the outmost enclosed
    clause.

    (a) It is allowed! The context requires a "strong void" and you have supplied an "INT"; this can be "strong"ly coerced by the "void"ing
    coercion to mode "void", as required, Indeed, as any mode can be
    strongly voided to void, you can supply anything as the result of your outermost enclosed clause.

    (b) You have been describing a "particular program"; this is what you,
    as a programmer, write. But the system us concerned with "program texts", which include also the relevant libraries, preludes and postludes and in
    which your "particular program" is embedded. It's the "program text" that
    has to deliver [by means unspecified in the RR] any interaction with the
    OS [as well as (eg) library routines such as "sqrt"].

    (c) You probably /don't/ want your program simply to return the status,
    even in an extended A68 or A68G, Firstly, because most current programs terminate with some result that is not any sort of status [not even zero],
    so they will all need to be re-written, Secondly, because "interesting"
    status results come from /not/ simply running off the end of the program
    [eg interrupts, wrong permissions, non-existent files, ...] which, by
    default, is likely to cause your program to abort with an error. So a
    perhaps better mechanism would be to add a library routine which can set
    the status and can be used by either the programmer or A68G.

    [...[
    -a-a-a-a-aI wouldn't have any objection to some such extension, but I
    also wouldn't have any great use for it.-a YMMV.
    That's the standard way of passing status between different interacting programs in process-oriented (scripted) systems. (I use this standard mechanism with every language I program in.)

    Yes, but my personal use of A68G scripts is largely as some sort
    of more sophisticated "sed" or "awk", which I normally expect to "just
    work" and otherwise expect to abort with an error message. The status
    is then largely determined by A68G rather than by my program, YMMV!
    --
    Andy Walker, Nottingham.
    Andy's music pages: www.cuboid.me.uk/andy/Music
    Composer of the day: www.cuboid.me.uk/andy/Music/Composers/Couperin
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.misc on Mon Jan 5 00:19:50 2026
    From Newsgroup: comp.lang.misc

    On Sun, 4 Jan 2026 23:57:43 +0000, Andy Walker wrote:

    (c) You probably /don't/ want your program simply to return the
    status, even in an extended A68 or A68G, Firstly, because most
    current programs terminate with some result that is not any sort of
    status [not even zero], so they will all need to be re-written,
    Secondly, because "interesting" status results come from /not/
    simply running off the end of the program [eg interrupts, wrong
    permissions, non-existent files, ...] which, by default, is likely
    to cause your program to abort with an error. So a perhaps better
    mechanism would be to add a library routine which can set the status
    and can be used by either the programmer or A68G.

    Even if you werenrCOt concerned with backward compatibility, I still
    wouldnrCOt want to do it C-style, where rCLmainrCY is a procedure which is given the command-line strings as arguments and is expected to return
    the exit status. Much better to access these via library routines (or
    implicit globals). Makes it easier to write separate argument-parsing
    code, that kind of thing.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.misc on Mon Jan 5 02:07:49 2026
    From Newsgroup: comp.lang.misc

    On 2026-01-05 00:57, Andy Walker wrote:
    On 04/01/2026 00:42, Janis Papanagnou wrote:
    [...] I don't see
    anything that forbids that interaction from including an exit code.
    I seem to recall to have read it somewhere (forgot where) and stumbled
    across it again in the previously quoted Lindsey paper (see APPENDIX 6.
    "Syntax Charts", pp. 353f) in a more formalized way. It first explains:
    -a-a"Above some of the rectangles there appears an indication of the
    -a-a mode that the construct inside is expected to yield, [...]"
    where for the "Particular Program" the Enclosed Clause is marked as
    "strong void" in the respective syntax chart.
    So, as to my suggestion, to formulate something like
    -a-a BEGIN
    -a-a-a-a INT rc = 1;
    -a-a-a-a rc
    -a-a END
    would (as to my understanding) not be allowed in the outmost enclosed
    clause.

    -a (a) It is allowed!-a The context requires a "strong void" and you have supplied an "INT";-a this can be "strong"ly coerced by the "void"ing
    coercion to mode "void", as required,-a Indeed, as any mode can be
    strongly voided to void, you can supply anything as the result of your outermost enclosed clause.

    Thanks for the clarification.

    What I meant is the _consequence_ of this special syntactical case;
    while it may be syntactically allowed, if it gets voided then it's
    effectively also not returning a status value; which was my concern.
    As it's defined the implicit voiding couldn't be prevented by writing
    an exit code value. So with this existing definition it's impossible
    to return anything. If we'd write in any particular program a value
    as return of the outmost block we'd have the effect guaranteed (per
    language specification) that nothing will be returned. The language
    doesn't seem to allow returning a value because it's prevented by
    that definition. (But maybe I still misunderstood what you said.)


    -a (b) You have been describing a "particular program";-a this is what you, as a programmer, write.-a But the system us concerned with "program texts", which include also the relevant libraries, preludes and postludes and in which your "particular program" is embedded.-a It's the "program text" that has to deliver [by means unspecified in the RR] any interaction with the
    OS [as well as (eg) library routines such as "sqrt"].

    Okay.


    -a (c) You probably /don't/ want your program simply to return the status, even in an extended A68 or A68G,

    ???

    If you want an exit status you could write a value. If you don't
    want (and not write) an exit status value you could just omit it.
    The calling context (the "prelude"? - not sure) could hide the
    details how a value ('void', 'int' in the allowed range, or else)
    would be passed to the environment.

    For example; a void outer block result could be translated to an
    implicit default 0 return status ('okay' status)

    BEGIN ...; print (newline) END

    while

    BEGIN INT rc; ...; rc END

    would return the value according to the OS interface rules. And
    things like

    BEGIN NOT_INT_MODE a; ...; a := b END

    or an INT value outside OS scope could be defined with whatever
    seems appropriate; depending on case, say, a voided interpretation,
    a warning or error, a masking of an INT value, whatever. But that
    all is as it appears to me not covered by the now general mandated
    implicit voiding.

    Firstly, because most current programs
    terminate with some result that is not any sort of status [not even zero],
    so they will all need to be re-written,

    Depending on how the outer language context is defined - see above -
    I don't think this is a necessary consequence.

    Secondly, because "interesting"
    status results come from /not/ simply running off the end of the program
    [eg interrupts, wrong permissions, non-existent files, ...] which, by default, is likely to cause your program to abort with an error.

    In a language that doesn't support "C"-like exit() to leave from
    everywhere you could employ other mechanics. Many other languages
    do that with exception mechanisms. An Algol 68 implementation could
    do that with an event routine (or just with a jump, as shown in so
    many examples).

    So a
    perhaps better mechanism would be to add a library routine which can set
    the status and can be used by either the programmer or A68G.

    Yes, this is a possible alternative approach. - It has advantages,
    and it wouldn't conflict with the mentioned semantic constraints.

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.misc on Mon Jan 5 02:21:18 2026
    From Newsgroup: comp.lang.misc

    On 2026-01-05 01:19, Lawrence DrCOOliveiro wrote:
    On Sun, 4 Jan 2026 23:57:43 +0000, Andy Walker wrote:

    (c) You probably /don't/ want your program simply to return the
    status, even in an extended A68 or A68G, Firstly, because most
    current programs terminate with some result that is not any sort of
    status [not even zero], so they will all need to be re-written,
    Secondly, because "interesting" status results come from /not/
    simply running off the end of the program [eg interrupts, wrong
    permissions, non-existent files, ...] which, by default, is likely
    to cause your program to abort with an error. So a perhaps better
    mechanism would be to add a library routine which can set the status
    and can be used by either the programmer or A68G.

    Even if you werenrCOt concerned with backward compatibility, I still wouldnrCOt want to do it C-style, where rCLmainrCY is a procedure which is given the command-line strings as arguments and is expected to return
    the exit status. Much better to access these via library routines (or implicit globals). Makes it easier to write separate argument-parsing
    code, that kind of thing.

    The "C" case is a bit different; while you can 'return' from the
    main() function with an exit code you can also just exit() from
    anywhere. What's *similar* is that the outmost Algol 68 block has
    a similar "outstanding" role as the main() function in "C"; it's
    also not surprising that there's such specific language components
    to adapt to the environment, also in other languages.[*]

    Re "command-line strings as arguments"; sadly there's no standard
    and I don't think that it's supported to any ideal degree in Genie.

    Janis

    [*] There are, of course, also other languages that don't have such
    a special case and handle that more symmetrically.
    --- Synchronet 3.21a-Linux NewsLink 1.2