• extending MySQL on VMS

    From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Tue Aug 12 19:08:51 2025
    From Newsgroup: comp.os.vms

    Code:

    #include <string.h>

    #include <mysql.h>

    my_bool demo_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
    {
    if(args->arg_count == 2 && args->arg_type[0] == STRING_RESULT && args->arg_type[1] == INT_RESULT)
    {
    return 0;
    }
    else
    {
    strcpy(message, "demo function requires two arguments: one
    string and one integer");
    return 1;
    }
    }

    long long demo(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned
    long *length, unsigned char *is_null, unsigned char *error)
    {
    const char *sv = args->args[0];
    long long iv = *((long long *)args->args[1]);
    return strlen(sv) + iv;
    }

    void demo_deinit(UDF_INIT *initid)
    {
    }

    Build:

    $ cc /include=mysql055_root:[include.mysql] /names=as_is demo.c
    $ link/share=demo_shr.exe demo + sys$input/opt mysql055_root:[lib.alpha]libclientlib/lib
    mysql055_root:[lib.alpha]libsql/lib
    mysql055_root:[lib.alpha]libmysys/lib
    mysql055_root:[lib.alpha]libdbug/lib
    mysql055_root:[lib.alpha]libstrings/lib
    mysql055_root:[lib.alpha]libvio/lib
    mysql055_root:[lib.alpha]libz/lib
    mysql055_root:[lib.alpha]ssl_libssl32/lib mysql055_root:[lib.alpha]ssl_libcrypto32/lib
    CASE_SENSITIVE=YES
    SYMBOL_VECTOR=(demo_init=PROCEDURE, -
    demo=PROCEDURE, -
    demo_deinit=PROCEDURE)
    $

    Install (DCL):

    $ copy/log demo_shr.exe mysql055_root:[plugin.alpha]*.*
    $ def/sys demo_shr "''f$parse("mysql055_root:[plugin.alpha]demo_shr.exe",,,,"NO_CONCEAL")'"

    Install (SQL):

    CREATE FUNCTION demo
    RETURNS INTEGER
    SONAME 'demo_shr';

    Demo:

    MariaDB [test]> select demo('ABC', 1);
    +----------------+
    | demo('ABC', 1) |
    +----------------+
    | 4 |
    +----------------+
    1 row in set (0.01 sec)

    MariaDB [test]> select demo('ABCD', 1);
    +-----------------+
    | demo('ABCD', 1) |
    +-----------------+
    | 5 |
    +-----------------+
    1 row in set (0.00 sec)

    MariaDB [test]> select demo('ABC', 2);
    +----------------+
    | demo('ABC', 2) |
    +----------------+
    | 5 |
    +----------------+
    1 row in set (0.00 sec)

    MariaDB [test]> SELECT demo();
    ERROR 1123 (HY000): Can't initialize function 'demo'; demo function
    requires two arguments: one string and one integer
    MariaDB [test]> SELECT demo('ABC');
    ERROR 1123 (HY000): Can't initialize function 'demo'; demo function
    requires two arguments: one string and one integer
    MariaDB [test]> SELECT demo('ABC', 'DEF');
    ERROR 1123 (HY000): Can't initialize function 'demo'; demo function
    requires two arguments: one string and one integer
    MariaDB [test]> SELECT demo('ABC', 1, 1);
    ERROR 1123 (HY000): Can't initialize function 'demo'; demo function
    requires two arguments: one string and one integer

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Tue Aug 12 19:28:44 2025
    From Newsgroup: comp.os.vms

    On 8/12/2025 7:08 PM, Arne Vajh|+j wrote:
    Build:

    $ cc /include=mysql055_root:[include.mysql] /names=as_is demo.c
    $ link/share=demo_shr.exe demo + sys$input/opt mysql055_root:[lib.alpha]libclientlib/lib
    mysql055_root:[lib.alpha]libsql/lib
    mysql055_root:[lib.alpha]libmysys/lib
    mysql055_root:[lib.alpha]libdbug/lib
    mysql055_root:[lib.alpha]libstrings/lib
    mysql055_root:[lib.alpha]libvio/lib
    mysql055_root:[lib.alpha]libz/lib
    mysql055_root:[lib.alpha]ssl_libssl32/lib mysql055_root:[lib.alpha]ssl_libcrypto32/lib
    CASE_SENSITIVE=YES
    SYMBOL_VECTOR=(demo_init=PROCEDURE, -
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a demo=PROCEDURE, -
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a demo_deinit=PROCEDURE)
    $

    Note that if as in this case the functions does not use
    any MySQL functions, then all the MySQL libraries can be
    omitted.

    $ cc /include=mysql055_root:[include.mysql] /names=as_is demo.c
    $ link/share=demo_shr.exe demo + sys$input/opt
    CASE_SENSITIVE=YES
    SYMBOL_VECTOR=(demo_init=PROCEDURE, -
    demo=PROCEDURE, -
    demo_deinit=PROCEDURE)
    $

    works just as well.

    But if you need some MySQL functions, then you will need
    some of the MySQL libraries.

    In the first version I just picked all the libraries
    needed by a client application.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence D'Oliveiro@ldo@nz.invalid to comp.os.vms on Wed Aug 13 03:09:21 2025
    From Newsgroup: comp.os.vms

    On Tue, 12 Aug 2025 19:08:51 -0400, Arne Vajh|+j wrote:

    mysql055_root:[lib.alpha]libclientlib/lib
    mysql055_root:[lib.alpha]libsql/lib
    mysql055_root:[lib.alpha]libmysys/lib
    mysql055_root:[lib.alpha]libdbug/lib
    mysql055_root:[lib.alpha]libstrings/lib
    mysql055_root:[lib.alpha]libvio/lib
    mysql055_root:[lib.alpha]libz/lib
    mysql055_root:[lib.alpha]ssl_libssl32/lib mysql055_root:[lib.alpha]ssl_libcrypto32/lib

    Is there some equivalent to rCL-L-2dir-+rCY to add a common directory to a linker search path so you can just shorten most of that to something
    more like rCL-lclientlib -lsql -lmysys -ldbug -lstrings -lvio -lzrCY?
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Thu Aug 14 20:33:20 2025
    From Newsgroup: comp.os.vms

    On 8/12/2025 11:09 PM, Lawrence D'Oliveiro wrote:
    On Tue, 12 Aug 2025 19:08:51 -0400, Arne Vajh|+j wrote:
    mysql055_root:[lib.alpha]libclientlib/lib
    mysql055_root:[lib.alpha]libsql/lib
    mysql055_root:[lib.alpha]libmysys/lib
    mysql055_root:[lib.alpha]libdbug/lib
    mysql055_root:[lib.alpha]libstrings/lib
    mysql055_root:[lib.alpha]libvio/lib
    mysql055_root:[lib.alpha]libz/lib
    mysql055_root:[lib.alpha]ssl_libssl32/lib
    mysql055_root:[lib.alpha]ssl_libcrypto32/lib

    Is there some equivalent to rCL-L-2dir-+rCY to add a common directory to a linker search path so you can just shorten most of that to something
    more like rCL-lclientlib -lsql -lmysys -ldbug -lstrings -lvio -lzrCY?

    VMS is not *nix.

    You can do a lot of things on VMS, but I don't think you
    can do exactly that.

    You can omit location on all libraries except the first and
    let the sticky default mechanism add it.

    (I don't think that is a nice solution)

    You can define a logical mylib and just use mylib:xxxx/lib
    to shorten.

    You can setup default libraries with LNK$LIBRARY* logicals.

    You can create shareable images and stuff all of them into
    a shareable library.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Fri Aug 15 01:04:21 2025
    From Newsgroup: comp.os.vms

    On Thu, 14 Aug 2025 20:33:20 -0400, Arne Vajh|+j wrote:

    On 8/12/2025 11:09 PM, Lawrence D'Oliveiro wrote:

    Is there some equivalent to rCL-L-2dir-+rCY to add a common directory to a >> linker search path so you can just shorten most of that to something
    more like rCL-lclientlib -lsql -lmysys -ldbug -lstrings -lvio -lzrCY?

    VMS is not *nix.

    You could have just said rCLnorCY.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Fri Aug 15 12:27:35 2025
    From Newsgroup: comp.os.vms

    On 2025-08-12, Arne Vajhoj <arne@vajhoej.dk> wrote:
    Code:

    #include <string.h>

    #include <mysql.h>

    my_bool demo_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
    {
    if(args->arg_count == 2 && args->arg_type[0] == STRING_RESULT && args->arg_type[1] == INT_RESULT)

    Is it guaranteed that arg_type[] will always have at least elements ?
    If not, that's dangerous unless the compiler you are using does
    expression short-circuiting.

    {
    return 0;
    }
    else
    {
    strcpy(message, "demo function requires two arguments: one
    string and one integer");
    return 1;

    YUCK!!! :-) Does MySQL provide a maximum error message size field or
    constant that you can use with strncpy() instead ?

    }
    }

    long long demo(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned
    long *length, unsigned char *is_null, unsigned char *error)
    {
    const char *sv = args->args[0];
    long long iv = *((long long *)args->args[1]);
    return strlen(sv) + iv;
    }

    void demo_deinit(UDF_INIT *initid)
    {
    }

    Build:

    $ cc /include=mysql055_root:[include.mysql] /names=as_is demo.c
    $ link/share=demo_shr.exe demo + sys$input/opt mysql055_root:[lib.alpha]libclientlib/lib
    mysql055_root:[lib.alpha]libsql/lib
    mysql055_root:[lib.alpha]libmysys/lib
    mysql055_root:[lib.alpha]libdbug/lib
    mysql055_root:[lib.alpha]libstrings/lib
    mysql055_root:[lib.alpha]libvio/lib
    mysql055_root:[lib.alpha]libz/lib
    mysql055_root:[lib.alpha]ssl_libssl32/lib mysql055_root:[lib.alpha]ssl_libcrypto32/lib
    CASE_SENSITIVE=YES
    SYMBOL_VECTOR=(demo_init=PROCEDURE, -
    demo=PROCEDURE, -
    demo_deinit=PROCEDURE)
    $

    Install (DCL):

    $ copy/log demo_shr.exe mysql055_root:[plugin.alpha]*.*
    $ def/sys demo_shr "''f$parse("mysql055_root:[plugin.alpha]demo_shr.exe",,,,"NO_CONCEAL")'"

    Install (SQL):

    CREATE FUNCTION demo
    RETURNS INTEGER
    SONAME 'demo_shr';

    Demo:

    MariaDB [test]> select demo('ABC', 1);
    +----------------+
    | demo('ABC', 1) |
    +----------------+
    | 4 |
    +----------------+
    1 row in set (0.01 sec)

    MariaDB [test]> select demo('ABCD', 1);
    +-----------------+
    | demo('ABCD', 1) |
    +-----------------+
    | 5 |
    +-----------------+
    1 row in set (0.00 sec)

    MariaDB [test]> select demo('ABC', 2);
    +----------------+
    | demo('ABC', 2) |
    +----------------+
    | 5 |
    +----------------+
    1 row in set (0.00 sec)

    MariaDB [test]> SELECT demo();
    ERROR 1123 (HY000): Can't initialize function 'demo'; demo function
    requires two arguments: one string and one integer
    MariaDB [test]> SELECT demo('ABC');
    ERROR 1123 (HY000): Can't initialize function 'demo'; demo function
    requires two arguments: one string and one integer
    MariaDB [test]> SELECT demo('ABC', 'DEF');
    ERROR 1123 (HY000): Can't initialize function 'demo'; demo function
    requires two arguments: one string and one integer
    MariaDB [test]> SELECT demo('ABC', 1, 1);
    ERROR 1123 (HY000): Can't initialize function 'demo'; demo function
    requires two arguments: one string and one integer

    Arne

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Fri Aug 15 09:35:00 2025
    From Newsgroup: comp.os.vms

    On 8/15/2025 8:27 AM, Simon Clubley wrote:
    On 2025-08-12, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Code:

    #include <string.h>

    #include <mysql.h>

    my_bool demo_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
    {
    if(args->arg_count == 2 && args->arg_type[0] == STRING_RESULT &&
    args->arg_type[1] == INT_RESULT)

    Is it guaranteed that arg_type[] will always have at least elements ?
    If not, that's dangerous unless the compiler you are using does
    expression short-circuiting.

    Isn't C required to do short circuiting on && ?

    {
    return 0;
    }
    else
    {
    strcpy(message, "demo function requires two arguments: one
    string and one integer");
    return 1;

    YUCK!!! :-) Does MySQL provide a maximum error message size field or
    constant that you can use with strncpy() instead ?

    Not that I am aware of.

    No such used in the example provided by MySQL/Oracle.

    Arne



    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From John Reagan@johnrreagan@earthlink.net to comp.os.vms on Fri Aug 15 09:40:06 2025
    From Newsgroup: comp.os.vms

    On 8/15/2025 9:35 AM, Arne Vajh|+j wrote:
    On 8/15/2025 8:27 AM, Simon Clubley wrote:
    On 2025-08-12, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Code:

    #include <string.h>

    #include <mysql.h>

    my_bool demo_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
    {
    -a-a-a-a-a if(args->arg_count == 2 && args->arg_type[0] == STRING_RESULT && >>> args->arg_type[1] == INT_RESULT)

    Is it guaranteed that arg_type[] will always have at least elements ?
    If not, that's dangerous unless the compiler you are using does
    expression short-circuiting.

    Isn't C required to do short circuiting on && ?

    Yes, C and C++ short-circuits. Other languages may not. For example,
    Pascal does promise short-circuit which is why our Pascal also provides
    an AND_THEN and OR_ELSE operator much like you find in Ada.


    -a-a-a-a-a {
    -a-a-a-a-a-a-a-a-a return 0;
    -a-a-a-a-a }
    -a-a-a-a-a else
    -a-a-a-a-a {
    -a-a-a-a-a-a-a-a-a strcpy(message, "demo function requires two arguments: one
    string and one integer");
    -a-a-a-a-a-a-a-a-a return 1;

    YUCK!!! :-) Does MySQL provide a maximum error message size field or
    constant that you can use with strncpy() instead ?

    Not that I am aware of.

    No such used in the example provided by MySQL/Oracle.

    Arne




    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Fri Aug 15 13:40:37 2025
    From Newsgroup: comp.os.vms

    In article <107n93n$13rjm$1@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-12, Arne Vajhoj <arne@vajhoej.dk> wrote:
    Code:

    #include <string.h>

    #include <mysql.h>

    my_bool demo_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
    {
    if(args->arg_count == 2 && args->arg_type[0] == STRING_RESULT &&
    args->arg_type[1] == INT_RESULT)

    Is it guaranteed that arg_type[] will always have at least elements ?
    If not, that's dangerous unless the compiler you are using does
    expression short-circuiting.

    C is well-defined in this regard. Boolean expressions in C,
    created by combining logical subexpressions with the `&&` and
    `||` operators, are documented to use short-circuiting behavior.

    {
    return 0;
    }
    else
    {
    strcpy(message, "demo function requires two arguments: one
    string and one integer");
    return 1;

    YUCK!!! :-) Does MySQL provide a maximum error message size field or
    constant that you can use with strncpy() instead ?

    Indeed yuck, and MySQL _does_ provide a constant that gives
    the maximum error message size: `MYSQL_ERRMSG_SIZE`. https://dev.mysql.com/doc/extending-mysql/9.4/en/adding-loadable-function.html

    While I agree that it's best to avoid `strcpy`, in this case,
    the source string is fixed, and short, and known to fit easily
    into the result. `strcpy` _should_ be deprecated and eventually
    removed from the C library, but in this specific case, it's ok.

    However, I must disagree strongly with the advice to use
    `strncpy`, which is poorly understood and has strange semantics:
    it will write as much of the source string to the destination as
    it can, with or without the NUL terminating byte. If the source
    is smaller than the destination buffer, then the remainder of
    the buffer will be filled with 0s. If the source is exactly as
    long as, or longer, than the destination, then the destination
    will not be NUL-terminated. Since it just returns the
    destination pointer, there is no way to detect truncation other
    than to test the last byte in the destination to see whether it
    is zero or not. So it is inefficent in the common case, and
    dangerous and awkward in the exceptional case. Moreover, its
    behavior is orthogonal to that of `strncat`, which does _not_
    have the "write 0s to all bytes in the destination past the end
    of the what we copied from the source string", and is also
    awkward in how it treats it's length argument: whereas for
    `strncpy` the length argument is the size of the entire
    destination buffer, for `strncat` it is not: `strncat` will
    write up to n+1 bytes into the destination.

    The strlcpy/strlcat functions introduced in OpenBSD addressed
    these shortcomings, and have liberally licensed implementations: https://www.usenix.org/legacy/event/usenix99/full_papers/millert/millert.pdf https://www.openbsd.org/papers/strlcpy-slides.pdf and https://github.com/openbsd/src/blob/master/lib/libc/string/strlcpy.c https://github.com/openbsd/src/blob/master/lib/libc/string/strlcat.c
    (or, if one prefers, https://pub.gajendra.net/src/strlcpy.c and https://pub.gajendra.net/src/strlcat.c)

    However, there are some complaints about `strlcpy` et al: https://lwn.net/Articles/905777/ which lead to Linux pushing
    adoption of `strscpy` instead: https://elixir.bootlin.com/linux/v5.19.3/source/lib/string.c#L151

    Any of these could be adopted for use on VMS with relatively
    minimal effort. But in this context, is it is better to just use
    `snprintf`. It will always properly terminate its destination
    buffer, it is easy to detect trunctaion, and, while irrelevant
    in this example, it supports formatting arguments.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Fri Aug 15 09:55:17 2025
    From Newsgroup: comp.os.vms

    On 8/15/2025 9:40 AM, John Reagan wrote:
    On 8/15/2025 9:35 AM, Arne Vajh|+j wrote:
    On 8/15/2025 8:27 AM, Simon Clubley wrote:
    On 2025-08-12, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Code:

    #include <string.h>

    #include <mysql.h>

    my_bool demo_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
    {
    -a-a-a-a-a if(args->arg_count == 2 && args->arg_type[0] == STRING_RESULT &&
    args->arg_type[1] == INT_RESULT)

    Is it guaranteed that arg_type[] will always have at least elements ?
    If not, that's dangerous unless the compiler you are using does
    expression short-circuiting.

    Isn't C required to do short circuiting on && ?

    Yes, C and C++ short-circuits.-a Other languages may not.-a For example, Pascal does promise short-circuit which is why our Pascal also provides
    ^not> an AND_THEN and OR_ELSE operator much like you find
    in Ada.

    VB.NET has AndAlso and OrElse.

    But I believe most curly bracket languages inherited from
    C in this regard.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Fri Aug 15 17:33:25 2025
    From Newsgroup: comp.os.vms

    On 2025-08-15, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <107n93n$13rjm$1@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-12, Arne Vajhoj <arne@vajhoej.dk> wrote:
    Code:

    #include <string.h>

    #include <mysql.h>

    my_bool demo_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
    {
    if(args->arg_count == 2 && args->arg_type[0] == STRING_RESULT &&
    args->arg_type[1] == INT_RESULT)

    Is it guaranteed that arg_type[] will always have at least elements ?
    If not, that's dangerous unless the compiler you are using does
    expression short-circuiting.

    C is well-defined in this regard. Boolean expressions in C,
    created by combining logical subexpressions with the `&&` and
    `||` operators, are documented to use short-circuiting behavior.


    Thank you.

    Unless it's explicit in the language syntax itself, and given that
    I write code in multiple languages, I have long written code that
    assumes implicit[*] short-circuiting is not available.

    As such, whether implicit short-circuiting is available or not is
    not really that important to me, but I will admit I didn't realise
    C had it.

    [*] By implicit short-circuiting I mean something that's only defined
    in the language standard or implemented in a compiler, instead of some
    explicit syntax in the language itself to state short-circuiting is
    available.


    However, I must disagree strongly with the advice to use
    `strncpy`, which is poorly understood and has strange semantics:
    it will write as much of the source string to the destination as
    it can, with or without the NUL terminating byte. If the source
    is smaller than the destination buffer, then the remainder of
    the buffer will be filled with 0s. If the source is exactly as
    long as, or longer, than the destination, then the destination
    will not be NUL-terminated. Since it just returns the
    destination pointer, there is no way to detect truncation other
    than to test the last byte in the destination to see whether it
    is zero or not. So it is inefficent in the common case, and
    dangerous and awkward in the exceptional case. Moreover, its
    behavior is orthogonal to that of `strncat`, which does _not_
    have the "write 0s to all bytes in the destination past the end
    of the what we copied from the source string", and is also
    awkward in how it treats it's length argument: whereas for
    `strncpy` the length argument is the size of the entire
    destination buffer, for `strncat` it is not: `strncat` will
    write up to n+1 bytes into the destination.


    strncpy() makes more sense when you realise that its original purpose
    was to fill fixed-size fields in a record with data and to clear the
    rest of the field if the source data was smaller than the field size.

    BTW, after using strncpy(), my code always unconditionally places
    a 0x00 in the final byte of the buffer "just in case :-)".

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris Townley@news@cct-net.co.uk to comp.os.vms on Fri Aug 15 18:51:26 2025
    From Newsgroup: comp.os.vms

    On 15/08/2025 18:33, Simon Clubley wrote:
    On 2025-08-15, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <107n93n$13rjm$1@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-12, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Code:

    #include <string.h>

    #include <mysql.h>

    my_bool demo_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
    {
    if(args->arg_count == 2 && args->arg_type[0] == STRING_RESULT && >>>> args->arg_type[1] == INT_RESULT)

    Is it guaranteed that arg_type[] will always have at least elements ?
    If not, that's dangerous unless the compiler you are using does
    expression short-circuiting.

    C is well-defined in this regard. Boolean expressions in C,
    created by combining logical subexpressions with the `&&` and
    `||` operators, are documented to use short-circuiting behavior.


    Thank you.

    Unless it's explicit in the language syntax itself, and given that
    I write code in multiple languages, I have long written code that
    assumes implicit[*] short-circuiting is not available.

    As such, whether implicit short-circuiting is available or not is
    not really that important to me, but I will admit I didn't realise
    C had it.

    [*] By implicit short-circuiting I mean something that's only defined
    in the language standard or implemented in a compiler, instead of some explicit syntax in the language itself to state short-circuiting is available.


    However, I must disagree strongly with the advice to use
    `strncpy`, which is poorly understood and has strange semantics:
    it will write as much of the source string to the destination as
    it can, with or without the NUL terminating byte. If the source
    is smaller than the destination buffer, then the remainder of
    the buffer will be filled with 0s. If the source is exactly as
    long as, or longer, than the destination, then the destination
    will not be NUL-terminated. Since it just returns the
    destination pointer, there is no way to detect truncation other
    than to test the last byte in the destination to see whether it
    is zero or not. So it is inefficent in the common case, and
    dangerous and awkward in the exceptional case. Moreover, its
    behavior is orthogonal to that of `strncat`, which does _not_
    have the "write 0s to all bytes in the destination past the end
    of the what we copied from the source string", and is also
    awkward in how it treats it's length argument: whereas for
    `strncpy` the length argument is the size of the entire
    destination buffer, for `strncat` it is not: `strncat` will
    write up to n+1 bytes into the destination.


    strncpy() makes more sense when you realise that its original purpose
    was to fill fixed-size fields in a record with data and to clear the
    rest of the field if the source data was smaller than the field size.

    BTW, after using strncpy(), my code always unconditionally places
    a 0x00 in the final byte of the buffer "just in case :-)".

    Simon.


    That wouldn't be good if you are filling part of a record!
    --
    Chris
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Fri Aug 15 18:05:19 2025
    From Newsgroup: comp.os.vms

    On 2025-08-15, Chris Townley <news@cct-net.co.uk> wrote:
    On 15/08/2025 18:33, Simon Clubley wrote:

    strncpy() makes more sense when you realise that its original purpose
    was to fill fixed-size fields in a record with data and to clear the
    rest of the field if the source data was smaller than the field size.

    BTW, after using strncpy(), my code always unconditionally places
    a 0x00 in the final byte of the buffer "just in case :-)".


    That wouldn't be good if you are filling part of a record!


    Yeah, but I'm not using it for that. :-)

    I wish that all modern languages had dynamically allocated string
    support so you would not have to worry about this.

    Even when they do, sometimes they still manage to mess up the
    implementation. For example, in C++, "[]" is an unchecked
    operator and you have to use at() to get bounds checking on
    strings.

    It would have been far better if "[]" was the bounds checked
    operator and you had to use at() to get unchecked indexing for
    those rare cases you needed some less overhead for performance
    reasons.

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Fri Aug 15 22:42:02 2025
    From Newsgroup: comp.os.vms

    On Fri, 15 Aug 2025 09:55:17 -0400, Arne Vajh|+j wrote:

    But I believe most curly bracket languages inherited from C in this
    regard.

    Python took over the C operator hierarchy, with one subtle little
    twist. It slightly tweaked the precedence of the bitwise operators
    relative to the comparisons, so you donrCOt need parentheses in
    expressions like

    (C) (-2val-+ & -2bitmask-+) == -2testvalue-+
    (Python) -2val-+ & -2bitmask-+ == -2testvalue-+

    I have asked on comp.lang.c whether any existing C code could be
    broken by making the same change in that language. In principle it
    could, but nobody could come up with any real-world examples.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Fri Aug 15 19:48:14 2025
    From Newsgroup: comp.os.vms

    On 8/15/2025 1:33 PM, Simon Clubley wrote:
    On 2025-08-15, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <107n93n$13rjm$1@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-12, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    if(args->arg_count == 2 && args->arg_type[0] == STRING_RESULT && >>>> args->arg_type[1] == INT_RESULT)

    Is it guaranteed that arg_type[] will always have at least elements ?
    If not, that's dangerous unless the compiler you are using does
    expression short-circuiting.

    C is well-defined in this regard. Boolean expressions in C,
    created by combining logical subexpressions with the `&&` and
    `||` operators, are documented to use short-circuiting behavior.

    Unless it's explicit in the language syntax itself, and given that
    I write code in multiple languages, I have long written code that
    assumes implicit[*] short-circuiting is not available.

    As such, whether implicit short-circuiting is available or not is
    not really that important to me, but I will admit I didn't realise
    C had it.

    [*] By implicit short-circuiting I mean something that's only defined
    in the language standard or implemented in a compiler, instead of some explicit syntax in the language itself to state short-circuiting is available.

    In general I like the idea of writing code in a way that does
    not require the reader to have memorized ten thousand things from
    the language spec.

    But I do not consider this a matter of remembering the specific
    details about an operator - I consider this a matter of remembering
    what operator a symbol represent.

    I consider "short circuiting AND" and "non short circuiting AND"
    to be two different operators.

    And in C then && is the first operator not the second operator.

    And understanding what operator each symbol represent is not
    detail but core. IMHO.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Fri Aug 15 19:58:21 2025
    From Newsgroup: comp.os.vms

    On 8/15/2025 9:40 AM, Dan Cross wrote:
    In article <107n93n$13rjm$1@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-12, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    strcpy(message, "demo function requires two arguments: one
    string and one integer");
    return 1;

    YUCK!!! :-) Does MySQL provide a maximum error message size field or
    constant that you can use with strncpy() instead ?

    Indeed yuck, and MySQL _does_ provide a constant that gives
    the maximum error message size: `MYSQL_ERRMSG_SIZE`. https://dev.mysql.com/doc/extending-mysql/9.4/en/adding-loadable-function.html
    Ah. There is a constant. Good find.

    And it is 512 in 5.5 on VMS.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From John Reagan@johnrreagan@earthlink.net to comp.os.vms on Fri Aug 15 20:27:37 2025
    From Newsgroup: comp.os.vms

    On 8/15/2025 9:55 AM, Arne Vajh|+j wrote:
    On 8/15/2025 9:40 AM, John Reagan wrote:
    On 8/15/2025 9:35 AM, Arne Vajh|+j wrote:
    On 8/15/2025 8:27 AM, Simon Clubley wrote:
    On 2025-08-12, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Code:

    #include <string.h>

    #include <mysql.h>

    my_bool demo_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
    {
    -a-a-a-a-a if(args->arg_count == 2 && args->arg_type[0] == STRING_RESULT &&
    args->arg_type[1] == INT_RESULT)

    Is it guaranteed that arg_type[] will always have at least elements ?
    If not, that's dangerous unless the compiler you are using does
    expression short-circuiting.

    Isn't C required to do short circuiting on && ?

    Yes, C and C++ short-circuits.-a Other languages may not.-a For example,
    Pascal does promise short-circuit which is why our Pascal also provides
    -a-a-a-a-a-a-a-a-a-a-a-a-a ^not> an AND_THEN and OR_ELSE operator much like you find
    in Ada.

    VB.NET has AndAlso and OrElse.

    But I believe most curly bracket languages inherited from
    C in this regard.

    Arne

    Thanks for the correction. Yes "not promise".

    BTW, BLISS does not promise short-circuit. And in the true BLISS
    fashion, most of us use the following macros

    ! AND_THEN(B1,B2,...Bn) returns TRUE if all of Bi are TRUE.
    ! Evaluates the Bi left to right and stops on the first false one.
    !
    AND_THEN(B)[]=
    %IF %LENGTH EQL 1
    %THEN
    (B)
    %ELSE
    (IF (B) THEN AND_THEN(%REMAINING) ELSE FALSE)
    %FI %,

    ! OR_ELSE(B1,B2,...Bn) returns FALSE if all of Bi are FALSE.
    ! Evaluates the Bi left to right and stops on the first true one.
    !
    OR_ELSE(B)[]=
    %IF %LENGTH EQL 1
    %THEN
    (B)
    %ELSE
    (IF (B) THEN TRUE ELSE OR_ELSE(%REMAINING))
    %FI %,

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From John Reagan@johnrreagan@earthlink.net to comp.os.vms on Fri Aug 15 20:31:31 2025
    From Newsgroup: comp.os.vms

    On 8/15/2025 7:48 PM, Arne Vajh|+j wrote:
    On 8/15/2025 1:33 PM, Simon Clubley wrote:
    On 2025-08-15, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <107n93n$13rjm$1@dont-email.me>,
    Simon Clubley-a <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-12, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    -a-a-a-a-a if(args->arg_count == 2 && args->arg_type[0] == STRING_RESULT &&
    args->arg_type[1] == INT_RESULT)

    Is it guaranteed that arg_type[] will always have at least elements ?
    If not, that's dangerous unless the compiler you are using does
    expression short-circuiting.

    C is well-defined in this regard.-a Boolean expressions in C,
    created by combining logical subexpressions with the `&&` and
    `||` operators, are documented to use short-circuiting behavior.

    Unless it's explicit in the language syntax itself, and given that
    I write code in multiple languages, I have long written code that
    assumes implicit[*] short-circuiting is not available.

    As such, whether implicit short-circuiting is available or not is
    not really that important to me, but I will admit I didn't realise
    C had it.

    [*] By implicit short-circuiting I mean something that's only defined
    in the language standard or implemented in a compiler, instead of some
    explicit syntax in the language itself to state short-circuiting is
    available.

    In general I like the idea of writing code in a way that does
    not require the reader to have memorized ten thousand things from
    the language spec.

    But I do not consider this a matter of remembering the specific
    details about an operator - I consider this a matter of remembering
    what operator a symbol represent.

    I consider "short circuiting AND" and "non short circuiting AND"
    to be two different operators.

    BTW, while the C frontend always generates the "short-circuiting" AND
    and OR intermediate opcodes, the GEM optimizer works to detect if that
    is really needed. It is hoping to hoist something from the right-hand
    side out of a loop (which happens more than you think) and on Itanium it
    can even put both left and right in the same bundle if possible (which
    doesn't happen all that much)

    And in C then && is the first operator not the second operator.

    And understanding what operator each symbol represent is not
    detail but core. IMHO.

    Arne


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Fri Aug 15 20:40:14 2025
    From Newsgroup: comp.os.vms

    On 8/15/2025 8:27 PM, John Reagan wrote:
    BTW, BLISS does not promise short-circuit.-a And in the true BLISS
    fashion, most of us use the following macros

    -a-a-a-a-a-a-a ! AND_THEN(B1,B2,...Bn) returns TRUE if all of Bi are TRUE.
    -a-a-a-a-a-a-a ! Evaluates the Bi left to right and stops on the first false one.
    -a-a-a-a-a-a-a !
    -a-a-a-a-a-a-a AND_THEN(B)[]=
    -a-a-a-a-a-a-a-a-a-a-a %IF %LENGTH EQL 1
    -a-a-a-a-a-a-a-a-a-a-a %THEN
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a (B)
    -a-a-a-a-a-a-a-a-a-a-a %ELSE
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a (IF (B) THEN AND_THEN(%REMAINING) ELSE FALSE)
    -a-a-a-a-a-a-a-a-a-a-a %FI %,

    -a-a-a-a-a-a-a ! OR_ELSE(B1,B2,...Bn) returns FALSE if all of Bi are FALSE.
    -a-a-a-a-a-a-a ! Evaluates the Bi left to right and stops on the first true one.
    -a-a-a-a-a-a-a !
    -a-a-a-a-a-a-a OR_ELSE(B)[]=
    -a-a-a-a-a-a-a-a-a-a-a %IF %LENGTH EQL 1
    -a-a-a-a-a-a-a-a-a-a-a %THEN
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a (B)
    -a-a-a-a-a-a-a-a-a-a-a %ELSE
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a (IF (B) THEN TRUE ELSE OR_ELSE(%REMAINING))
    -a-a-a-a-a-a-a-a-a-a-a %FI %,

    Very readable. But not obvious to come up with.

    But it got me curious.

    I consider it a given that the age distribution for competent Bliss
    programmers are a bit "right side heavy".

    VSI (and Oracle Rdb team for that matter!) has a lot of Bliss to
    maintain.

    Do you have a plan for how to train new Bliss programmers?

    Very few example on the internet. No books that I are aware
    of. Not any active forums.

    Not easy for anyone to learn by themselves.

    Arne




    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Fri Aug 15 20:44:59 2025
    From Newsgroup: comp.os.vms

    On 8/15/2025 8:31 PM, John Reagan wrote:
    On 8/15/2025 7:48 PM, Arne Vajh|+j wrote:
    On 8/15/2025 1:33 PM, Simon Clubley wrote:
    On 2025-08-15, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <107n93n$13rjm$1@dont-email.me>,
    Simon Clubley-a <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote: >>>>> On 2025-08-12, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    -a-a-a-a-a if(args->arg_count == 2 && args->arg_type[0] ==
    STRING_RESULT &&
    args->arg_type[1] == INT_RESULT)

    Is it guaranteed that arg_type[] will always have at least elements ? >>>>> If not, that's dangerous unless the compiler you are using does
    expression short-circuiting.

    C is well-defined in this regard.-a Boolean expressions in C,
    created by combining logical subexpressions with the `&&` and
    `||` operators, are documented to use short-circuiting behavior.

    Unless it's explicit in the language syntax itself, and given that
    I write code in multiple languages, I have long written code that
    assumes implicit[*] short-circuiting is not available.

    As such, whether implicit short-circuiting is available or not is
    not really that important to me, but I will admit I didn't realise
    C had it.

    [*] By implicit short-circuiting I mean something that's only defined
    in the language standard or implemented in a compiler, instead of some
    explicit syntax in the language itself to state short-circuiting is
    available.

    In general I like the idea of writing code in a way that does
    not require the reader to have memorized ten thousand things from
    the language spec.

    But I do not consider this a matter of remembering the specific
    details about an operator - I consider this a matter of remembering
    what operator a symbol represent.

    I consider "short circuiting AND" and "non short circuiting AND"
    to be two different operators.

    BTW, while the C frontend always generates the "short-circuiting" AND
    and OR intermediate opcodes, the GEM optimizer works to detect if that
    is really needed.-a It is hoping to hoist something from the right-hand
    side out of a loop (which happens more than you think) and on Itanium it
    can even put both left and right in the same bundle if possible (which doesn't happen all that much)

    Keeping the pipeline busy ...

    But there are two obvious issues to avoid:
    * early test that must short circuit or later test will crash
    (null pointer usage, array index out of range etc.)
    * call of functions with side effects

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Sat Aug 16 02:22:21 2025
    From Newsgroup: comp.os.vms

    On Fri, 15 Aug 2025 19:48:14 -0400, Arne Vajh|+j wrote:

    In general I like the idea of writing code in a way that does not
    require the reader to have memorized ten thousand things from the
    language spec.

    What language spec has room for ten thousand things in it, anyway?

    .

    .

    .

    .

    .

    .

    ... oh, Java.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Sat Aug 16 13:20:43 2025
    From Newsgroup: comp.os.vms

    On 8/15/2025 6:42 PM, Lawrence DrCOOliveiro wrote:
    On Fri, 15 Aug 2025 09:55:17 -0400, Arne Vajh|+j wrote:
    But I believe most curly bracket languages inherited from C in this
    regard.

    Python took over the C operator hierarchy, with one subtle little
    twist. It slightly tweaked the precedence of the bitwise operators
    relative to the comparisons, so you donrCOt need parentheses in
    expressions like

    (C) (-2val-+ & -2bitmask-+) == -2testvalue-+
    (Python) -2val-+ & -2bitmask-+ == -2testvalue-+

    I have asked on comp.lang.c whether any existing C code could be
    broken by making the same change in that language. In principle it
    could, but nobody could come up with any real-world examples.

    What about:

    if(reperr & sys$put(&rab, 0, 0) != RMS$_NORMAL)
    {
    printf("Houston we have a problem\n");
    }

    ?

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Sat Aug 16 19:31:56 2025
    From Newsgroup: comp.os.vms

    On 8/15/2025 10:22 PM, Lawrence DrCOOliveiro wrote:
    On Fri, 15 Aug 2025 19:48:14 -0400, Arne Vajh|+j wrote:

    In general I like the idea of writing code in a way that does not
    require the reader to have memorized ten thousand things from the
    language spec.

    What language spec has room for ten thousand things in it, anyway?

    ... oh, Java.

    Language specs for modern languages tend to be pretty big.

    Java 21 is 872 pages (no library)
    C 23 is 761 pages (basic library)
    C++ 11 is 1334 pages (basic library)
    Fortran 2018 is 646 pages (basic library)
    Cobol 2014 is 923 pages (basic library)
    Ada 2012 is 951 pages (basic library)
    C# 6.0 is 639 pages (no library)

    Arne








    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Sun Aug 17 00:52:11 2025
    From Newsgroup: comp.os.vms

    On Sat, 16 Aug 2025 19:31:56 -0400, Arne Vajh|+j wrote:

    On 8/15/2025 10:22 PM, Lawrence DrCOOliveiro wrote:

    On Fri, 15 Aug 2025 19:48:14 -0400, Arne Vajh|+j wrote:

    In general I like the idea of writing code in a way that does not
    require the reader to have memorized ten thousand things from the
    language spec.

    What language spec has room for ten thousand things in it, anyway?

    ... oh, Java.

    Language specs for modern languages tend to be pretty big.

    Python is as rCLmodernrCY as they come, and its core language spec is only a fraction the size of any of those -- even including builtin functions and types, it would be no more than a couple hundred pages.

    And remember, it manages to include multiple inheritance, operator overloading, metaclasses, functions and classes as first-class objects
    with lexical binding (i.e. no need for generics), async/await, arbitrary- precision integers, Unicode strings as distinct from bytes objects, and descriptors.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From hb0815@mw40171@mucweb.de to comp.os.vms on Sun Aug 17 17:24:47 2025
    From Newsgroup: comp.os.vms

    On 8/15/25 02:33, Arne Vajh|+j wrote:
    On 8/12/2025 11:09 PM, Lawrence D'Oliveiro wrote:
    On Tue, 12 Aug 2025 19:08:51 -0400, Arne Vajh|+j wrote:
    mysql055_root:[lib.alpha]libclientlib/lib
    mysql055_root:[lib.alpha]libsql/lib
    mysql055_root:[lib.alpha]libmysys/lib
    mysql055_root:[lib.alpha]libdbug/lib
    mysql055_root:[lib.alpha]libstrings/lib
    mysql055_root:[lib.alpha]libvio/lib
    mysql055_root:[lib.alpha]libz/lib
    mysql055_root:[lib.alpha]ssl_libssl32/lib
    mysql055_root:[lib.alpha]ssl_libcrypto32/lib

    Is there some equivalent to rCL-L-2dir-+rCY to add a common directory to a >> linker search path so you can just shorten most of that to something
    more like rCL-lclientlib -lsql -lmysys -ldbug -lstrings -lvio -lzrCY?

    ...
    You can omit location on all libraries except the first and
    let the sticky default mechanism add it.

    (I don't think that is a nice solution)

    I know, the discussion moved on/away from this subtopic ...

    You may not like it, but using the file specification stickiness or RMS related name context processing is the only useful method to avoid
    repeating the directory specification. This works on the command line as
    well as in option files. And you can have more than one library on a
    single option line, anyway.

    Redefining SYS$DISK or merging the libraries into a local copy of
    STARLET.OLB can also avoid this, and both are fun to try. But they are
    only hacks.

    If you have GNV, you can use its linker wrapper. However, it requires
    naming the object libraries in Unix style. Although a "libfoo.olb"
    works, there is no way to use an "foo.olb" (and you can't easily get a
    full map with cross references). So this will not work for ssl_* in the
    shown link command. Yeah, you can create (symbolic) links ...

    You can setup default libraries with LNK$LIBRARY* logicals.

    In your example you would need 9 logicals: LNK$LIBRARY, LNK$LIBRARY_1,
    ..., LNK$LIBRARY_8. There is no _0 and they must all be defined. The
    suffixes must start with 1 and must not have a gap in numbering. You
    can't use a search list. Additionally, the link command line doesn't
    show that non-system object libraries are used at all.

    You can create shareable images and stuff all of them into
    a shareable library.

    Then the resulting image or application is no longer "statically"
    linked: you need the shareable image at runtime. You have to create a shareable with as many universal symbols, aka symbol vector entries, as
    global symbols in the libraries - just to avoid specifying a couple of
    file paths in the link command.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Sun Aug 17 13:52:59 2025
    From Newsgroup: comp.os.vms

    On 8/17/2025 11:24 AM, hb0815 wrote:
    On 8/15/25 02:33, Arne Vajh|+j wrote:
    On 8/12/2025 11:09 PM, Lawrence D'Oliveiro wrote:
    On Tue, 12 Aug 2025 19:08:51 -0400, Arne Vajh|+j wrote:
    mysql055_root:[lib.alpha]libclientlib/lib
    mysql055_root:[lib.alpha]libsql/lib
    mysql055_root:[lib.alpha]libmysys/lib
    mysql055_root:[lib.alpha]libdbug/lib
    mysql055_root:[lib.alpha]libstrings/lib
    mysql055_root:[lib.alpha]libvio/lib
    mysql055_root:[lib.alpha]libz/lib
    mysql055_root:[lib.alpha]ssl_libssl32/lib
    mysql055_root:[lib.alpha]ssl_libcrypto32/lib

    Is there some equivalent to rCL-L-2dir-+rCY to add a common directory to a >>> linker search path so you can just shorten most of that to something
    more like rCL-lclientlib -lsql -lmysys -ldbug -lstrings -lvio -lzrCY?

    ...
    You can omit location on all libraries except the first and
    let the sticky default mechanism add it.

    (I don't think that is a nice solution)

    You may not like it, but using the file specification stickiness or RMS related name context processing is the only useful method to avoid
    repeating the directory specification. This works on the command line as well as in option files. And you can have more than one library on a
    single option line, anyway.

    It can be used.

    But if someone edit the list and either remove libraries or
    add libraries, then it is pretty easy to mess up.

    If you have GNV, you can use its linker wrapper. However, it requires
    naming the object libraries in Unix style. Although a "libfoo.olb"
    works, there is no way to use an "foo.olb" (and you can't easily get a
    full map with cross references). So this will not work for ssl_* in the shown link command. Yeah, you can create (symbolic) links ...

    I did not even consider GNV.

    You can setup default libraries with LNK$LIBRARY* logicals.

    In your example you would need 9 logicals: LNK$LIBRARY,
    LNK$LIBRARY_1, ..., LNK$LIBRARY_8. There is no _0 and-a they must all be defined. The suffixes must start with 1 and must not have a gap in numbering. You can't use a search list. Additionally, the link command
    line doesn't show that non-system object libraries are used at all.

    It is an option that I considered relevant for the question on
    how to shorten link commands.

    I would not use it in this case.

    As an old Fortran programmer then I find it quite natural that
    it starts with _1 and not _0.

    :-)

    You can create shareable images and stuff all of them into
    a shareable library.

    Then the resulting image or application is no longer "statically"
    linked: you need the shareable image at runtime. You have to create a shareable with as many universal symbols, aka symbol vector entries, as global symbols in the libraries - just to avoid specifying a couple of
    file paths in the link command.

    There is no free lunch.

    It is an option for the question on how to shorten link commands.

    I would not use it in this case either.

    I don't even think I have ever created such a shareable library. But
    everyone is using one (IMAGELIB).

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris Townley@news@cct-net.co.uk to comp.os.vms on Sun Aug 17 19:45:47 2025
    From Newsgroup: comp.os.vms

    On 17/08/2025 18:52, Arne Vajh|+j wrote:
    On 8/17/2025 11:24 AM, hb0815 wrote:
    On 8/15/25 02:33, Arne Vajh|+j wrote:
    On 8/12/2025 11:09 PM, Lawrence D'Oliveiro wrote:
    On Tue, 12 Aug 2025 19:08:51 -0400, Arne Vajh|+j wrote:
    mysql055_root:[lib.alpha]libclientlib/lib
    mysql055_root:[lib.alpha]libsql/lib
    mysql055_root:[lib.alpha]libmysys/lib
    mysql055_root:[lib.alpha]libdbug/lib
    mysql055_root:[lib.alpha]libstrings/lib
    mysql055_root:[lib.alpha]libvio/lib
    mysql055_root:[lib.alpha]libz/lib
    mysql055_root:[lib.alpha]ssl_libssl32/lib
    mysql055_root:[lib.alpha]ssl_libcrypto32/lib

    Is there some equivalent to rCL-L-2dir-+rCY to add a common directory to a >>>> linker search path so you can just shorten most of that to something
    more like rCL-lclientlib -lsql -lmysys -ldbug -lstrings -lvio -lzrCY?

    ...
    You can omit location on all libraries except the first and
    let the sticky default mechanism add it.

    (I don't think that is a nice solution)

    You may not like it, but using the file specification stickiness or
    RMS related name context processing is the only useful method to avoid
    repeating the directory specification. This works on the command line
    as well as in option files. And you can have more than one library on
    a single option line, anyway.

    It can be used.

    But if someone edit the list and either remove libraries or
    add libraries, then it is pretty easy to mess up.

    If you have GNV, you can use its linker wrapper. However, it requires
    naming the object libraries in Unix style. Although a "libfoo.olb"
    works, there is no way to use an "foo.olb" (and you can't easily get a
    full map with cross references). So this will not work for ssl_* in
    the shown link command. Yeah, you can create (symbolic) links ...

    I did not even consider GNV.

    You can setup default libraries with LNK$LIBRARY* logicals.

    In your example you would need 9 logicals: LNK$LIBRARY,
    LNK$LIBRARY_1, ..., LNK$LIBRARY_8. There is no _0 and-a they must all
    be defined. The suffixes must start with 1 and must not have a gap in
    numbering. You can't use a search list. Additionally, the link command
    line doesn't show that non-system object libraries are used at all.

    It is an option that I considered relevant for the question on
    how to shorten link commands.

    I would not use it in this case.

    As an old Fortran programmer then I find it quite natural that
    it starts with _1 and not _0.

    :-)

    You can create shareable images and stuff all of them into
    a shareable library.

    Then the resulting image or application is no longer "statically"
    linked: you need the shareable image at runtime. You have to create a
    shareable with as many universal symbols, aka symbol vector entries,
    as global symbols in the libraries - just to avoid specifying a couple
    of file paths in the link command.

    There is no free lunch.

    It is an option for the question on how to shorten link commands.

    I would not use it in this case either.

    I don't even think I have ever created such a shareable library. But
    everyone is using one (IMAGELIB).

    Arne

    Can you not use make, MMK (or equiv) utility?
    --
    Chris
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From hb0815@mw40171@mucweb.de to comp.os.vms on Sun Aug 17 22:48:10 2025
    From Newsgroup: comp.os.vms

    On 8/17/25 19:52, Arne Vajh|+j wrote:

    It is an option for the question on how to shorten link commands.

    I would not use it in this case either.

    I don't even think I have ever created such a shareable library. But
    everyone is using one (IMAGELIB).

    Shareable image libraries can be used on the link command line. So far
    so shortened. But you still have to create the shareable images from the object libraries. And you still need the shareable images at runtime: imagelib.olb contains universal symbols (often named symbol vector
    entries) and a pointer to the shareables that defines them.

    Make, MMK (or equiv) don't generate shareable images. They may be able
    to find out if an element in the shareable image libraries needs to be updated. That's all I would expect.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Sun Aug 17 19:57:33 2025
    From Newsgroup: comp.os.vms

    On 8/17/2025 2:45 PM, Chris Townley wrote:
    Can you not use make, MMK (or equiv) utility?

    Of course.

    But I don't know if it helps.

    It may - I have very little experience with MMS and MMK.

    But the basic DESCRIP.MMS of:

    mylib = some_root:[lib]
    ...
    link test + $(mylib)a/lib + $(mylib)b/lib + $(mylib)c/lib

    seems just equivalent of the DCL:

    $ mylib = "some_root:[lib]"
    ...
    $ link test + 'mylib'a/lib + 'mylib'b/lib + 'mylib'c/lib

    Arne



    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Mon Aug 18 12:14:53 2025
    From Newsgroup: comp.os.vms

    On 2025-08-16, Arne Vajhoj <arne@vajhoej.dk> wrote:
    On 8/15/2025 6:42 PM, Lawrence D?Oliveiro wrote:
    On Fri, 15 Aug 2025 09:55:17 -0400, Arne Vajhoj wrote:
    But I believe most curly bracket languages inherited from C in this
    regard.

    Python took over the C operator hierarchy, with one subtle little
    twist. It slightly tweaked the precedence of the bitwise operators
    relative to the comparisons, so you don?t need parentheses in
    expressions like

    (C) (2val+ & 2bitmask+) == 2testvalue+
    (Python) 2val+ & 2bitmask+ == 2testvalue+

    I have asked on comp.lang.c whether any existing C code could be
    broken by making the same change in that language. In principle it
    could, but nobody could come up with any real-world examples.

    What about:

    if(reperr & sys$put(&rab, 0, 0) != RMS$_NORMAL)
    {
    printf("Houston we have a problem\n");
    }


    And it's crap like that which means I tend to ignore operator precedence
    and place all subexpressions in brackets (nested if needed).

    It avoids stuff like this and makes it _extremely_ clear in the code
    what the intention is (and makes it easier to read BTW).

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Mon Aug 18 12:37:44 2025
    From Newsgroup: comp.os.vms

    On 2025-08-15, Arne Vajhoj <arne@vajhoej.dk> wrote:

    In general I like the idea of writing code in a way that does
    not require the reader to have memorized ten thousand things from
    the language spec.

    But I do not consider this a matter of remembering the specific
    details about an operator - I consider this a matter of remembering
    what operator a symbol represent.

    I consider "short circuiting AND" and "non short circuiting AND"
    to be two different operators.


    They are not. One is a subset of the other and both carry out the
    same core operation.

    And in C then && is the first operator not the second operator.

    And understanding what operator each symbol represent is not
    detail but core. IMHO.


    I disagree. Strongly. Both operators do exactly the same thing which
    is to implement a logical AND. Code written using this operator
    generates exactly the same logical AND result regardless of whether
    short circuiting is in use or not.

    In addition however, a short circuiting compiler generates code to
    stop evaluation if the previous logical AND subexpression was false.
    This is a feature of the compiler and does not turn logical AND into
    something which does something other than logical AND.

    It is _always_ safe to write code which assumes short circuiting is
    not in use and it will work exactly the same even in the presence
    of a compiler which generates short circuiting code.

    It's all about writing robust code, not clever code. My approach
    generates much more robust code, especially when you might translate
    the code to another language that does not implement short circuiting
    and you don't realise this during the translation.

    I prefer that approach to having to maintain a fragile matrix in my
    head of what specific language or compiler implements short circuiting
    and which do not.

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 18 15:21:07 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 8:14 AM, Simon Clubley wrote:
    On 2025-08-16, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/15/2025 6:42 PM, Lawrence D?Oliveiro wrote:
    On Fri, 15 Aug 2025 09:55:17 -0400, Arne Vajh|+j wrote:
    But I believe most curly bracket languages inherited from C in this
    regard.

    Python took over the C operator hierarchy, with one subtle little
    twist. It slightly tweaked the precedence of the bitwise operators
    relative to the comparisons, so you don?t need parentheses in
    expressions like

    (C) (-2val-+ & -2bitmask-+) == -2testvalue-+
    (Python) -2val-+ & -2bitmask-+ == -2testvalue-+

    I have asked on comp.lang.c whether any existing C code could be
    broken by making the same change in that language. In principle it
    could, but nobody could come up with any real-world examples.

    What about:

    if(reperr & sys$put(&rab, 0, 0) != RMS$_NORMAL)
    {
    printf("Houston we have a problem\n");
    }


    And it's crap like that which means I tend to ignore operator precedence
    and place all subexpressions in brackets (nested if needed).

    It avoids stuff like this and makes it _extremely_ clear in the code
    what the intention is (and makes it easier to read BTW).

    There are two separate questions.

    Should one use parentheses to specify evaluation explicit
    instead of relying on operator precedence?

    I do think so. The above is not good code.

    I like the Java Coding Convention section 10.5.1:

    <quote>
    10.5.1 Parentheses
    It is generally a good idea to use parentheses liberally in expressions involving mixed operators
    to avoid operator precedence problems. Even if the operator precedence
    seems clear to you, it
    might not be to othersrCoyou shouldnrCOt assume that other programmers know precedence as
    well as you do.
    if (a == b && c == d) // AVOID!
    if ((a == b) && (c == d)) // RIGHT
    </quote>

    Is it OK for a language to change operator precedence, because the
    change would only make a difference for code not following good
    style?

    I don't think so.

    Changing behavior of existing code is not acceptable. Not even
    for bad style code.

    I know a few languages has made such changes (changing behavior of
    existing code - not specifically changing operator precedence).

    But I still don't like it.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 18 15:42:49 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 8:37 AM, Simon Clubley wrote:
    On 2025-08-15, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    In general I like the idea of writing code in a way that does
    not require the reader to have memorized ten thousand things from
    the language spec.

    But I do not consider this a matter of remembering the specific
    details about an operator - I consider this a matter of remembering
    what operator a symbol represent.

    I consider "short circuiting AND" and "non short circuiting AND"
    to be two different operators.

    They are not. One is a subset of the other and both carry out the
    same core operation.

    And in C then && is the first operator not the second operator.

    And understanding what operator each symbol represent is not
    detail but core. IMHO.


    I disagree. Strongly. Both operators do exactly the same thing which
    is to implement a logical AND. Code written using this operator
    generates exactly the same logical AND result regardless of whether
    short circuiting is in use or not.

    In addition however, a short circuiting compiler generates code to
    stop evaluation if the previous logical AND subexpression was false.
    This is a feature of the compiler and does not turn logical AND into something which does something other than logical AND.

    Considering two operators the same because the functionality of one is
    a subset of the functionality of the other seems unlogical to me.

    C += vs C =
    PHP == vs PHP ===
    etc.

    It is _always_ safe to write code which assumes short circuiting is
    not in use and it will work exactly the same even in the presence
    of a compiler which generates short circuiting code.

    Not true.

    Not if the second expression has side effects.

    I am sure that you don't want expressions with side effect. But
    it happens.

    It's all about writing robust code, not clever code. My approach
    generates much more robust code, especially when you might translate
    the code to another language that does not implement short circuiting
    and you don't realise this during the translation.

    I agree with the philosophy in general.

    But I have little faith in trying to translate from one language
    to another language without deep understanding of operators in the
    two languages.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 18 15:55:23 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 3:42 PM, Arne Vajh|+j wrote:
    On 8/18/2025 8:37 AM, Simon Clubley wrote:
    On 2025-08-15, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    In general I like the idea of writing code in a way that does
    not require the reader to have memorized ten thousand things from
    the language spec.

    But I do not consider this a matter of remembering the specific
    details about an operator - I consider this a matter of remembering
    what operator a symbol represent.

    I consider "short circuiting AND" and "non short circuiting AND"
    to be two different operators.

    They are not. One is a subset of the other and both carry out the
    same core operation.

    And in C then && is the first operator not the second operator.

    And understanding what operator each symbol represent is not
    detail but core. IMHO.


    I disagree. Strongly. Both operators do exactly the same thing which
    is to implement a logical AND. Code written using this operator
    generates exactly the same logical AND result regardless of whether
    short circuiting is in use or not.

    In addition however, a short circuiting compiler generates code to
    stop evaluation if the previous logical AND subexpression was false.
    This is a feature of the compiler and does not turn logical AND into
    something which does something other than logical AND.

    Considering two operators the same because the functionality of one is
    a subset of the functionality of the other seems unlogical to me.
    And some languages have both operators.

    C is a bit messy. Pun intended.

    But John already mentioned VMS Pascal:

    https://docs.vmssoftware.com/vsi-pascal-for-openvms-reference-manual/#LOGICAL_OP_SEC

    and I mentioned VB.NET:

    https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/logical-bitwise-operators

    Arne


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 18 16:14:52 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 3:42 PM, Arne Vajh|+j wrote:
    On 8/18/2025 8:37 AM, Simon Clubley wrote:
    It is _always_ safe to write code which assumes short circuiting is
    not in use and it will work exactly the same even in the presence
    of a compiler which generates short circuiting code.

    Not true.

    Not if the second expression has side effects.

    I am sure that you don't want expressions with side effect. But
    it happens.

    Function calls is a classic example of potential side
    effect, but many languages allow assignments in expressions.

    Python 3.8 introduced the walrus operator.

    $ type se1.py
    def f():
    print('f called')
    return False

    print('first')
    if False and f():
    print('problem')
    print('second')
    if False & f():
    print('problem')
    $ python se1.py
    first
    second
    f called
    $ type se2.py
    v = 0
    print(v)
    print('first')
    if False and (v := v + 1) > 100:
    print('problem')
    print(v)
    print('second')
    if False & (v := v + 1) > 100:
    print('problem')
    print(v)
    $ python se2.py
    0
    first
    0
    second
    1

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Mon Aug 18 21:57:40 2025
    From Newsgroup: comp.os.vms

    In article <107nr15$18f8f$1@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-15, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <107n93n$13rjm$1@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-12, Arne Vajhoj <arne@vajhoej.dk> wrote:
    Code:

    #include <string.h>

    #include <mysql.h>

    my_bool demo_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
    {
    if(args->arg_count == 2 && args->arg_type[0] == STRING_RESULT && >>>> args->arg_type[1] == INT_RESULT)

    Is it guaranteed that arg_type[] will always have at least elements ?
    If not, that's dangerous unless the compiler you are using does >>>expression short-circuiting.

    C is well-defined in this regard. Boolean expressions in C,
    created by combining logical subexpressions with the `&&` and
    `||` operators, are documented to use short-circuiting behavior.


    Thank you.

    Sure thing!

    Unless it's explicit in the language syntax itself, and given that
    I write code in multiple languages, I have long written code that
    assumes implicit[*] short-circuiting is not available.

    Huh, interesting. I suppose my take is that I have an
    obligation to learn the idioms of a given language, if I am
    writing code in that language, and this feels like one that is
    useful to know about.

    To each their own, I suppose.

    As such, whether implicit short-circuiting is available or not is
    not really that important to me, but I will admit I didn't realise
    C had it.

    I suppose if one's particular style is to program as if
    short-circuiting were not part of the langauge, then fair
    enough.

    As for C, this particular aspect is documented as far back as
    the "C Reference Manual" included in volume 2 of the 6th Edition
    Unix Programmer's Manual. So only a little over 50 years. :-D

    [*] By implicit short-circuiting I mean something that's only defined
    in the language standard or implemented in a compiler, instead of some >explicit syntax in the language itself to state short-circuiting is >available.

    Fair.

    However, I must disagree strongly with the advice to use
    `strncpy`, which is poorly understood and has strange semantics:
    it will write as much of the source string to the destination as
    it can, with or without the NUL terminating byte. If the source
    is smaller than the destination buffer, then the remainder of
    the buffer will be filled with 0s. If the source is exactly as
    long as, or longer, than the destination, then the destination
    will not be NUL-terminated. Since it just returns the
    destination pointer, there is no way to detect truncation other
    than to test the last byte in the destination to see whether it
    is zero or not. So it is inefficent in the common case, and
    dangerous and awkward in the exceptional case. Moreover, its
    behavior is orthogonal to that of `strncat`, which does _not_
    have the "write 0s to all bytes in the destination past the end
    of the what we copied from the source string", and is also
    awkward in how it treats it's length argument: whereas for
    `strncpy` the length argument is the size of the entire
    destination buffer, for `strncat` it is not: `strncat` will
    write up to n+1 bytes into the destination.

    strncpy() makes more sense when you realise that its original purpose
    was to fill fixed-size fields in a record with data and to clear the
    rest of the field if the source data was smaller than the field size.

    Yup. I'd heard that it was created to fill in the directory
    name portion of directory entries in early versions of the Unix
    kernel, but that's apochryphal. `strncpy` first appears in Unix
    distributions with the 7th Edition, and it _is_ used in a few
    places to create directory names, but those are all in user
    programs, not the kernel. Specifically, it is used in the
    `mkdir` _command_, but to create a path name that refers to the
    parent of the to-be-created directory so that the command can
    check for permission to create the directory (note there's a
    TOCTOU bug here). Anyway, I suspect that's the origin of the
    rumor.

    Personally, I think the name has been a disservice. It probably
    should have been called `fldscpy` or something like that to make
    clear it was intended for copying string data into fixed-size
    fields.

    BTW, after using strncpy(), my code always unconditionally places
    a 0x00 in the final byte of the buffer "just in case :-)".

    A wise idea, if you're going to use `strncpy` at all other than
    for its original intended purpose. But, unless you want to
    ensure that the rest of the destination buffer is fully zeroed,
    I'd just bring in one of the other, safer, string copy routines.
    I'll bet cummulatively, it's less code to import the "shortest
    version of strlcpy" and "shortest version of strlcat" from the
    slides given at ATC (available the OpenBSD web site) than to add `foo[sizeof(foo)-1]=0;` in $n$ different places. https://www.openbsd.org/papers/strlcpy-slides.pdf

    Or, better yet, write less C and use safer languages. :-D

    - Dan C.

    Lightly edited version from the slides:

    size_t
    strlcpy(char *dst, const char *src, size_t siz)
    {
    size_t slen = strlen(src);

    if (siz != 0) {
    size_t n = siz - 1;
    if (slen < n)
    n = slen;
    memcpy(dst, src, n);
    dst[n] = A\0A;
    }

    return(slen);
    }

    size_t
    strlcat(char *dst, const char *src, size_t siz)
    {
    size_t dlen = strlen(dst);

    /* Make sure siz is sane */
    if (siz < dlen + 1)
    return(dlen + strlen(src));

    return(dlen + strlcpy(dst + dlen, src, siz - dlen));
    }
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Mon Aug 18 22:24:21 2025
    From Newsgroup: comp.os.vms

    In article <107r4db$1vod3$3@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/15/2025 10:22 PM, Lawrence DrCOOliveiro wrote:
    On Fri, 15 Aug 2025 19:48:14 -0400, Arne Vajh|+j wrote:

    In general I like the idea of writing code in a way that does not
    require the reader to have memorized ten thousand things from the
    language spec.

    What language spec has room for ten thousand things in it, anyway?

    ... oh, Java.

    Language specs for modern languages tend to be pretty big.

    Java 21 is 872 pages (no library)
    C 23 is 761 pages (basic library)

    Much of that is examples, footnotes, and handling bizarre edge
    cases that happen as a result of the fact that C never had (and
    never will have) formal semantics, and so instead the spec
    defines and targets an "abstract virtual machine" that often
    doesn't map to real harware.

    C++ 11 is 1334 pages (basic library)
    Fortran 2018 is 646 pages (basic library)
    Cobol 2014 is 923 pages (basic library)
    Ada 2012 is 951 pages (basic library)
    C# 6.0 is 639 pages (no library)

    It's important to note that all of these specifications are
    intended primarily for compiler writers, not end users of the
    langauge (read: most programmers). While e.g. the C standard
    _is_ the final word on the language, most C programmers don't
    need to consult it on a daily basis, if ever.

    The size of a spec may be a useful proxy for describing the
    complexity of the language, or it may not. It really depends on
    the language.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 18 19:11:48 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 3:42 PM, Arne Vajh|+j wrote:
    On 8/18/2025 8:37 AM, Simon Clubley wrote:
    It's all about writing robust code, not clever code. My approach
    generates much more robust code, especially when you might translate
    the code to another language that does not implement short circuiting
    and you don't realise this during the translation.

    I agree with the philosophy in general.

    But I have little faith in trying to translate from one language
    to another language without deep understanding of operators in the
    two languages.

    As warning:

    $ type op.c
    #include <stdio.h>

    int main(int argc, char *argv[])
    {
    int iv = 5;
    printf("%d %d\n", iv / 2, iv % 2);
    return 0;
    }
    $ cc op
    $ link op
    $ run op
    2 1
    $ type op.pas
    program op(input,output);

    var
    iv : integer;

    begin
    iv := 5;
    writeln(iv / 2, ' ', iv mod 2);
    end.
    $ pas op
    $ lin op
    $ run op
    2.50000E+00 1
    $ type op.for
    program op
    integer*4 iv
    iv = 5
    write(*,*) iv / 2, iv mod 2
    end
    $ for op
    $ lin op
    $ run op
    2 0

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Mon Aug 18 23:27:53 2025
    From Newsgroup: comp.os.vms

    In article <68a3b334$0$713$14726298@news.sunsite.dk>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/18/2025 3:42 PM, Arne Vajh|+j wrote:
    On 8/18/2025 8:37 AM, Simon Clubley wrote:
    It's all about writing robust code, not clever code. My approach
    generates much more robust code, especially when you might translate
    the code to another language that does not implement short circuiting
    and you don't realise this during the translation.

    I agree with the philosophy in general.

    But I have little faith in trying to translate from one language
    to another language without deep understanding of operators in the
    two languages.

    As warning:

    $ type op.c
    #include <stdio.h>

    int main(int argc, char *argv[])
    {
    int iv = 5;
    printf("%d %d\n", iv / 2, iv % 2);
    return 0;
    }
    $ cc op
    $ link op
    $ run op
    2 1
    $ type op.pas
    program op(input,output);

    var
    iv : integer;

    begin
    iv := 5;
    writeln(iv / 2, ' ', iv mod 2);
    end.
    $ pas op
    $ lin op
    $ run op
    2.50000E+00 1

    Of course. In pascal, integer division is spelled, `div`, not
    `/`. Why would one expect otherwise?

    - Dan C.

    $ type op.for
    program op
    integer*4 iv
    iv = 5
    write(*,*) iv / 2, iv mod 2
    end
    $ for op
    $ lin op
    $ run op
    2 0

    Here, FORTRAN has type promotion rules that require one of the
    operands of the `/` binary operator to be of a real type before
    the operation is performed as a real. iv/2.0 would give the
    floating point result, for FORTRAN-77 and later.

    And of course, `iv mod 2` should be, `mod(iv, 2)`.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 18 19:38:40 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 7:27 PM, Dan Cross wrote:
    In article <68a3b334$0$713$14726298@news.sunsite.dk>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/18/2025 3:42 PM, Arne Vajh|+j wrote:
    On 8/18/2025 8:37 AM, Simon Clubley wrote:
    It's all about writing robust code, not clever code. My approach
    generates much more robust code, especially when you might translate
    the code to another language that does not implement short circuiting
    and you don't realise this during the translation.

    I agree with the philosophy in general.

    But I have little faith in trying to translate from one language
    to another language without deep understanding of operators in the
    two languages.

    As warning:

    $ cc op
    $ link op
    $ run op
    2 1

    $ pas op
    $ lin op
    $ run op
    2.50000E+00 1

    Of course. In pascal, integer division is spelled, `div`, not
    `/`. Why would one expect otherwise?
    $ for op
    $ lin op
    $ run op
    2 0

    Here, FORTRAN has type promotion rules that require one of the
    operands of the `/` binary operator to be of a real type before
    the operation is performed as a real. iv/2.0 would give the
    floating point result, for FORTRAN-77 and later.

    And of course, `iv mod 2` should be, `mod(iv, 2)`.

    Yes.

    But point is that one need to know something about the
    languages.

    Just picking an operator that "looks like" and hope it
    has similar semantics is no good.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Mon Aug 18 23:45:39 2025
    From Newsgroup: comp.os.vms

    On Mon, 18 Aug 2025 15:21:07 -0400, Arne Vajh|+j wrote:

    Should one use parentheses to specify evaluation explicit instead of
    relying on operator precedence?

    I do think so.

    Parentheses are best used lightly -- where needed, maybe a little bit more than that, and thatrCOs it.

    Otherwise parenthesis clutter introduces its own obstacles to readability.

    Even if the operator precedence seems clear to you, it might not be
    to othersrCoyou shouldnrCOt assume that other programmers know
    precedence as well as you do.

    I assume that they are just as able to read the spec as you are.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 18 19:48:16 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 7:45 PM, Lawrence DrCOOliveiro wrote:
    On Mon, 18 Aug 2025 15:21:07 -0400, Arne Vajh|+j wrote:
    Should one use parentheses to specify evaluation explicit instead of
    relying on operator precedence?

    I do think so.

    Parentheses are best used lightly -- where needed, maybe a little bit more than that, and thatrCOs it.

    Otherwise parenthesis clutter introduces its own obstacles to readability.

    That is not the mantra among people who try to prevent future errors.

    Even if the operator precedence seems clear to you, it might not be
    to othersrCoyou shouldnrCOt assume that other programmers know
    precedence as well as you do.

    I assume that they are just as able to read the spec as you are.

    able to <> will

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Mon Aug 18 23:48:38 2025
    From Newsgroup: comp.os.vms

    On Mon, 18 Aug 2025 15:42:49 -0400, Arne Vajh|+j wrote:

    C += vs C =

    Inconsistency: if rCL==rCY is equality comparison, and rCL!rCY denotes logical negation, why isnrCOt the inequality operator rCL!==rCY? Because rCL!=rCY looks like
    it follows the pattern of rCLa -2op-+= brCY being a short form for rCLa = a -2op-+
    brCY.

    PHP == vs PHP ===

    Why do PHP and Java need the separate rCL===rCY operator in addition to rCL==rCY,
    when Python does not?
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Mon Aug 18 23:52:37 2025
    From Newsgroup: comp.os.vms

    On Mon, 18 Aug 2025 19:11:48 -0400, Arne Vajh|+j wrote:

    printf("%d %d\n", iv / 2, iv % 2);

    The interpretation in C of rCL/rCY being an integer operation with integer operands, and float otherwise, is generally regarded as a Bad Idea. I
    think it caught the infection from Fortran.

    Python actually started out following this interpretation, then changed to always returning a float, introducing the additional separate rCL//rCY operator for when you explicitly want integer division.

    Even PHP, bad as it is in other ways, did not follow the C mistake.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 18 19:54:00 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 7:48 PM, Lawrence DrCOOliveiro wrote:
    On Mon, 18 Aug 2025 15:42:49 -0400, Arne Vajh|+j wrote:
    C += vs C =

    Inconsistency: if rCL==rCY is equality comparison, and rCL!rCY denotes logical
    negation, why isnrCOt the inequality operator rCL!==rCY? Because rCL!=rCY looks like
    it follows the pattern of rCLa -2op-+= brCY being a short form for rCLa = a -2op-+
    brCY.

    That is not related to the point.

    PHP == vs PHP ===

    Why do PHP and Java need the separate rCL===rCY operator in addition to rCL==rCY,
    when Python does not?

    Java does not have a === operator.

    PHP has both == and === operators. === behave like one would
    expect. == is a little "helpful" to allow developers to shoot
    themselves in the foot.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Mon Aug 18 23:59:44 2025
    From Newsgroup: comp.os.vms

    On Mon, 18 Aug 2025 19:48:16 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:45 PM, Lawrence DrCOOliveiro wrote:

    On Mon, 18 Aug 2025 15:21:07 -0400, Arne Vajh|+j wrote:

    Should one use parentheses to specify evaluation explicit instead of
    relying on operator precedence?

    I do think so.

    Parentheses are best used lightly -- where needed, maybe a little bit
    more than that, and thatrCOs it.

    Otherwise parenthesis clutter introduces its own obstacles to
    readability.

    That is not the mantra among people who try to prevent future errors.

    There are people who just repeat what they are told, arenrCOt there, instead of learning from actual experience.

    Even if the operator precedence seems clear to you, it might not be to
    othersrCoyou shouldnrCOt assume that other programmers know precedence as >>> well as you do.

    I assume that they are just as able to read the spec as you are.

    able to <> will

    LetrCOs just say, my code gives them the incentive to do so.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 18 20:18:25 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 3:21 PM, Arne Vajh|+j wrote:
    Is it OK for a language to change operator precedence, because the
    change would only make a difference for code not following good
    style?

    I don't think so.

    Changing behavior of existing code is not acceptable. Not even
    for bad style code.

    I know a few languages has made such changes (changing behavior of
    existing code - not specifically changing operator precedence).

    But I still don't like it.

    Everybody know about Python 2.x to 3.x change of / operator semtantics
    (from integer division to floating point division).

    Less known is how Scala changed statement block definition from 2.x
    to 3.x:

    $ type Blk1.scala
    object Blk1 {
    def main(args: Array[String]): Unit = {
    val flag = false;
    if(flag) {
    println("flag true")
    }
    println("done")
    }
    }
    $ scalac """-version"""
    Scala compiler version 2.13.11 -- Copyright 2002-2023, LAMP/EPFL and Lightbend, Inc.
    $ scalac Blk1.scala
    $ java -cp .:/disk0/net/scala/scala-2.13.11/lib/* Blk1
    done
    $ scala3c """-version"""
    Scala compiler version 3.3.0 -- Copyright 2002-2023, LAMP/EPFL
    $ scala3c Blk1.scala
    $ java -cp .:/disk0/net/scala3/scala3-3.3.0/lib/* Blk1
    done
    $ type Blk2.scala
    object Blk2 {
    def main(args: Array[String]): Unit = {
    val flag = false;
    if(flag)
    println("flag true")
    println("done")
    }
    }
    $ scalac """-version"""
    Scala compiler version 2.13.11 -- Copyright 2002-2023, LAMP/EPFL and Lightbend, Inc.
    $ scalac Blk2.scala
    $ java -cp .:/disk0/net/scala/scala-2.13.11/lib/* Blk2
    done
    $ scala3c """-version"""
    Scala compiler version 3.3.0 -- Copyright 2002-2023, LAMP/EPFL
    $ scala3c Blk2.scala
    $ java -cp .:/disk0/net/scala3/scala3-3.3.0/lib/* Blk2
    done
    $ type Blk3.scala
    object Blk3 {
    def main(args: Array[String]): Unit = {
    val flag = false;
    if(flag)
    println("flag true")
    println("done")
    }
    }
    $ scalac """-version"""
    Scala compiler version 2.13.11 -- Copyright 2002-2023, LAMP/EPFL and Lightbend, Inc.
    $ scalac Blk3.scala
    $ java -cp .:/disk0/net/scala/scala-2.13.11/lib/* Blk3
    done
    $ scala3c """-version"""
    Scala compiler version 3.3.0 -- Copyright 2002-2023, LAMP/EPFL
    $ scala3c Blk3.scala
    $ java -cp .:/disk0/net/scala3/scala3-3.3.0/lib/* Blk3
    $

    WTF?

    Arne

    PS: Yes - both Scala 2.13 and 3.3 runs fine on VMS. For 3.3 source files
    must be rfm:stmlf.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 18 20:22:11 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 7:52 PM, Lawrence DrCOOliveiro wrote:
    On Mon, 18 Aug 2025 19:11:48 -0400, Arne Vajh|+j wrote:

    printf("%d %d\n", iv / 2, iv % 2);

    The interpretation in C of rCL/rCY being an integer operation with integer operands, and float otherwise, is generally regarded as a Bad Idea. I
    think it caught the infection from Fortran.

    Python actually started out following this interpretation, then changed to always returning a float, introducing the additional separate rCL//rCY operator for when you explicitly want integer division.

    Even PHP, bad as it is in other ways, did not follow the C mistake.

    Are there any languages invented the last 20 years that does
    not do integer division for two integer operands?

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 18 20:47:08 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 8:18 PM, Arne Vajh|+j wrote:
    PS: Yes - both Scala 2.13 and 3.3 runs fine on VMS. For 3.3 source files
    -a-a-a must be rfm:stmlf.

    And the Scala 3.x how to:

    $ typ scala.com
    $ p1 = f$edit(p1, "UPCASE")
    $ clz = ""
    $ if p1 .eqs. "COMPILE" then clz = "dotty.tools.MainGenericCompiler"
    $ if p1 .eqs. "RUNNER" then clz = "dotty.tools.MainGenericRunner"
    $ if p1 .eqs. "DOC" then clz = "dotty.tools.scaladoc.Main"
    $ parent = "/disk0/net/scala3"
    $ ver = "3.3.0"
    $ scalahome = "''parent'/scala3-''ver'"
    $ xmx = "''scala_xmx'"
    $ if xmx .eqs. "" then xmx = "256m"
    $ cp = "''scala_cp'"
    $ if cp .nes. "" then cp = ":" + cp
    $ java -
    "-Xmx''xmx'" -
    "-Dscala.home=''scalahome'" -
    "-Dscala.usejavacp=true" -
    -cp "''scalahome'/lib/*''cp'" -
    "''clz'" -
    'p2' 'p3' 'p4' 'p5' 'p6' 'p7' 'p8'
    $ if p1 .eqs. "COMPILE" .and. f$env("depth") .le. 1 then write
    sys$output "Run with java -cp .:''cp'''scalahome'/lib/*''cp' <main-class>"
    $ exit
    $ type scaladef.com
    $ proc = f$env("procedure")
    $ defdir = f$parse(proc,,,"device") + f$parse(proc,,,"directory")
    $ scala3c :== @'defdir'scala.com compile
    $ scala3 :== @'defdir'scala.com runner
    $ scala3doc :== @'defdir'scala.com doc
    $ exit

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Tue Aug 19 00:48:52 2025
    From Newsgroup: comp.os.vms

    In article <68a3b980$0$713$14726298@news.sunsite.dk>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/18/2025 7:27 PM, Dan Cross wrote:
    In article <68a3b334$0$713$14726298@news.sunsite.dk>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/18/2025 3:42 PM, Arne Vajh|+j wrote:
    On 8/18/2025 8:37 AM, Simon Clubley wrote:
    It's all about writing robust code, not clever code. My approach
    generates much more robust code, especially when you might translate >>>>> the code to another language that does not implement short circuiting >>>>> and you don't realise this during the translation.

    I agree with the philosophy in general.

    But I have little faith in trying to translate from one language
    to another language without deep understanding of operators in the
    two languages.

    As warning:

    $ cc op
    $ link op
    $ run op
    2 1

    $ pas op
    $ lin op
    $ run op
    2.50000E+00 1

    Of course. In pascal, integer division is spelled, `div`, not
    `/`. Why would one expect otherwise?
    $ for op
    $ lin op
    $ run op
    2 0

    Here, FORTRAN has type promotion rules that require one of the
    operands of the `/` binary operator to be of a real type before
    the operation is performed as a real. iv/2.0 would give the
    floating point result, for FORTRAN-77 and later.

    And of course, `iv mod 2` should be, `mod(iv, 2)`.

    Yes.

    But point is that one need to know something about the
    languages.

    Just picking an operator that "looks like" and hope it
    has similar semantics is no good.

    This seems like a very extreme example. There is a scale of
    knowledge when it comes to programming languages, from the basic
    ways in which one does various things like write loops or
    perform basic arithmetic, to the minutia of specific library or
    IO routines, with semantics of specific operators and how they
    combine probably somewhere in the middle.

    I happen to disagree with Simon's notion of what makes for
    robust programming, but to go to such an extreme as to suggest
    that writing code as if logical operators don't short-circuit
    is the same as not knowing the semantics of division is
    specious.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 18 21:04:43 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 8:48 PM, Dan Cross wrote:
    In article <68a3b980$0$713$14726298@news.sunsite.dk>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    But point is that one need to know something about the
    languages.

    Just picking an operator that "looks like" and hope it
    has similar semantics is no good.

    This seems like a very extreme example. There is a scale of
    knowledge when it comes to programming languages, from the basic
    ways in which one does various things like write loops or
    perform basic arithmetic, to the minutia of specific library or
    IO routines, with semantics of specific operators and how they
    combine probably somewhere in the middle.

    I happen to disagree with Simon's notion of what makes for
    robust programming, but to go to such an extreme as to suggest
    that writing code as if logical operators don't short-circuit
    is the same as not knowing the semantics of division is
    specious.

    There are 4 operations:
    - short circuiting and
    - non short circuiting and
    - integer division
    - floating point division

    Both source and target language has a way of doing those: operator,
    function or a more complex expression.

    I agree that the risk of someone not understanding "division"
    ways is much less than the risk of someone not understanding
    "and" ways.

    But in the end the team doing the translation need to understand
    all operations to do a correct translation.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Tue Aug 19 01:13:06 2025
    From Newsgroup: comp.os.vms

    On Mon, 18 Aug 2025 21:04:43 -0400, Arne Vajh|+j wrote:

    I agree that the risk of someone not understanding "division"
    ways is much less than the risk of someone not understanding "and" ways.

    People still get confused by the subtleties of binary floating-point arithmetic. e.g.

    Python 3.13.5 (main, Jun 25 2025, 18:55:22) [GCC 14.2.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import math
    >>> math.cos(math.pi / 2)
    6.123233995736766e-17
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 18 21:49:29 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 7:59 PM, Lawrence DrCOOliveiro wrote:
    On Mon, 18 Aug 2025 19:48:16 -0400, Arne Vajh|+j wrote:
    On 8/18/2025 7:45 PM, Lawrence DrCOOliveiro wrote:
    On Mon, 18 Aug 2025 15:21:07 -0400, Arne Vajh|+j wrote:

    Should one use parentheses to specify evaluation explicit instead of
    relying on operator precedence?

    I do think so.

    Parentheses are best used lightly -- where needed, maybe a little bit
    more than that, and thatrCOs it.

    Otherwise parenthesis clutter introduces its own obstacles to
    readability.

    That is not the mantra among people who try to prevent future errors.

    There are people who just repeat what they are told, arenrCOt there, instead of learning from actual experience.

    It is the recommendation from people with actual experience.

    One book that recommend it is "The Practice of Programming".
    Brian Kernighan and Rob Pike.

    Arne


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Tue Aug 19 03:00:22 2025
    From Newsgroup: comp.os.vms

    On Mon, 18 Aug 2025 21:49:29 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:59 PM, Lawrence DrCOOliveiro wrote:

    On Mon, 18 Aug 2025 19:48:16 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:45 PM, Lawrence DrCOOliveiro wrote:

    Parentheses are best used lightly -- where needed, maybe a little
    bit more than that, and thatrCOs it.

    Otherwise parenthesis clutter introduces its own obstacles to
    readability.

    That is not the mantra among people who try to prevent future
    errors.

    There are people who just repeat what they are told, arenrCOt there,
    instead of learning from actual experience.

    It is the recommendation from people with actual experience.

    One book that recommend it is "The Practice of Programming".
    Brian Kernighan and Rob Pike.

    One wonders how much experience they really have, across how many
    different languages.

    For example, consider some Lisp code. Here is a function of mine, not
    laid out the way I would usually write it, but in something
    approximating traditional Lisp layout:

    (defun cur-line (ensure-newline)
    (mstr
    "returns list of two character positions, representing the"
    " beginning and end of the selection if there is one, else"
    " the beginning and end of the current line. ensure-newline"
    " => ensures there is a newline at the end of the line.")
    (let (beg end)
    (cond
    ((use-region-p)
    (setq beg (min (point) (mark)))
    (setq end (max (point) (mark))))
    (t (save-excursion
    (setq beg (search-backward "\n" nil t))
    (cond
    (beg (setq beg (+ beg 1)))
    (t (setq beg (point-min))))
    (goto-char beg)
    (search-forward "\n" nil 1)
    (setq end (point)))))
    (when ensure-newline
    (deactivate-mark)
    (goto-char end)
    (unless (eq (char-before) 10)
    (insert "\n")
    (setq end (point))))
    (list beg end)))

    Here is the way I actually lay it out:

    (defun cur-line (ensure-newline)
    (mstr
    "returns list of two character positions, representing the"
    " beginning and end of the selection if there is one, else"
    " the beginning and end of the current line. ensure-newline"
    " => ensures there is a newline at the end of the line."
    )
    (let (beg end)
    (cond
    ((use-region-p)
    (setq beg (min (point) (mark)))
    (setq end (max (point) (mark)))
    )
    (t
    (save-excursion
    (setq beg (search-backward "\n" nil t))
    (cond
    (beg
    (setq beg (+ beg 1))
    )
    (t
    (setq beg (point-min))
    )
    ) ; cond
    (goto-char beg)
    (search-forward "\n" nil 1)
    (setq end (point))
    ) ; save-excursion
    )
    ) ; cond
    (when ensure-newline
    (deactivate-mark)
    (goto-char end)
    (unless (eq (char-before) 10)
    (insert "\n")
    (setq end (point))
    ) ; unless
    ) ; when
    (list beg end)
    ) ; let
    ) ; defun cur-line

    Which would you prefer?
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Tue Aug 19 03:23:36 2025
    From Newsgroup: comp.os.vms

    In article <1080ijb$3dju4$4@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/18/2025 8:48 PM, Dan Cross wrote:
    In article <68a3b980$0$713$14726298@news.sunsite.dk>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    But point is that one need to know something about the
    languages.

    Just picking an operator that "looks like" and hope it
    has similar semantics is no good.

    This seems like a very extreme example. There is a scale of
    knowledge when it comes to programming languages, from the basic
    ways in which one does various things like write loops or
    perform basic arithmetic, to the minutia of specific library or
    IO routines, with semantics of specific operators and how they
    combine probably somewhere in the middle.

    I happen to disagree with Simon's notion of what makes for
    robust programming, but to go to such an extreme as to suggest
    that writing code as if logical operators don't short-circuit
    is the same as not knowing the semantics of division is
    specious.

    There are 4 operations:
    - short circuiting and
    - non short circuiting and
    - integer division
    - floating point division

    There are usually many more operations in any given programming
    language than just those four.

    Both source and target language has a way of doing those: operator,
    function or a more complex expression.

    I agree that the risk of someone not understanding "division"
    ways is much less than the risk of someone not understanding
    "and" ways.

    But in the end the team doing the translation need to understand
    all operations to do a correct translation.

    Yes. This is all part of knowing those programming languages.

    It seems obvious that if one is embarking on a project to
    rewrite an existing system in a different language, that one
    should staff the project with programmers who are competent in
    both the original and new languages. Further, I do not believe
    that anyone I would take seriously here[*] has suggested
    otherwise. You appear to be extrapolating a very specific
    statement on Simon's part to a conclusion that just follow.



    - Dan C.

    [*] Perhaps the troll has, but I don't take him seriously, and only
    see snippets of what he writes through the backspatter of people
    replying to him.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Tue Aug 19 12:20:57 2025
    From Newsgroup: comp.os.vms

    On 2025-08-18, Arne Vajhoj <arne@vajhoej.dk> wrote:

    Considering two operators the same because the functionality of one is
    a subset of the functionality of the other seems unlogical to me.


    The _core_ functionality is the same (ie: a logical AND in this case).

    C += vs C =

    This is not the same core functionality. Plus combined with assignment
    versus a simple assignment.

    PHP == vs PHP ===

    And those two are must certainly bloody well _NOT_ the same. :-)

    Loose comparison versus strict comparison (the latter is also called:
    how it is done in any sane language).

    The concept of loose comparison should not even exist and helps demonstrate just how lousy PHP really is when it comes to writing something important.

    When I write PHP code, I have a monitor routine I include via require_once
    that catches warnings which should be errors and turns them into the errors that they should be. It's crazy that I have to do that. :-(

    etc.

    It is _always_ safe to write code which assumes short circuiting is
    not in use and it will work exactly the same even in the presence
    of a compiler which generates short circuiting code.

    Not true.

    Not if the second expression has side effects.

    I am sure that you don't want expressions with side effect. But
    it happens.


    Tell me Arne, given what you now know about me, do you really think
    I would ever write code that had expression side effects like that ? :-)

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Tue Aug 19 12:29:46 2025
    From Newsgroup: comp.os.vms

    On 2025-08-18, Arne Vajhoj <arne@vajhoej.dk> wrote:
    On 8/18/2025 3:42 PM, Arne Vajhoj wrote:
    On 8/18/2025 8:37 AM, Simon Clubley wrote:
    It is _always_ safe to write code which assumes short circuiting is
    not in use and it will work exactly the same even in the presence
    of a compiler which generates short circuiting code.

    Not true.

    Not if the second expression has side effects.

    I am sure that you don't want expressions with side effect. But
    it happens.

    Function calls is a classic example of potential side
    effect, but many languages allow assignments in expressions.

    Python 3.8 introduced the walrus operator.


    Then Python has lost the plot. When you do ugly things like this, then
    the easier it is for subtle errors to slip in. Also, you write code once (hopefully), but read it many times.

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Tue Aug 19 12:42:43 2025
    From Newsgroup: comp.os.vms

    On 2025-08-18, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <107nr15$18f8f$1@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:

    Unless it's explicit in the language syntax itself, and given that
    I write code in multiple languages, I have long written code that
    assumes implicit[*] short-circuiting is not available.

    Huh, interesting. I suppose my take is that I have an
    obligation to learn the idioms of a given language, if I am
    writing code in that language, and this feels like one that is
    useful to know about.

    To each their own, I suppose.


    I write simple to understand code, not clever code, even when the
    problem it is solving is complex or has a lot of functionality
    built into the problem.

    I've found it makes code more robust and easier for others to read,
    especially when they may not have the knowledge you have when you
    wrote the original code.

    I certainly don't feel the need to write job security code or some
    "macho" desire to write dense and hard to understand code to order
    to try and demonstrate to others just how "smart" I am.

    I am not saying you are doing that BTW, but I've seen enough code
    written by others which was clearly written with that mindset.


    Or, better yet, write less C and use safer languages. :-D


    Unfortunately that's not really possible in many cases. I _strongly_
    wish a Wirth-style language had become the standard system integration
    and low-level language instead of C.

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Tue Aug 19 12:45:54 2025
    From Newsgroup: comp.os.vms

    On 2025-08-18, Arne Vajhoj <arne@vajhoej.dk> wrote:

    But point is that one need to know something about the
    languages.

    Just picking an operator that "looks like" and hope it
    has similar semantics is no good.


    Agreed.

    But also, knowing the language to a level that allows you to write
    robust code in it, is not the same as needing to be a language lawyer
    in order to be able to use that language.

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Tue Aug 19 12:56:24 2025
    From Newsgroup: comp.os.vms

    On 2025-08-18, Arne Vajhoj <arne@vajhoej.dk> wrote:

    Are there any languages invented the last 20 years that does
    not do integer division for two integer operands?


    Javascript's basic number data type is a floating point number. :-(

    Make of that what you will and also the mindset of someone who thought
    that was a good idea.

    Yes, I know Javascript is older than that but it's been through
    multiple standards processes.

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Tue Aug 19 13:01:56 2025
    From Newsgroup: comp.os.vms

    On 2025-08-18, Dan Cross <cross@spitfire.i.gajendra.net> wrote:

    I happen to disagree with Simon's notion of what makes for
    robust programming, but to go to such an extreme as to suggest
    that writing code as if logical operators don't short-circuit
    is the same as not knowing the semantics of division is
    specious.


    That last one is an interesting example. I may not care about
    short circuiting, but I am _very_ _very_ aware of the combined
    unsigned integers and signed integers issues in C expressions. :-(

    It also affects how I look at the same issues in other languages.

    I've mentioned this before, but I think languages should give you
    unsigned integers by default, and you should have to ask for
    a signed integer if you really want one.

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Tue Aug 19 14:09:02 2025
    From Newsgroup: comp.os.vms

    In article <1081sk3$3njqo$7@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-18, Dan Cross <cross@spitfire.i.gajendra.net> wrote:

    I happen to disagree with Simon's notion of what makes for
    robust programming, but to go to such an extreme as to suggest
    that writing code as if logical operators don't short-circuit
    is the same as not knowing the semantics of division is
    specious.

    That last one is an interesting example. I may not care about
    short circuiting, but I am _very_ _very_ aware of the combined
    unsigned integers and signed integers issues in C expressions. :-(

    It also affects how I look at the same issues in other languages.

    I've mentioned this before, but I think languages should give you
    unsigned integers by default, and you should have to ask for
    a signed integer if you really want one.

    Whether integers are signed or unsigned by default is not
    terribly interesting to me, but I do believe, strongly, that
    implicit type conversions as in C are a Bad Idea(TM), and I
    think that history has shown that view to be more or less
    correct; the only language that seems to get this approximately
    right is Haskell, using typeclasses, but that's not implicit
    coercion; it takes well-defined, strongly-typed functions that
    do explicit conversions internally, from the prelude.

    But that's Haskell. For most programming, if one wants to do
    arithmetic on operands of differing type, then one should be
    required to explicitly convert everything to a single, uniform
    type and live with whatever the semantics of that type are.

    This needn't be as tedious or verbose as it sounds; with a
    little bit of type inference, it can be quite succinct while
    still being safe and correct.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Tue Aug 19 14:25:34 2025
    From Newsgroup: comp.os.vms

    In article <1081rg2$3njqo$3@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-18, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <107nr15$18f8f$1@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:

    Unless it's explicit in the language syntax itself, and given that
    I write code in multiple languages, I have long written code that
    assumes implicit[*] short-circuiting is not available.

    Huh, interesting. I suppose my take is that I have an
    obligation to learn the idioms of a given language, if I am
    writing code in that language, and this feels like one that is
    useful to know about.

    To each their own, I suppose.

    I write simple to understand code, not clever code, even when the
    problem it is solving is complex or has a lot of functionality
    built into the problem.

    I've found it makes code more robust and easier for others to read, >especially when they may not have the knowledge you have when you
    wrote the original code.

    I'm curious how this expresses itself with respect to e.g. the
    short-circuiting thing, though. For instance, this might be
    common in C:

    struct something *p;
    ...
    if (p != NULL && p->ptr != NULL && something(*p->ptr)) {
    // Do something here.
    }

    This, of course, relies on short-circuiting to avoid
    dereferncing either `p` or `*p->ptr` if either is NULL. What
    is the alternative?

    if (p != NULL) {
    if (p->ptr != NULL) {
    if (something(*p->ptr)) {
    // Do something....
    }
    }
    }

    If I dare say so, this is strictly worse because the code is now
    much more heavily indented.

    Ken Thompson used to avoid things like this by writing such code
    as:

    if (p != NULL)
    if (p->ptr != NULL)
    if (something(p->ptr)) {
    // Do something....
    }

    Which has a certain elegance to it, but automated code
    formatters inevitably don't understand it (and at this point,
    one really ought to be using an automated formatter whenever
    possible).

    AN alternative might be to extract the conditional and put it
    into an auxiliary function, and use something similar to
    Dijkstra's guarded commands:

    void
    maybe_do_something(struct something *p)
    {
    if (p == NULL)
    return;
    if (p->ptr == NULL)
    return;
    if (!something(*p->ptr))
    return;
    // Now do something.
    }

    I would argue that this is better than the previous example, and
    possibly on par with or better than the original: if nothing
    else, it gives a name to the operation. This is of course just
    a contrived example, so the name here is meaningless, but one
    hopes that in a real program a name with some semantic meaning
    would be chosen.

    If one is in a loop, judicious use of `continue` or `break`
    might serve a similar purpose.

    But all of this feels like quite a bit of ceremony to avoid a
    common idiom in the language.

    I certainly don't feel the need to write job security code or some
    "macho" desire to write dense and hard to understand code to order
    to try and demonstrate to others just how "smart" I am.

    I am not saying you are doing that BTW, but I've seen enough code
    written by others which was clearly written with that mindset.

    I understand, and largely agree. There are programmers out
    there who seem to delight in writing difficult to understand
    code because they can, and because it provides them a vehicle
    to demonstrate their intelligence.

    Or, better yet, write less C and use safer languages. :-D

    Unfortunately that's not really possible in many cases. I _strongly_
    wish a Wirth-style language had become the standard system integration
    and low-level language instead of C.

    I confess I have a very soft spot for C: it was my first "real"
    language. In that sense, it reminds me of my first car: it was
    a clunker, but it got me around.

    That said, as much as I love C, I think it's best to avoid as
    much as possible. Realistically, _most_ programmers should be
    working in managed, safe languages with clear semantics..

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Tue Aug 19 10:45:44 2025
    From Newsgroup: comp.os.vms

    On 8/18/2025 11:00 PM, Lawrence DrCOOliveiro wrote:
    On Mon, 18 Aug 2025 21:49:29 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:59 PM, Lawrence DrCOOliveiro wrote:

    On Mon, 18 Aug 2025 19:48:16 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:45 PM, Lawrence DrCOOliveiro wrote:

    Parentheses are best used lightly -- where needed, maybe a little
    bit more than that, and thatrCOs it.

    Otherwise parenthesis clutter introduces its own obstacles to
    readability.

    That is not the mantra among people who try to prevent future
    errors.

    There are people who just repeat what they are told, arenrCOt there,
    instead of learning from actual experience.

    It is the recommendation from people with actual experience.

    One book that recommend it is "The Practice of Programming".
    Brian Kernighan and Rob Pike.

    One wonders how much experience they really have, across how many
    different languages.

    Brian Kernighan and Rob Pike? A lot! :-)

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Tue Aug 19 10:54:30 2025
    From Newsgroup: comp.os.vms

    On 8/19/2025 8:29 AM, Simon Clubley wrote:
    On 2025-08-18, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/18/2025 3:42 PM, Arne Vajh|+j wrote:
    On 8/18/2025 8:37 AM, Simon Clubley wrote:
    It is _always_ safe to write code which assumes short circuiting is
    not in use and it will work exactly the same even in the presence
    of a compiler which generates short circuiting code.

    Not true.

    Not if the second expression has side effects.

    I am sure that you don't want expressions with side effect. But
    it happens.

    Function calls is a classic example of potential side
    effect, but many languages allow assignments in expressions.

    Python 3.8 introduced the walrus operator.

    Then Python has lost the plot. When you do ugly things like this, then
    the easier it is for subtle errors to slip in. Also, you write code once (hopefully), but read it many times.

    Most languages allow the same just using plain assignment (*).

    Two points related to the fact that they have a special
    operator instead of just using plain assignment.

    1) That it got added later means that there must have been an
    explicit demand for such functionality unlike plain assignment
    that could have appeared "by accident".
    2) That it is a special operator also means that it is easy to
    search for either by tools or manually making it something to
    check for in code review.

    *) And not just C. For the first many years of Java's existence, the
    following was the way to read lines from a file:

    BufferedReader br = ..;
    String line;
    while((line = br.readLine()) != null) {
    ...
    }

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Tue Aug 19 10:58:26 2025
    From Newsgroup: comp.os.vms

    On 8/19/2025 9:01 AM, Simon Clubley wrote:
    On 2025-08-18, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    I happen to disagree with Simon's notion of what makes for
    robust programming, but to go to such an extreme as to suggest
    that writing code as if logical operators don't short-circuit
    is the same as not knowing the semantics of division is
    specious.


    That last one is an interesting example. I may not care about
    short circuiting, but I am _very_ _very_ aware of the combined
    unsigned integers and signed integers issues in C expressions. :-(

    It also affects how I look at the same issues in other languages.

    I've mentioned this before, but I think languages should give you
    unsigned integers by default, and you should have to ask for
    a signed integer if you really want one.

    "by default" sort of imply signedness being an attribute of
    same type.

    Why not just make it two different types with different names?

    Whether we follow tradition and call them integer and cardinal
    or more modern style and call them int and uint is less important.

    Arne



    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Tue Aug 19 11:00:22 2025
    From Newsgroup: comp.os.vms

    On 8/19/2025 8:56 AM, Simon Clubley wrote:
    On 2025-08-18, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Are there any languages invented the last 20 years that does
    not do integer division for two integer operands?

    Javascript's basic number data type is a floating point number. :-(

    Make of that what you will and also the mindset of someone who thought
    that was a good idea.

    Yes, I know Javascript is older than that but it's been through
    multiple standards processes.

    Yes. But too late to change something as fundamental.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Tue Aug 19 11:03:43 2025
    From Newsgroup: comp.os.vms

    On 8/19/2025 8:20 AM, Simon Clubley wrote:
    On 2025-08-18, Arne Vajh|+j <arne@vajhoej.dk> wrote:
    It is _always_ safe to write code which assumes short circuiting is
    not in use and it will work exactly the same even in the presence
    of a compiler which generates short circuiting code.

    Not true.

    Not if the second expression has side effects.

    I am sure that you don't want expressions with side effect. But
    it happens.

    Tell me Arne, given what you now know about me, do you really think
    I would ever write code that had expression side effects like that ? :-)

    I am sure you don't want to do that. As I wrote.

    But what about the guy sitting next to you working on the same project?

    Unless you have a coding convention against it and use a static code
    analyzer to enforce the rule, then it could happen.

    You should not assume everybody on the project write code the same
    way as you.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Tue Aug 19 11:10:37 2025
    From Newsgroup: comp.os.vms

    On 8/19/2025 10:09 AM, Dan Cross wrote:
    In article <1081sk3$3njqo$7@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-18, Dan Cross <cross@spitfire.i.gajendra.net> wrote:

    I happen to disagree with Simon's notion of what makes for
    robust programming, but to go to such an extreme as to suggest
    that writing code as if logical operators don't short-circuit
    is the same as not knowing the semantics of division is
    specious.

    That last one is an interesting example. I may not care about
    short circuiting, but I am _very_ _very_ aware of the combined
    unsigned integers and signed integers issues in C expressions. :-(

    It also affects how I look at the same issues in other languages.

    I've mentioned this before, but I think languages should give you
    unsigned integers by default, and you should have to ask for
    a signed integer if you really want one.

    Whether integers are signed or unsigned by default is not
    terribly interesting to me, but I do believe, strongly, that
    implicit type conversions as in C are a Bad Idea(TM), and I
    think that history has shown that view to be more or less
    correct; the only language that seems to get this approximately
    right is Haskell, using typeclasses, but that's not implicit
    coercion; it takes well-defined, strongly-typed functions that
    do explicit conversions internally, from the prelude.

    But that's Haskell. For most programming, if one wants to do
    arithmetic on operands of differing type, then one should be
    required to explicitly convert everything to a single, uniform
    type and live with whatever the semantics of that type are.

    This needn't be as tedious or verbose as it sounds; with a
    little bit of type inference, it can be quite succinct while
    still being safe and correct.

    Kotlin is rather picky about mixing signed and unsigned.

    var v: UInt = 16u

    v = v / 2

    gives an error.

    v = v / 2u
    v = v / 2.toUInt()

    works.

    I consider that rather picky.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris Townley@news@cct-net.co.uk to comp.os.vms on Tue Aug 19 16:19:16 2025
    From Newsgroup: comp.os.vms

    On 19/08/2025 16:10, Arne Vajh|+j wrote:
    On 8/19/2025 10:09 AM, Dan Cross wrote:
    In article <1081sk3$3njqo$7@dont-email.me>,
    Simon Clubley-a <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-18, Dan Cross <cross@spitfire.i.gajendra.net> wrote:

    I happen to disagree with Simon's notion of what makes for
    robust programming, but to go to such an extreme as to suggest
    that writing code as if logical operators don't short-circuit
    is the same as not knowing the semantics of division is
    specious.

    That last one is an interesting example. I may not care about
    short circuiting, but I am _very_ _very_ aware of the combined
    unsigned integers and signed integers issues in C expressions. :-(

    It also affects how I look at the same issues in other languages.

    I've mentioned this before, but I think languages should give you
    unsigned integers by default, and you should have to ask for
    a signed integer if you really want one.

    Whether integers are signed or unsigned by default is not
    terribly interesting to me, but I do believe, strongly, that
    implicit type conversions as in C are a Bad Idea(TM), and I
    think that history has shown that view to be more or less
    correct; the only language that seems to get this approximately
    right is Haskell, using typeclasses, but that's not implicit
    coercion; it takes well-defined, strongly-typed functions that
    do explicit conversions internally, from the prelude.

    But that's Haskell.-a For most programming, if one wants to do
    arithmetic on operands of differing type, then one should be
    required to explicitly convert everything to a single, uniform
    type and live with whatever the semantics of that type are.

    This needn't be as tedious or verbose as it sounds; with a
    little bit of type inference, it can be quite succinct while
    still being safe and correct.

    Kotlin is rather picky about mixing signed and unsigned.

    var v: UInt = 16u

    v = v / 2

    gives an error.

    v = v / 2u
    v = v / 2.toUInt()

    works.

    I consider that rather picky.

    Arne

    Ada as nearly as bad, although that would work, It relies on the
    programmer making an explicit conversion
    --
    Chris
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Tue Aug 19 11:23:38 2025
    From Newsgroup: comp.os.vms

    On 8/19/2025 11:19 AM, Chris Townley wrote:
    On 19/08/2025 16:10, Arne Vajh|+j wrote:
    On 8/19/2025 10:09 AM, Dan Cross wrote:
    Whether integers are signed or unsigned by default is not
    terribly interesting to me, but I do believe, strongly, that
    implicit type conversions as in C are a Bad Idea(TM), and I
    think that history has shown that view to be more or less
    correct; the only language that seems to get this approximately
    right is Haskell, using typeclasses, but that's not implicit
    coercion; it takes well-defined, strongly-typed functions that
    do explicit conversions internally, from the prelude.

    But that's Haskell.-a For most programming, if one wants to do
    arithmetic on operands of differing type, then one should be
    required to explicitly convert everything to a single, uniform
    type and live with whatever the semantics of that type are.

    This needn't be as tedious or verbose as it sounds; with a
    little bit of type inference, it can be quite succinct while
    still being safe and correct.

    Kotlin is rather picky about mixing signed and unsigned.

    var v: UInt = 16u

    v = v / 2

    gives an error.

    v = v / 2u
    v = v / 2.toUInt()

    works.

    I consider that rather picky.
    Ada as nearly as bad, although that would work, It relies on the
    programmer making an explicit conversion

    Just for the record then I do not consider it bad.

    Arne




    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Tue Aug 19 11:25:39 2025
    From Newsgroup: comp.os.vms

    On 8/19/2025 11:10 AM, Arne Vajh|+j wrote:
    Kotlin is rather picky about mixing signed and unsigned.

    var v: UInt = 16u

    v = v / 2

    gives an error.

    v = v / 2u
    v = v / 2.toUInt()

    works.

    I consider that rather picky.

    Note that Kotlin run on VMS.

    At least 1.x - I have not tried 2.x yet.

    And source files must be rfm:stmlf.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Tue Aug 19 16:07:13 2025
    From Newsgroup: comp.os.vms

    In article <10822mn$3pb8v$1@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/18/2025 11:00 PM, Lawrence DrCOOliveiro wrote:
    On Mon, 18 Aug 2025 21:49:29 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:59 PM, Lawrence DrCOOliveiro wrote:

    On Mon, 18 Aug 2025 19:48:16 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:45 PM, Lawrence DrCOOliveiro wrote:

    Parentheses are best used lightly -- where needed, maybe a little
    bit more than that, and thatrCOs it.

    Otherwise parenthesis clutter introduces its own obstacles to
    readability.

    That is not the mantra among people who try to prevent future
    errors.

    There are people who just repeat what they are told, arenrCOt there,
    instead of learning from actual experience.

    It is the recommendation from people with actual experience.

    One book that recommend it is "The Practice of Programming".
    Brian Kernighan and Rob Pike.

    One wonders how much experience they really have, across how many
    different languages.

    (Wow.)

    Brian Kernighan and Rob Pike? A lot! :-)

    It may help to read what they actually wrote in TPoP; on page 6:

    |_Parenthesize to resolve ambiguity_. Parentheses specify
    |grouping and can be used to make the intent clear even when
    |they are not required. The inner parentheses in the previous
    |example are not necessary, but they don't hurt, either.
    |Seasoned programmers might omit them, because the relational
    |operators (< <= == != >= >) have higher precedence than the
    |logical operators (&& and ||).
    |
    |When mixing unrelated operators, though, it's a good idea to
    |parenthesize. C and its friends present pernicious precedence
    |problems, and it's easy to make a mistake.

    For reference, the "previous example" they mention here is:

    if ((block_id >= actblks) || (block_id < unblocks))

    Most C programmers would write this as,

    if (block_id >= actblks || block_id < unblocks)

    And Kernighan and Pike would be fine with that. It must be
    noted that, throughout the rest of TPoP, they rarely
    parenthesize as aggressively as they do in that one example.
    For example, on page 98, in the discussion of building a CSV
    file parser interface, they present a function called,
    `advquoted` that contains this line of code:

    if (pj] == '"' && p[++j] != '"') {
    ...
    }

    (Note this doesn't just omit parenthesis, but also makes use of
    the pre-increment operator _and_ boolean short-circuiting.)

    Pike is famous for brevity; his 1989 document, "Notes on
    Programming in C" is a model here: http://www.literateprogramming.com/pikestyle.pdf

    Even now, it's still an interesting read. I like my own code
    princples, as well, but of course, I'm biased: https://pub.gajendra.net/2016/03/code_principles

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Tue Aug 19 17:04:38 2025
    From Newsgroup: comp.os.vms

    In article <68a493ec$0$710$14726298@news.sunsite.dk>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/19/2025 10:09 AM, Dan Cross wrote:
    In article <1081sk3$3njqo$7@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-18, Dan Cross <cross@spitfire.i.gajendra.net> wrote:

    I happen to disagree with Simon's notion of what makes for
    robust programming, but to go to such an extreme as to suggest
    that writing code as if logical operators don't short-circuit
    is the same as not knowing the semantics of division is
    specious.

    That last one is an interesting example. I may not care about
    short circuiting, but I am _very_ _very_ aware of the combined
    unsigned integers and signed integers issues in C expressions. :-(

    It also affects how I look at the same issues in other languages.

    I've mentioned this before, but I think languages should give you
    unsigned integers by default, and you should have to ask for
    a signed integer if you really want one.

    Whether integers are signed or unsigned by default is not
    terribly interesting to me, but I do believe, strongly, that
    implicit type conversions as in C are a Bad Idea(TM), and I
    think that history has shown that view to be more or less
    correct; the only language that seems to get this approximately
    right is Haskell, using typeclasses, but that's not implicit
    coercion; it takes well-defined, strongly-typed functions that
    do explicit conversions internally, from the prelude.

    But that's Haskell. For most programming, if one wants to do
    arithmetic on operands of differing type, then one should be
    required to explicitly convert everything to a single, uniform
    type and live with whatever the semantics of that type are.

    This needn't be as tedious or verbose as it sounds; with a
    little bit of type inference, it can be quite succinct while
    still being safe and correct.

    Kotlin is rather picky about mixing signed and unsigned.

    var v: UInt = 16u

    v = v / 2

    gives an error.

    v = v / 2u
    v = v / 2.toUInt()

    works.

    I consider that rather picky.

    It's kind of annoying that it can't infer to use unsigned for
    the '2' in the first example. Rust, for example, does do that
    inference which makes most arithmetic very natural.

    Rust's type inference is extended Hindley-Milner, but it's not
    as expressive as, say, SML.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Tue Aug 19 17:26:59 2025
    From Newsgroup: comp.os.vms

    In article <10823ei$3pb8v$3@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/19/2025 9:01 AM, Simon Clubley wrote:
    On 2025-08-18, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    I happen to disagree with Simon's notion of what makes for
    robust programming, but to go to such an extreme as to suggest
    that writing code as if logical operators don't short-circuit
    is the same as not knowing the semantics of division is
    specious.


    That last one is an interesting example. I may not care about
    short circuiting, but I am _very_ _very_ aware of the combined
    unsigned integers and signed integers issues in C expressions. :-(

    It also affects how I look at the same issues in other languages.

    I've mentioned this before, but I think languages should give you
    unsigned integers by default, and you should have to ask for
    a signed integer if you really want one.

    "by default" sort of imply signedness being an attribute of
    same type.

    Why not just make it two different types with different names?

    I gathered Simon was referring to the type assigned to manifest
    constants like 0, 1, or 2 (or 1024, 4096, or whatever). What
    type is such a literal? Signed or unsigned? How wide is it?
    In C (for example) it's `int` unless it's too big to fit into an
    `int`, in which case it's `unsigned int`. But how big is `int`?
    THAT depends on the target platform, and so it can be difficult
    to reason about the semantics of a program just from reading the
    code.

    And despite the old admonition to make everything a symbolic
    constant, things like `2 * pi * r` are perfectly readable, and
    I'd argue that `TWO * pi * r` are less so.

    Whether we follow tradition and call them integer and cardinal
    or more modern style and call them int and uint is less important.

    I would argue that, at this point, there's little need for a
    generic "int" type anymore, and that types representing integers
    as understood by the machine should explicitly include both
    signedness and width. An exception may be something like,
    `size_t`, which is platform-dependent, but when transferred
    externally should be given an explicit size. A lot of the
    guesswork and folklore that goes into understanding the
    semantics of those things just disappears when you're explicit.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris Townley@news@cct-net.co.uk to comp.os.vms on Tue Aug 19 21:08:59 2025
    From Newsgroup: comp.os.vms

    On 19/08/2025 17:07, Dan Cross wrote:
    In article <10822mn$3pb8v$1@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/18/2025 11:00 PM, Lawrence DrCOOliveiro wrote:
    On Mon, 18 Aug 2025 21:49:29 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:59 PM, Lawrence DrCOOliveiro wrote:

    On Mon, 18 Aug 2025 19:48:16 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:45 PM, Lawrence DrCOOliveiro wrote:

    Parentheses are best used lightly -- where needed, maybe a little >>>>>>> bit more than that, and thatrCOs it.

    Otherwise parenthesis clutter introduces its own obstacles to
    readability.

    That is not the mantra among people who try to prevent future
    errors.

    There are people who just repeat what they are told, arenrCOt there, >>>>> instead of learning from actual experience.

    It is the recommendation from people with actual experience.

    One book that recommend it is "The Practice of Programming".
    Brian Kernighan and Rob Pike.

    One wonders how much experience they really have, across how many
    different languages.

    (Wow.)

    Brian Kernighan and Rob Pike? A lot! :-)

    It may help to read what they actually wrote in TPoP; on page 6:

    |_Parenthesize to resolve ambiguity_. Parentheses specify
    |grouping and can be used to make the intent clear even when
    |they are not required. The inner parentheses in the previous
    |example are not necessary, but they don't hurt, either.
    |Seasoned programmers might omit them, because the relational
    |operators (< <= == != >= >) have higher precedence than the
    |logical operators (&& and ||).
    |
    |When mixing unrelated operators, though, it's a good idea to
    |parenthesize. C and its friends present pernicious precedence
    |problems, and it's easy to make a mistake.

    For reference, the "previous example" they mention here is:

    if ((block_id >= actblks) || (block_id < unblocks))

    Most C programmers would write this as,

    if (block_id >= actblks || block_id < unblocks)

    And Kernighan and Pike would be fine with that. It must be
    noted that, throughout the rest of TPoP, they rarely
    parenthesize as aggressively as they do in that one example.
    For example, on page 98, in the discussion of building a CSV
    file parser interface, they present a function called,
    `advquoted` that contains this line of code:

    if (pj] == '"' && p[++j] != '"') {
    ...
    }

    (Note this doesn't just omit parenthesis, but also makes use of
    the pre-increment operator _and_ boolean short-circuiting.)

    Pike is famous for brevity; his 1989 document, "Notes on
    Programming in C" is a model here: http://www.literateprogramming.com/pikestyle.pdf

    Even now, it's still an interesting read. I like my own code
    princples, as well, but of course, I'm biased: https://pub.gajendra.net/2016/03/code_principles

    - Dan C.


    Interestingly I have just come across an old bit of DEC Basic code:

    REPORT.ONLY = W.S4 = "R" ! Global flag

    I know what it does, but I would wrapped the knuckles of any programmer
    who did that on my shift!
    --
    Chris
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Wed Aug 20 01:11:05 2025
    From Newsgroup: comp.os.vms

    On Tue, 19 Aug 2025 10:54:30 -0400, Arne Vajh|+j wrote:

    Two points related to the fact that they have a special operator instead
    of just using plain assignment.

    ItrCOs yet another mechanism for local scoping within an expression. Python doesnrCOt allow statement blocks within expressions, but it has for- expressions where the for-variables are strictly local to the expression.

    To this has been added the walrus. But the walrus is (mostly) unnecessary;
    you can use a for-expression that iterates over just one value, to get the same effect.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Wed Aug 20 03:18:47 2025
    From Newsgroup: comp.os.vms

    On Tue, 19 Aug 2025 10:45:44 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 11:00 PM, Lawrence DrCOOliveiro wrote:

    One wonders how much experience they really have, across how many
    different languages.

    Brian Kernighan and Rob Pike? A lot! :-)

    Maybe not Lisp, though. Else they would not be so sanguine about
    parentheses.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Wed Aug 20 12:08:21 2025
    From Newsgroup: comp.os.vms

    On 2025-08-19, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <68a493ec$0$710$14726298@news.sunsite.dk>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:

    Kotlin is rather picky about mixing signed and unsigned.

    var v: UInt = 16u

    v = v / 2

    gives an error.

    v = v / 2u
    v = v / 2.toUInt()

    works.

    I consider that rather picky.

    I've not used Kotlin, but I consider that to be the really good type
    of picky. :-)


    It's kind of annoying that it can't infer to use unsigned for
    the '2' in the first example. Rust, for example, does do that
    inference which makes most arithmetic very natural.


    I actually consider that to be a good thing. The programmer is forced
    to think about what they have written and to change it to make those
    intentions explicit in the code. I like this.

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Wed Aug 20 12:27:01 2025
    From Newsgroup: comp.os.vms

    On 2025-08-19, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <1081rg2$3njqo$3@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:

    I write simple to understand code, not clever code, even when the
    problem it is solving is complex or has a lot of functionality
    built into the problem.

    I've found it makes code more robust and easier for others to read, >>especially when they may not have the knowledge you have when you
    wrote the original code.

    I'm curious how this expresses itself with respect to e.g. the short-circuiting thing, though. For instance, this might be
    common in C:

    struct something *p;
    ...
    if (p != NULL && p->ptr != NULL && something(*p->ptr)) {
    // Do something here.
    }

    This, of course, relies on short-circuiting to avoid
    dereferncing either `p` or `*p->ptr` if either is NULL. What
    is the alternative?

    if (p != NULL) {
    if (p->ptr != NULL) {
    if (something(*p->ptr)) {
    // Do something....
    }
    }
    }

    If I dare say so, this is strictly worse because the code is now
    much more heavily indented.

    Indented properly (not as in your next example!) I find that very
    readable and is mostly how I would write it although I do use code
    like your return example when appropriate. This is my variant:

    if (p != NULL)
    {
    if (p->ptr != NULL)
    {
    if (something(*p->ptr))
    {
    // Do something....
    }
    }
    }

    In case that doesn't survive a NNTP client, it is in Whitesmiths format:

    https://en.wikipedia.org/wiki/Indentation_style#Whitesmiths

    I like to spread out code vertically as I find it is easier to read.
    We are no longer in the era of VT50/52/100 terminals. :-)


    Ken Thompson used to avoid things like this by writing such code
    as:

    if (p != NULL)
    if (p->ptr != NULL)
    if (something(p->ptr)) {
    // Do something....
    }


    YUCK * 1000!!! That's horrible!!! :-)

    Which has a certain elegance to it, but automated code
    formatters inevitably don't understand it (and at this point,
    one really ought to be using an automated formatter whenever
    possible).

    AN alternative might be to extract the conditional and put it
    into an auxiliary function, and use something similar to
    Dijkstra's guarded commands:

    void
    maybe_do_something(struct something *p)
    {
    if (p == NULL)
    return;
    if (p->ptr == NULL)
    return;
    if (!something(*p->ptr))
    return;
    // Now do something.
    }

    I would argue that this is better than the previous example, and
    possibly on par with or better than the original: if nothing
    else, it gives a name to the operation. This is of course just
    a contrived example, so the name here is meaningless, but one
    hopes that in a real program a name with some semantic meaning
    would be chosen.


    There is one difference for me here however. _All_ single conditional statements as in the above example are placed in braces to help avoid
    the possibility of a later editing error.

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Wed Aug 20 12:34:19 2025
    From Newsgroup: comp.os.vms

    On 2025-08-19, Dan Cross <cross@spitfire.i.gajendra.net> wrote:

    Even now, it's still an interesting read. I like my own code
    princples, as well, but of course, I'm biased: https://pub.gajendra.net/2016/03/code_principles


    I've just read through that document and agree with everything there.
    I was especially amused by the write for readability and it will be
    read many times comments as I use that wording myself.

    I am surprised you are picking me up on some things however, given
    the mindset expressed in that document. Perhaps your idea of readability
    is different from mine. :-)

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Wed Aug 20 15:03:46 2025
    From Newsgroup: comp.os.vms

    In article <1082lks$3nmtt$2@dont-email.me>,
    Chris Townley <news@cct-net.co.uk> wrote:
    On 19/08/2025 17:07, Dan Cross wrote:
    In article <10822mn$3pb8v$1@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/18/2025 11:00 PM, Lawrence DrCOOliveiro wrote:
    On Mon, 18 Aug 2025 21:49:29 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:59 PM, Lawrence DrCOOliveiro wrote:

    On Mon, 18 Aug 2025 19:48:16 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:45 PM, Lawrence DrCOOliveiro wrote:

    Parentheses are best used lightly -- where needed, maybe a little >>>>>>>> bit more than that, and thatrCOs it.

    Otherwise parenthesis clutter introduces its own obstacles to
    readability.

    That is not the mantra among people who try to prevent future
    errors.

    There are people who just repeat what they are told, arenrCOt there, >>>>>> instead of learning from actual experience.

    It is the recommendation from people with actual experience.

    One book that recommend it is "The Practice of Programming".
    Brian Kernighan and Rob Pike.

    One wonders how much experience they really have, across how many
    different languages.

    (Wow.)

    Brian Kernighan and Rob Pike? A lot! :-)

    It may help to read what they actually wrote in TPoP; on page 6:

    |_Parenthesize to resolve ambiguity_. Parentheses specify
    |grouping and can be used to make the intent clear even when
    |they are not required. The inner parentheses in the previous
    |example are not necessary, but they don't hurt, either.
    |Seasoned programmers might omit them, because the relational
    |operators (< <= == != >= >) have higher precedence than the
    |logical operators (&& and ||).
    |
    |When mixing unrelated operators, though, it's a good idea to
    |parenthesize. C and its friends present pernicious precedence
    |problems, and it's easy to make a mistake.

    For reference, the "previous example" they mention here is:

    if ((block_id >= actblks) || (block_id < unblocks))

    Most C programmers would write this as,

    if (block_id >= actblks || block_id < unblocks)

    And Kernighan and Pike would be fine with that. It must be
    noted that, throughout the rest of TPoP, they rarely
    parenthesize as aggressively as they do in that one example.
    For example, on page 98, in the discussion of building a CSV
    file parser interface, they present a function called,
    `advquoted` that contains this line of code:

    if (pj] == '"' && p[++j] != '"') {
    ...
    }

    (Note this doesn't just omit parenthesis, but also makes use of
    the pre-increment operator _and_ boolean short-circuiting.)

    Pike is famous for brevity; his 1989 document, "Notes on
    Programming in C" is a model here:
    http://www.literateprogramming.com/pikestyle.pdf

    Even now, it's still an interesting read. I like my own code
    princples, as well, but of course, I'm biased:
    https://pub.gajendra.net/2016/03/code_principles

    - Dan C.


    Interestingly I have just come across an old bit of DEC Basic code:

    REPORT.ONLY = W.S4 = "R" ! Global flag

    I know what it does, but I would wrapped the knuckles of any programmer
    who did that on my shift!

    Not knowing DEC BASIC, am I correct in guessing that this
    assigns the boolean result of comparing `W.S4` with the string
    "R" to `REPORT.ONLY`?

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris Townley@news@cct-net.co.uk to comp.os.vms on Wed Aug 20 16:11:46 2025
    From Newsgroup: comp.os.vms

    On 20/08/2025 16:03, Dan Cross wrote:
    In article <1082lks$3nmtt$2@dont-email.me>,
    Chris Townley <news@cct-net.co.uk> wrote:
    On 19/08/2025 17:07, Dan Cross wrote:
    In article <10822mn$3pb8v$1@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/18/2025 11:00 PM, Lawrence DrCOOliveiro wrote:
    On Mon, 18 Aug 2025 21:49:29 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:59 PM, Lawrence DrCOOliveiro wrote:

    On Mon, 18 Aug 2025 19:48:16 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:45 PM, Lawrence DrCOOliveiro wrote:

    Parentheses are best used lightly -- where needed, maybe a little >>>>>>>>> bit more than that, and thatrCOs it.

    Otherwise parenthesis clutter introduces its own obstacles to >>>>>>>>> readability.

    That is not the mantra among people who try to prevent future
    errors.

    There are people who just repeat what they are told, arenrCOt there, >>>>>>> instead of learning from actual experience.

    It is the recommendation from people with actual experience.

    One book that recommend it is "The Practice of Programming".
    Brian Kernighan and Rob Pike.

    One wonders how much experience they really have, across how many
    different languages.

    (Wow.)

    Brian Kernighan and Rob Pike? A lot! :-)

    It may help to read what they actually wrote in TPoP; on page 6:

    |_Parenthesize to resolve ambiguity_. Parentheses specify
    |grouping and can be used to make the intent clear even when
    |they are not required. The inner parentheses in the previous
    |example are not necessary, but they don't hurt, either.
    |Seasoned programmers might omit them, because the relational
    |operators (< <= == != >= >) have higher precedence than the
    |logical operators (&& and ||).
    |
    |When mixing unrelated operators, though, it's a good idea to
    |parenthesize. C and its friends present pernicious precedence
    |problems, and it's easy to make a mistake.

    For reference, the "previous example" they mention here is:

    if ((block_id >= actblks) || (block_id < unblocks))

    Most C programmers would write this as,

    if (block_id >= actblks || block_id < unblocks)

    And Kernighan and Pike would be fine with that. It must be
    noted that, throughout the rest of TPoP, they rarely
    parenthesize as aggressively as they do in that one example.
    For example, on page 98, in the discussion of building a CSV
    file parser interface, they present a function called,
    `advquoted` that contains this line of code:

    if (pj] == '"' && p[++j] != '"') {
    ...
    }

    (Note this doesn't just omit parenthesis, but also makes use of
    the pre-increment operator _and_ boolean short-circuiting.)

    Pike is famous for brevity; his 1989 document, "Notes on
    Programming in C" is a model here:
    http://www.literateprogramming.com/pikestyle.pdf

    Even now, it's still an interesting read. I like my own code
    princples, as well, but of course, I'm biased:
    https://pub.gajendra.net/2016/03/code_principles

    - Dan C.


    Interestingly I have just come across an old bit of DEC Basic code:

    REPORT.ONLY = W.S4 = "R" ! Global flag

    I know what it does, but I would wrapped the knuckles of any programmer
    who did that on my shift!

    Not knowing DEC BASIC, am I correct in guessing that this
    assigns the boolean result of comparing `W.S4` with the string
    "R" to `REPORT.ONLY`?

    - Dan C.


    Correct, but I would have surrounded the comparison with brackets, or
    used an IF statement.

    Not quite as bad as a colleague who found source code file for a
    function, that ended with an UNLESS Z
    Z was a global not mentioned in the source file! Try searching a massive codebase for Z!
    --
    Chris
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Wed Aug 20 15:18:20 2025
    From Newsgroup: comp.os.vms

    In article <1084fca$afbj$3@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-19, Dan Cross <cross@spitfire.i.gajendra.net> wrote:

    Even now, it's still an interesting read. I like my own code
    princples, as well, but of course, I'm biased:
    https://pub.gajendra.net/2016/03/code_principles


    I've just read through that document and agree with everything there.
    I was especially amused by the write for readability and it will be
    read many times comments as I use that wording myself.

    I am surprised you are picking me up on some things however, given
    the mindset expressed in that document. Perhaps your idea of readability
    is different from mine. :-)

    Oh, I hope any criticism I offer doesn't come across as
    personal!

    One of the harder things about programming is how much matters
    of style, readability, and so on, are open to subjective
    interpretation, and how these vary from language to language.

    My general rule is, when working in any given language, find out
    if there is some dominant style preferred by the bulk of
    programmers working in that language, and adhere as closely to
    that as I can; a decent metric is looking at the standard
    library code for the language.

    If an automated formatter exists for the language, then use it
    aggressively, and with as close to a "stock" format as possible.

    This is just part of learning the idioms of that language.

    I think there is something of a generational divide when it
    comes to this kind of thing. I've found that folks who've been
    around longer tend to feel very strongly about using their
    preferred coding styles, whereas newer programmers tend to care
    much less, expecting that there is some tool automate the
    process.

    When the Go language was being developed, one of the best things
    they did as a service to the community was declare that only
    programs as emitted by the standard `gofmt` tool were valid. It
    instantly eliminated entire categories of silly arguments. It
    is truly liberating.

    I suspect this was informed by the authors' experiences at
    Google. When I started working there, I absolutely _loathed_
    the style "guides", which are not so much guides as sets of hard
    rules, that were in use for each language. C++ in particular
    was just ugly. However, a few months in, I simply stopped
    noticing and thus I stopped caring, and moreover I couldn't deny
    the network effects of being able to change into any directory
    of G's massive source monorepo and read, essentially, any source
    file with no cognitive overhead based on style differences.

    When you are working in code bases measured in the BLOC, that's
    essential.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Wed Aug 20 15:51:14 2025
    From Newsgroup: comp.os.vms

    In article <1084drl$afbj$1@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-19, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <68a493ec$0$710$14726298@news.sunsite.dk>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:

    Kotlin is rather picky about mixing signed and unsigned.

    var v: UInt = 16u

    v = v / 2

    gives an error.

    v = v / 2u
    v = v / 2.toUInt()

    works.

    I consider that rather picky.

    I've not used Kotlin, but I consider that to be the really good type
    of picky. :-)


    It's kind of annoying that it can't infer to use unsigned for
    the '2' in the first example. Rust, for example, does do that
    inference which makes most arithmetic very natural.

    I actually consider that to be a good thing. The programmer is forced
    to think about what they have written and to change it to make those >intentions explicit in the code. I like this.

    I think the point is, that in cases like this, the compiler
    enforces the explicit typing anyway: if the program compiles, it
    is well-typed. If it does not, then it is not. In that
    context, this level of explicitness adds little, if any,
    additional value.

    That the literal "2" is a different type than "2u" is
    interesting, however, and goes back to what you were saying
    earlier about default signedness. As a mathematical object,
    "2" is just a positive integer, but programming languages are
    not _really_ a mathematical notation, so the need to be explicit
    here makes sense from that perspective, I guess.

    In Rust, I might write this sequence as:

    let mut v = 16u32;
    v = v / 2;

    And the type inference mechanism would deduce that 2 should be
    treated as a `u32`. But I could just as easily write,

    let mut v = 16u32;
    v = v / 2u32;

    Which explicitly calls out that 2 as a `u32`.

    Is this really better, though? This is where I'd argue that
    matters of idiom come into play: this is not idiomatic usage in
    the language, and so it is probably not better, and maybe worse.

    Which begs the question: who do we write our programs for? Note
    that I don't ask "what", but rather, "who": sure, we write code
    to (hopefully) make the machine do something useful, but really
    we use these notations we call "programming languages" for
    ourselves and for each other. So what are the characteristics
    of that audience? In particular, what level of proficiency
    should I assume when I write code in a particular language? Do
    I write for programmers who are not familiar with the language
    and its idioms, or the do I assume a greater level of
    familiarity? Personally, I err on the side of the latter, but
    then I'm often writing code in a domain where casual changes
    rarely work. Still, like all things, I think there's a balance
    here, and I am very tired of the mentality that programming
    _should_ be hard just because it should.

    - Dan C.

    Just as an aside about Rust, note that variables are immutable
    by default; in the above example, I can avoid `mut` and write:

    let v = 16u32;
    let v = v / 2;

    Which shadows the original binding, but gives the same effect as
    the version that uses `mut`. _This_ is subjective, and not a
    matter of idiom, however.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Wed Aug 20 15:57:50 2025
    From Newsgroup: comp.os.vms

    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/18/2025 8:48 PM, Dan Cross wrote:
    In article <68a3b980$0$713$14726298@news.sunsite.dk>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    But point is that one need to know something about the
    languages.

    Just picking an operator that "looks like" and hope it
    has similar semantics is no good.

    This seems like a very extreme example. There is a scale of
    knowledge when it comes to programming languages, from the basic
    ways in which one does various things like write loops or
    perform basic arithmetic, to the minutia of specific library or
    IO routines, with semantics of specific operators and how they
    combine probably somewhere in the middle.

    I happen to disagree with Simon's notion of what makes for
    robust programming, but to go to such an extreme as to suggest
    that writing code as if logical operators don't short-circuit
    is the same as not knowing the semantics of division is
    specious.

    There are 4 operations:
    - short circuiting and
    - non short circuiting and
    - integer division
    - floating point division

    There is a lot of different integer divisions:
    - "correct one", that is producing a fraction
    - rounding quotient up
    - rounding quotient down
    - rounding quotient to 0
    - rounding quotient at half with ties going to even
    - with positive remainder
    - with remainder of smallest absolute value and in case of ties positive

    There are various behaviours on overflow and in case of zero divisor.

    Both source and target language has a way of doing those: operator,
    function or a more complex expression.

    I agree that the risk of someone not understanding "division"
    ways is much less than the risk of someone not understanding
    "and" ways.

    Well, division is much more complex than boolean operations, so
    harder to understand. OTOH details of division are are harder
    to ignore than details of boolean operations.
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Wed Aug 20 16:18:53 2025
    From Newsgroup: comp.os.vms

    In article <1084eul$afbj$2@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-19, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <1081rg2$3njqo$3@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:

    I write simple to understand code, not clever code, even when the
    problem it is solving is complex or has a lot of functionality
    built into the problem.

    I've found it makes code more robust and easier for others to read, >>>especially when they may not have the knowledge you have when you
    wrote the original code.

    I'm curious how this expresses itself with respect to e.g. the
    short-circuiting thing, though. For instance, this might be
    common in C:

    struct something *p;
    ...
    if (p != NULL && p->ptr != NULL && something(*p->ptr)) {
    // Do something here.
    }

    This, of course, relies on short-circuiting to avoid
    dereferncing either `p` or `*p->ptr` if either is NULL. What
    is the alternative?

    if (p != NULL) {
    if (p->ptr != NULL) {
    if (something(*p->ptr)) {
    // Do something....
    }
    }
    }

    If I dare say so, this is strictly worse because the code is now
    much more heavily indented.

    Indented properly (not as in your next example!) I find that very
    readable and is mostly how I would write it although I do use code
    like your return example when appropriate. This is my variant:

    if (p != NULL)
    {
    if (p->ptr != NULL)
    {
    if (something(*p->ptr))
    {
    // Do something....
    }
    }
    }

    In case that doesn't survive a NNTP client, it is in Whitesmiths format:

    https://en.wikipedia.org/wiki/Indentation_style#Whitesmiths

    Well...at least it's not GNU style. :-D

    Jokes aside, I've found this easy to turn into a mess, if the
    nested 'if's also have 'else's. In the context where we're
    talking about a replacement for short-circuiting booleans,
    that's not generally a consideration, though.

    I like to spread out code vertically as I find it is easier to read.
    We are no longer in the era of VT50/52/100 terminals. :-)

    Eh, vertical density has some cognitive advantages. Like it all
    things, it can be taken to an extreme, however. Sometimes it's
    useful to burn vertical space for readability; sometimes that is
    done excessively, defeating the purpose.

    Ken Thompson used to avoid things like this by writing such code
    as:

    if (p != NULL)
    if (p->ptr != NULL)
    if (something(p->ptr)) {
    // Do something....
    }


    YUCK * 1000!!! That's horrible!!! :-)

    Heh. Well, tell it to Ken; in a lot of ways, he's responible
    for much of the language (via Dennis Ritchie), so he can do what
    more or less what he wants. :-)

    Which has a certain elegance to it, but automated code
    formatters inevitably don't understand it (and at this point,
    one really ought to be using an automated formatter whenever
    possible).

    AN alternative might be to extract the conditional and put it
    into an auxiliary function, and use something similar to
    Dijkstra's guarded commands:

    void
    maybe_do_something(struct something *p)
    {
    if (p == NULL)
    return;
    if (p->ptr == NULL)
    return;
    if (!something(*p->ptr))
    return;
    // Now do something.
    }

    I would argue that this is better than the previous example, and
    possibly on par with or better than the original: if nothing
    else, it gives a name to the operation. This is of course just
    a contrived example, so the name here is meaningless, but one
    hopes that in a real program a name with some semantic meaning
    would be chosen.

    There is one difference for me here however. _All_ single conditional >statements as in the above example are placed in braces to help avoid
    the possibility of a later editing error.

    Oh, that's fine; I have no objection to that. On USENET, I'd
    omit that just for brevity, however. Here, I _do_ care about
    vertical space!

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris Townley@news@cct-net.co.uk to comp.os.vms on Wed Aug 20 18:05:32 2025
    From Newsgroup: comp.os.vms

    On 20/08/2025 13:27, Simon Clubley wrote:
    <big snip>> Indented properly (not as in your next example!) I find that
    very
    readable and is mostly how I would write it although I do use code
    like your return example when appropriate. This is my variant:

    if (p != NULL)
    {
    if (p->ptr != NULL)
    {
    if (something(*p->ptr))
    {
    // Do something....
    }
    }
    }

    In case that doesn't survive a NNTP client, it is in Whitesmiths format:

    <snip>
    That is why I don't like Whitesmiths

    To me the curly braces should logically align with the preceding statement.

    When I first looked at he example, I immediately thought there is a
    missing closing brace, which of course there isn't.

    I also dislike putting the opening brace at the end of the preceding
    line, although I have had to in some cases. Probably a Microsoft invention
    --
    Chris
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Wed Aug 20 17:43:21 2025
    From Newsgroup: comp.os.vms

    In article <1084ojj$95kl$1@dont-email.me>,
    Chris Townley <news@cct-net.co.uk> wrote:
    On 20/08/2025 16:03, Dan Cross wrote:
    In article <1082lks$3nmtt$2@dont-email.me>,
    Chris Townley <news@cct-net.co.uk> wrote:
    [snip]
    Interestingly I have just come across an old bit of DEC Basic code:

    REPORT.ONLY = W.S4 = "R" ! Global flag

    I know what it does, but I would wrapped the knuckles of any programmer
    who did that on my shift!

    Not knowing DEC BASIC, am I correct in guessing that this
    assigns the boolean result of comparing `W.S4` with the string
    "R" to `REPORT.ONLY`?

    Correct, but I would have surrounded the comparison with brackets, or
    used an IF statement.

    Indeed!

    Not quite as bad as a colleague who found source code file for a
    function, that ended with an UNLESS Z
    Z was a global not mentioned in the source file! Try searching a massive >codebase for Z!

    Eek.

    In the Plan 9 kernel (https://9p.io/sys/doc/9.html), the symbol
    `m` refers to a pointer to the local "Mach" (basically, a
    per-CPU data structure).

    `up` is similarly a symbol that refers to the current process
    context on the current CPU.

    In the ARM version of that kernel, these are "extern register"
    variables understood by the compiler, that are preserved on exit
    from, and restored on entry to, the kernel. To understand
    exactly which register corresponds to which variable requires
    examining compiler internals and the way that the compiler
    (implicitly) allocates them to such variables. "Good luck!"

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Simon Clubley@clubley@remove_me.eisner.decus.org-Earth.UFP to comp.os.vms on Wed Aug 20 18:07:10 2025
    From Newsgroup: comp.os.vms

    On 2025-08-20, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <1084fca$afbj$3@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-19, Dan Cross <cross@spitfire.i.gajendra.net> wrote:

    Even now, it's still an interesting read. I like my own code
    princples, as well, but of course, I'm biased:
    https://pub.gajendra.net/2016/03/code_principles


    I've just read through that document and agree with everything there.
    I was especially amused by the write for readability and it will be
    read many times comments as I use that wording myself.

    I am surprised you are picking me up on some things however, given
    the mindset expressed in that document. Perhaps your idea of readability
    is different from mine. :-)

    Oh, I hope any criticism I offer doesn't come across as
    personal!


    No, it absolutely does _not_ in any way.

    For me, it's exactly the same as a colleague noticing something
    in another colleague's code or design proposal and commenting on it.
    You would have to be extremely fragile to take _that_ personally. :-)

    Simon.
    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Wed Aug 20 18:08:10 2025
    From Newsgroup: comp.os.vms

    In article <1084v8t$95kl$2@dont-email.me>,
    Chris Townley <news@cct-net.co.uk> wrote:
    On 20/08/2025 13:27, Simon Clubley wrote:
    <big snip>> Indented properly (not as in your next example!) I find that >very
    readable and is mostly how I would write it although I do use code
    like your return example when appropriate. This is my variant:

    if (p != NULL)
    {
    if (p->ptr != NULL)
    {
    if (something(*p->ptr))
    {
    // Do something....
    }
    }
    }

    In case that doesn't survive a NNTP client, it is in Whitesmiths format:

    <snip>
    That is why I don't like Whitesmiths

    To me the curly braces should logically align with the preceding statement.

    When I first looked at he example, I immediately thought there is a
    missing closing brace, which of course there isn't.

    Just give yourself over to a tool to manage formatting. It
    won't feel "perfect", certainly not at first, but in a very
    short time it will become indispensible.

    https://clang.llvm.org/docs/ClangFormat.html

    I also dislike putting the opening brace at the end of the preceding
    line, although I have had to in some cases. Probably a Microsoft invention

    As in,

    if (foo != 2) {
    /* whatever here... */
    }

    ?

    That demonstrably predates Microsoft. It's often called K&R
    style, or sometimes, the "One True Brace Style", because it was
    used in Kernighan and Ritchie's books on C; Ritchie, of course,
    being the primary architect and earliest implementer of the C
    language, based on a language called B (and "new B" or nb) by
    Ken Thompson, which itself was based on Martin Richards's BCPL.
    This was also the style used in the Unix kernel, which was
    probably the first really serious program written in C.

    As they put it in the first edition of K&R (1978):

    |Although C is quite permissive about statement positioning,
    |proper indentation and use of white space are critical in
    |making programs easy for people to read. The position of the
    |braces is less important; we have chosen one of several
    |popular styles. Pick a style that suits you, then use it
    |consistently.

    The intent was good here, but really, they should have just said
    "use this style" and been done with it. It'd have saved a lot
    of blocks on disks storing USENET messages arguing over where to
    put the braces. :-D

    Btw, some folks may find Henry Spencer's, "10 Commandments for C
    Programmers" amusing. Number 8 is relevant here: https://www.lysator.liu.se/c/ten-commandments.html

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Wed Aug 20 18:09:16 2025
    From Newsgroup: comp.os.vms

    In article <10852se$fica$1@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-20, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <1084fca$afbj$3@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-19, Dan Cross <cross@spitfire.i.gajendra.net> wrote:

    Even now, it's still an interesting read. I like my own code
    princples, as well, but of course, I'm biased:
    https://pub.gajendra.net/2016/03/code_principles


    I've just read through that document and agree with everything there.
    I was especially amused by the write for readability and it will be
    read many times comments as I use that wording myself.

    I am surprised you are picking me up on some things however, given
    the mindset expressed in that document. Perhaps your idea of readability >>>is different from mine. :-)

    Oh, I hope any criticism I offer doesn't come across as
    personal!

    No, it absolutely does _not_ in any way.

    For me, it's exactly the same as a colleague noticing something
    in another colleague's code or design proposal and commenting on it.
    You would have to be extremely fragile to take _that_ personally. :-)

    Okay, great; that's 100% the intention. Thanks for confirming!

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Dave Froble@davef@tsoft-inc.com to comp.os.vms on Thu Aug 21 10:58:22 2025
    From Newsgroup: comp.os.vms

    On 8/20/2025 11:11 AM, Chris Townley wrote:
    On 20/08/2025 16:03, Dan Cross wrote:
    In article <1082lks$3nmtt$2@dont-email.me>,
    Chris Townley <news@cct-net.co.uk> wrote:
    On 19/08/2025 17:07, Dan Cross wrote:
    In article <10822mn$3pb8v$1@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/18/2025 11:00 PM, Lawrence DrCOOliveiro wrote:
    On Mon, 18 Aug 2025 21:49:29 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:59 PM, Lawrence DrCOOliveiro wrote:

    On Mon, 18 Aug 2025 19:48:16 -0400, Arne Vajh|+j wrote:

    On 8/18/2025 7:45 PM, Lawrence DrCOOliveiro wrote:

    Parentheses are best used lightly -- where needed, maybe a little >>>>>>>>>> bit more than that, and thatrCOs it.

    Otherwise parenthesis clutter introduces its own obstacles to >>>>>>>>>> readability.

    That is not the mantra among people who try to prevent future >>>>>>>>> errors.

    There are people who just repeat what they are told, arenrCOt there, >>>>>>>> instead of learning from actual experience.

    It is the recommendation from people with actual experience.

    One book that recommend it is "The Practice of Programming".
    Brian Kernighan and Rob Pike.

    One wonders how much experience they really have, across how many
    different languages.

    (Wow.)

    Brian Kernighan and Rob Pike? A lot! :-)

    It may help to read what they actually wrote in TPoP; on page 6:

    |_Parenthesize to resolve ambiguity_. Parentheses specify
    |grouping and can be used to make the intent clear even when
    |they are not required. The inner parentheses in the previous
    |example are not necessary, but they don't hurt, either.
    |Seasoned programmers might omit them, because the relational
    |operators (< <= == != >= >) have higher precedence than the
    |logical operators (&& and ||).
    |
    |When mixing unrelated operators, though, it's a good idea to
    |parenthesize. C and its friends present pernicious precedence
    |problems, and it's easy to make a mistake.

    For reference, the "previous example" they mention here is:

    if ((block_id >= actblks) || (block_id < unblocks))

    Most C programmers would write this as,

    if (block_id >= actblks || block_id < unblocks)

    And Kernighan and Pike would be fine with that. It must be
    noted that, throughout the rest of TPoP, they rarely
    parenthesize as aggressively as they do in that one example.
    For example, on page 98, in the discussion of building a CSV
    file parser interface, they present a function called,
    `advquoted` that contains this line of code:

    if (pj] == '"' && p[++j] != '"') {
    ...
    }

    (Note this doesn't just omit parenthesis, but also makes use of
    the pre-increment operator _and_ boolean short-circuiting.)

    Pike is famous for brevity; his 1989 document, "Notes on
    Programming in C" is a model here:
    http://www.literateprogramming.com/pikestyle.pdf

    Even now, it's still an interesting read. I like my own code
    princples, as well, but of course, I'm biased:
    https://pub.gajendra.net/2016/03/code_principles

    - Dan C.


    Interestingly I have just come across an old bit of DEC Basic code:

    REPORT.ONLY = W.S4 = "R" ! Global flag

    I know what it does, but I would wrapped the knuckles of any programmer
    who did that on my shift!

    Not knowing DEC BASIC, am I correct in guessing that this
    assigns the boolean result of comparing `W.S4` with the string
    "R" to `REPORT.ONLY`?

    - Dan C.


    Correct, but I would have surrounded the comparison with brackets, or used an IF
    statement.

    Not quite as bad as a colleague who found source code file for a function, that
    ended with an UNLESS Z
    Z was a global not mentioned in the source file! Try searching a massive codebase for Z!


    That statement could make a person think for a while. Not a bad thing, being able to understand something like that. However, I've always been a big fan of
    clarity, so go ahead and wack some knuckles.
    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Sun Aug 24 23:24:05 2025
    From Newsgroup: comp.os.vms

    In article <108dlgm$2fi6h$3@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/20/2025 11:51 AM, Dan Cross wrote:
    In article <1084drl$afbj$1@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2025-08-19, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <68a493ec$0$710$14726298@news.sunsite.dk>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:

    Kotlin is rather picky about mixing signed and unsigned.

    var v: UInt = 16u

    v = v / 2

    gives an error.

    v = v / 2u
    v = v / 2.toUInt()

    works.

    I consider that rather picky.

    I've not used Kotlin, but I consider that to be the really good type
    of picky. :-)

    It's kind of annoying that it can't infer to use unsigned for
    the '2' in the first example. Rust, for example, does do that
    inference which makes most arithmetic very natural.

    I actually consider that to be a good thing. The programmer is forced
    to think about what they have written and to change it to make those
    intentions explicit in the code. I like this.

    I think the point is, that in cases like this, the compiler
    enforces the explicit typing anyway: if the program compiles, it
    is well-typed. If it does not, then it is not. In that
    context, this level of explicitness adds little, if any,
    additional value.

    That the literal "2" is a different type than "2u" is
    interesting, however, and goes back to what you were saying
    earlier about default signedness. As a mathematical object,
    "2" is just a positive integer, but programming languages are
    not _really_ a mathematical notation, so the need to be explicit
    here makes sense from that perspective, I guess.

    In Rust, I might write this sequence as:

    let mut v = 16u32;
    v = v / 2;

    And the type inference mechanism would deduce that 2 should be
    treated as a `u32`. But I could just as easily write,

    let mut v = 16u32;
    v = v / 2u32;

    Which explicitly calls out that 2 as a `u32`.

    Is this really better, though? This is where I'd argue that
    matters of idiom come into play: this is not idiomatic usage in
    the language, and so it is probably not better, and maybe worse.

    The practical difference for specific code is likely zero.

    But there is a difference in language principles and the
    confidence the developer can have in it.

    A rule that there is never any implicit conversion or
    literal inference no matter the context is simple to
    understand and gives confidence.

    That conflates two separate things, and actually making two, not
    one, rules.

    Implicit type conversion is subtle, with often-confusing rules,
    and programmers frequently mess it up; I agree. Even
    programmers who feel very confident in the rules are not immune
    here.

    However, type inference is an entirely different matter. The
    specific context is Rust, and there is no matter of "confidence"
    at play here; either the inference rules work, and the program
    type checks, or they the inference engine in the compiler can't
    deduce the appropriate types (or makes a mistake) and the
    program does not type check and fails to compile.

    And that's the critical part: the program is either properly
    typed or it is not; unlike weakly typed languages, there is no
    middle ground. And if it is not properly typed, it will not
    compile; period, end of story.

    So if the program compiles, then that's all the "confidence" the
    programmer needs; there's no need to decorate every literal with
    an explicit type annotation, which is just noisy and clutters up
    the program with extraneous detail.

    Exceptions even in cases where it does not matter adds
    the complexity of understanding when the exceptions apply
    and why they do not matter. Complexity that developers
    would rather avoid.

    There are no exceptions. The program is either well-typed, in
    which case (barring any other errors) the program compiles. Or
    it is not, and the program fails to compile: again, there is no
    middle ground.

    Most experienced Rust programmers who saw a bunch of explicit
    type annotations on literals, when the type system could
    otherwise easily infer them, would find rightly find that
    non-idiomatic, and thus confusing, and wonder what was so
    special about the program that literals had to be so annotated.

    _That_ adds complexity where there need not be any, and thus
    increases cognitive load, which is never a desirable property
    for a maintainable program.

    This is why matters of idiom in a language are important.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Sun Aug 24 23:27:11 2025
    From Newsgroup: comp.os.vms

    In article <108dlq4$2fi6h$4@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/19/2025 1:26 PM, Dan Cross wrote:
    In article <10823ei$3pb8v$3@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/19/2025 9:01 AM, Simon Clubley wrote:
    On 2025-08-18, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    I happen to disagree with Simon's notion of what makes for
    robust programming, but to go to such an extreme as to suggest
    that writing code as if logical operators don't short-circuit
    is the same as not knowing the semantics of division is
    specious.

    That last one is an interesting example. I may not care about
    short circuiting, but I am _very_ _very_ aware of the combined
    unsigned integers and signed integers issues in C expressions. :-(

    It also affects how I look at the same issues in other languages.

    I've mentioned this before, but I think languages should give you
    unsigned integers by default, and you should have to ask for
    a signed integer if you really want one.

    "by default" sort of imply signedness being an attribute of
    same type.

    Why not just make it two different types with different names?

    Whether we follow tradition and call them integer and cardinal
    or more modern style and call them int and uint is less important.

    I would argue that, at this point, there's little need for a
    generic "int" type anymore, and that types representing integers
    as understood by the machine should explicitly include both
    signedness and width. An exception may be something like,
    `size_t`, which is platform-dependent, but when transferred
    externally should be given an explicit size. A lot of the
    guesswork and folklore that goes into understanding the
    semantics of those things just disappears when you're explicit.

    The integer types should have well defined width.

    And they could also be called int32 and uint32.

    That seems to be in fashion in low level languages
    competing with C.

    Many higher level languages just define that int is 32 bit,
    but don't show it in the name.

    If by "many higher level languages" you mean languages in the
    JVM and CLR ecosystem, then sure, I guess so. But it's not
    universal, and I don't see how it's an improvement.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Sun Aug 24 23:32:32 2025
    From Newsgroup: comp.os.vms

    In article <108dm7k$2fi6h$5@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/19/2025 1:26 PM, Dan Cross wrote:
    And despite the old admonition to make everything a symbolic
    constant, things like `2 * pi * r` are perfectly readable, and
    I'd argue that `TWO * pi * r` are less so.

    I would say that TWO and 2 are the same regarding readability.

    The problem with TWO is not readability, but lack of purpose.

    Hence why it's poor from a readability perspective: it adds
    nothing, just a symbolic, alphanumberic label for a number, but
    that number is perfectly understandable, and in context, taken
    from a universal mathematical truth.

    There are two good reasons to introduce symbolic names for constants:
    1) The name can be more self documenting than a numeric value
    2) If the constant is used multiple places, then having a symbolic
    name makes it easier to change the value

    But neither applies.

    TWO does not provide more information than 2.

    Just so.

    And it would be very unwise to change the value of TWO
    to something different from 2.

    Indeed. Also, in a language like Rust, where all constants
    must have a type, a name like "TWO" is too generic; supposing I
    wanted to use such a constant in multiple contexts involving
    different types, this wouldn't work with the type inference
    rules, which would be unidiomatic.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Sun Aug 24 19:52:52 2025
    From Newsgroup: comp.os.vms

    On 8/24/2025 7:27 PM, Dan Cross wrote:
    In article <108dlq4$2fi6h$4@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/19/2025 1:26 PM, Dan Cross wrote:
    In article <10823ei$3pb8v$3@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Whether we follow tradition and call them integer and cardinal
    or more modern style and call them int and uint is less important.

    I would argue that, at this point, there's little need for a
    generic "int" type anymore, and that types representing integers
    as understood by the machine should explicitly include both
    signedness and width. An exception may be something like,
    `size_t`, which is platform-dependent, but when transferred
    externally should be given an explicit size. A lot of the
    guesswork and folklore that goes into understanding the
    semantics of those things just disappears when you're explicit.

    The integer types should have well defined width.

    And they could also be called int32 and uint32.

    That seems to be in fashion in low level languages
    competing with C.

    Many higher level languages just define that int is 32 bit,
    but don't show it in the name.

    If by "many higher level languages" you mean languages in the
    JVM and CLR ecosystem, then sure, I guess so. But it's not
    universal, and I don't see how it's an improvement.

    That are two huge group of languages with a pretty big
    market share in business applications.

    Delphi provide both flavors. shortint/smallint/integer
    and int8/int16/int32, byte/word/cardinal and
    uint8/uint16/uint32. I believe the first are the most
    widely used.

    (64 bit is just int64 and uint64, because somehow they
    fucked up longint and made it 32 bit on 32 bit and 64 bit
    Windows but 64 bit on 64 bit *nix)

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Mon Aug 25 01:24:23 2025
    From Newsgroup: comp.os.vms

    On Sun, 24 Aug 2025 19:52:52 -0400, Arne Vajh|+j wrote:

    (... somehow they fucked up longint and made it 32 bit on 32 bit and
    64 bit Windows but 64 bit on 64 bit *nix)

    It was *Microsoft* that rCLfucked up longintrCY, and nobody else. Just to be clear.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Sun Aug 24 21:27:08 2025
    From Newsgroup: comp.os.vms

    On 8/24/2025 9:24 PM, Lawrence DrCOOliveiro wrote:
    On Sun, 24 Aug 2025 19:52:52 -0400, Arne Vajh|+j wrote:
    (... somehow they fucked up longint and made it 32 bit on 32 bit and
    64 bit Windows but 64 bit on 64 bit *nix)

    It was *Microsoft* that rCLfucked up longintrCY, and nobody else. Just to be clear.

    I don't think you can blame MS for Delphi.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.os.vms on Mon Aug 25 02:05:37 2025
    From Newsgroup: comp.os.vms

    Lawrence DrCOOliveiro <ldo@nz.invalid> wrote:
    On Sun, 24 Aug 2025 19:52:52 -0400, Arne Vajh|+j wrote:

    (... somehow they fucked up longint and made it 32 bit on 32 bit and
    64 bit Windows but 64 bit on 64 bit *nix)

    It was *Microsoft* that rCLfucked up longintrCY, and nobody else. Just to be clear.

    You mean long. But note that DEC made half step first: Alpha is
    64-bit machine and DEC made long 32-bit on Alpha. DEC had reasons
    for doing this and Microsoft had reasons to make long 32-bit on
    64-bit Windows. One can argue if those reasons were good enough,
    but that was not a random decision.
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Mon Aug 25 02:22:29 2025
    From Newsgroup: comp.os.vms

    On Mon, 25 Aug 2025 02:05:37 -0000 (UTC), Waldek Hebisch wrote:

    But note that DEC made half step first: Alpha is 64-bit machine and
    DEC made long 32-bit on Alpha.

    On DEC Unix, as on every other *nix, rCLintrCY was 32 bits and rCLlongrCY was 64
    bits. This applied on Alpha, too.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Mon Aug 25 11:07:10 2025
    From Newsgroup: comp.os.vms

    On 8/24/2025 10:22 PM, Lawrence DrCOOliveiro wrote:
    On Mon, 25 Aug 2025 02:05:37 -0000 (UTC), Waldek Hebisch wrote:
    But note that DEC made half step first: Alpha is 64-bit machine and
    DEC made long 32-bit on Alpha.

    On DEC Unix, as on every other *nix, rCLintrCY was 32 bits and rCLlongrCY was 64
    bits. This applied on Alpha, too.

    Given the group, then Alpha with no OS specification is likely to
    mean VMS.

    VMS and Tru64 (DEC OSF/1 -> Digital Unix -> Compaq Tru64) was
    treated very differently for Alpha.

    On VMS Alpha the goal was backwards compatibility with VMS VAX,
    so long stayed 32 bit.

    On Tru64 there were no strong requirement for compatibility with
    Ultrix VAX and Ultrix MIPS, so long was made 64 bit.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Fri Aug 29 13:17:32 2025
    From Newsgroup: comp.os.vms

    In article <108g8kk$33isk$1@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/24/2025 7:27 PM, Dan Cross wrote:
    In article <108dlq4$2fi6h$4@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/19/2025 1:26 PM, Dan Cross wrote:
    In article <10823ei$3pb8v$3@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Whether we follow tradition and call them integer and cardinal
    or more modern style and call them int and uint is less important.

    I would argue that, at this point, there's little need for a
    generic "int" type anymore, and that types representing integers
    as understood by the machine should explicitly include both
    signedness and width. An exception may be something like,
    `size_t`, which is platform-dependent, but when transferred
    externally should be given an explicit size. A lot of the
    guesswork and folklore that goes into understanding the
    semantics of those things just disappears when you're explicit.

    The integer types should have well defined width.

    And they could also be called int32 and uint32.

    That seems to be in fashion in low level languages
    competing with C.

    Many higher level languages just define that int is 32 bit,
    but don't show it in the name.

    If by "many higher level languages" you mean languages in the
    JVM and CLR ecosystem, then sure, I guess so. But it's not
    universal, and I don't see how it's an improvement.

    That are two huge group of languages with a pretty big
    market share in business applications.

    Market share is not the same as influence, and while the JVM/CLR
    languages _do_ have a lot of users, that does not imply that all
    are good languages. In fact, only a handful of languages in
    each family have any significant adoption, and I don't think PL
    designers are mining them for much inspiration these days.

    Again, not universal, nor really an improvement over just using
    explicitly sized types.

    Delphi provide both flavors. shortint/smallint/integer
    and int8/int16/int32, byte/word/cardinal and
    uint8/uint16/uint32. I believe the first are the most
    widely used.

    The older names feel like they're very much looking backwards in
    time.

    (64 bit is just int64 and uint64, because somehow they
    fucked up longint and made it 32 bit on 32 bit and 64 bit
    Windows but 64 bit on 64 bit *nix)

    I'd blame C for that. I've heard some folks suggest that the
    real mistake was not making `long` 64 bits on the first VAX C
    compiler, which admittedly may have already been too late (the
    Interdata compilers for the 7/32 and 8/32 Unix ports targeted a
    32-bit machine very early on).

    John Mashey et al got a lot of this mess fixed up with
    `<inttypes.h>` in the 1990s as they were pushing the 64-bit
    adoption. But had types been annotated with widths very early
    on, most of these problems wouldn't have existed in the first
    place.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Fri Aug 29 15:52:04 2025
    From Newsgroup: comp.os.vms

    On 8/29/2025 9:17 AM, Dan Cross wrote:
    In article <108g8kk$33isk$1@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/24/2025 7:27 PM, Dan Cross wrote:
    In article <108dlq4$2fi6h$4@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/19/2025 1:26 PM, Dan Cross wrote:
    In article <10823ei$3pb8v$3@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Whether we follow tradition and call them integer and cardinal
    or more modern style and call them int and uint is less important.

    I would argue that, at this point, there's little need for a
    generic "int" type anymore, and that types representing integers
    as understood by the machine should explicitly include both
    signedness and width. An exception may be something like,
    `size_t`, which is platform-dependent, but when transferred
    externally should be given an explicit size. A lot of the
    guesswork and folklore that goes into understanding the
    semantics of those things just disappears when you're explicit.

    The integer types should have well defined width.

    And they could also be called int32 and uint32.

    That seems to be in fashion in low level languages
    competing with C.

    Many higher level languages just define that int is 32 bit,
    but don't show it in the name.

    If by "many higher level languages" you mean languages in the
    JVM and CLR ecosystem, then sure, I guess so. But it's not
    universal, and I don't see how it's an improvement.

    That are two huge group of languages with a pretty big
    market share in business applications.

    Market share is not the same as influence, and while the JVM/CLR
    languages _do_ have a lot of users, that does not imply that all
    are good languages. In fact, only a handful of languages in
    each family have any significant adoption, and I don't think PL
    designers are mining them for much inspiration these days.

    Again, not universal, nor really an improvement over just using
    explicitly sized types.

    It is a huge domain that are totally dominated by two approaches:
    * no need for declaring variables
    * declaring variables required but type names not including width
    (despite width being well defined for the type)

    And market share does matter as it sets developers expectations.

    Delphi provide both flavors. shortint/smallint/integer
    and int8/int16/int32, byte/word/cardinal and
    uint8/uint16/uint32. I believe the first are the most
    widely used.

    The older names feel like they're very much looking backwards in
    time.

    Developers tend to like what they know.

    (64 bit is just int64 and uint64, because somehow they
    fucked up longint and made it 32 bit on 32 bit and 64 bit
    Windows but 64 bit on 64 bit *nix)

    I'd blame C for that.

    Delphi is not C.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Fri Aug 29 21:38:02 2025
    From Newsgroup: comp.os.vms

    In article <108t0d4$249vm$11@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/29/2025 9:17 AM, Dan Cross wrote:
    In article <108g8kk$33isk$1@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/24/2025 7:27 PM, Dan Cross wrote:
    In article <108dlq4$2fi6h$4@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/19/2025 1:26 PM, Dan Cross wrote:
    In article <10823ei$3pb8v$3@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Whether we follow tradition and call them integer and cardinal
    or more modern style and call them int and uint is less important. >>>>>>
    I would argue that, at this point, there's little need for a
    generic "int" type anymore, and that types representing integers
    as understood by the machine should explicitly include both
    signedness and width. An exception may be something like,
    `size_t`, which is platform-dependent, but when transferred
    externally should be given an explicit size. A lot of the
    guesswork and folklore that goes into understanding the
    semantics of those things just disappears when you're explicit.

    The integer types should have well defined width.

    And they could also be called int32 and uint32.

    That seems to be in fashion in low level languages
    competing with C.

    Many higher level languages just define that int is 32 bit,
    but don't show it in the name.

    If by "many higher level languages" you mean languages in the
    JVM and CLR ecosystem, then sure, I guess so. But it's not
    universal, and I don't see how it's an improvement.

    That are two huge group of languages with a pretty big
    market share in business applications.

    Market share is not the same as influence, and while the JVM/CLR
    languages _do_ have a lot of users, that does not imply that all
    are good languages. In fact, only a handful of languages in
    each family have any significant adoption, and I don't think PL
    designers are mining them for much inspiration these days.

    Again, not universal, nor really an improvement over just using
    explicitly sized types.

    It is a huge domain that are totally dominated by two approaches:
    [snip]

    So? You referred to "many higher level languages". That is
    qualitatively different than "a small number of languages with a
    huge share of the market."

    Delphi provide both flavors. shortint/smallint/integer
    and int8/int16/int32, byte/word/cardinal and
    uint8/uint16/uint32. I believe the first are the most
    widely used.

    The older names feel like they're very much looking backwards in
    time.

    Developers tend to like what they know.

    (64 bit is just int64 and uint64, because somehow they
    fucked up longint and made it 32 bit on 32 bit and 64 bit
    Windows but 64 bit on 64 bit *nix)

    I'd blame C for that.

    Delphi is not C.

    Obviously.

    But it would be foolish to assume that they weren't influenced
    by matters of compatibility with C (or more specifically C++)
    here, particularly given the history of Delphi as a language.

    Even the name gives it away ("longint").

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Fri Aug 29 19:03:30 2025
    From Newsgroup: comp.os.vms

    On 8/29/2025 5:38 PM, Dan Cross wrote:
    In article <108t0d4$249vm$11@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/29/2025 9:17 AM, Dan Cross wrote:
    In article <108g8kk$33isk$1@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Delphi provide both flavors. shortint/smallint/integer
    and int8/int16/int32, byte/word/cardinal and
    uint8/uint16/uint32. I believe the first are the most
    widely used.

    The older names feel like they're very much looking backwards in
    time.

    Developers tend to like what they know.

    (64 bit is just int64 and uint64, because somehow they
    fucked up longint and made it 32 bit on 32 bit and 64 bit
    Windows but 64 bit on 64 bit *nix)

    I'd blame C for that.

    Delphi is not C.

    Obviously.

    But it would be foolish to assume that they weren't influenced
    by matters of compatibility with C (or more specifically C++)
    here, particularly given the history of Delphi as a language.

    Even the name gives it away ("longint").

    That was also Lawrence's guess.

    But the hypothesis that they wanted to follow
    C/C++ is obviously not true.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Fri Aug 29 19:06:34 2025
    From Newsgroup: comp.os.vms

    On 8/29/2025 5:38 PM, Dan Cross wrote:
    In article <108t0d4$249vm$11@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/29/2025 9:17 AM, Dan Cross wrote:
    In article <108g8kk$33isk$1@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/24/2025 7:27 PM, Dan Cross wrote:
    In article <108dlq4$2fi6h$4@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/19/2025 1:26 PM, Dan Cross wrote:
    In article <10823ei$3pb8v$3@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Whether we follow tradition and call them integer and cardinal >>>>>>>> or more modern style and call them int and uint is less important. >>>>>>>
    I would argue that, at this point, there's little need for a
    generic "int" type anymore, and that types representing integers >>>>>>> as understood by the machine should explicitly include both
    signedness and width. An exception may be something like,
    `size_t`, which is platform-dependent, but when transferred
    externally should be given an explicit size. A lot of the
    guesswork and folklore that goes into understanding the
    semantics of those things just disappears when you're explicit.

    The integer types should have well defined width.

    And they could also be called int32 and uint32.

    That seems to be in fashion in low level languages
    competing with C.

    Many higher level languages just define that int is 32 bit,
    but don't show it in the name.

    If by "many higher level languages" you mean languages in the
    JVM and CLR ecosystem, then sure, I guess so. But it's not
    universal, and I don't see how it's an improvement.

    That are two huge group of languages with a pretty big
    market share in business applications.

    Market share is not the same as influence, and while the JVM/CLR
    languages _do_ have a lot of users, that does not imply that all
    are good languages. In fact, only a handful of languages in
    each family have any significant adoption, and I don't think PL
    designers are mining them for much inspiration these days.

    Again, not universal, nor really an improvement over just using
    explicitly sized types.

    It is a huge domain that are totally dominated by two approaches:
    [snip]

    So? You referred to "many higher level languages". That is
    qualitatively different than "a small number of languages with a
    huge share of the market."

    Yes - that is two different statements.

    But they are both true.

    And the second qualifies the first in the sense that the
    many are actually some that matter not pure exotic.

    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Sat Aug 30 01:21:10 2025
    From Newsgroup: comp.os.vms

    In article <108tbk2$29q30$2@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/29/2025 5:38 PM, Dan Cross wrote:
    In article <108t0d4$249vm$11@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/29/2025 9:17 AM, Dan Cross wrote:
    In article <108g8kk$33isk$1@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Delphi provide both flavors. shortint/smallint/integer
    and int8/int16/int32, byte/word/cardinal and
    uint8/uint16/uint32. I believe the first are the most
    widely used.

    The older names feel like they're very much looking backwards in
    time.

    Developers tend to like what they know.

    (64 bit is just int64 and uint64, because somehow they
    fucked up longint and made it 32 bit on 32 bit and 64 bit
    Windows but 64 bit on 64 bit *nix)

    I'd blame C for that.

    Delphi is not C.

    Obviously.

    But it would be foolish to assume that they weren't influenced
    by matters of compatibility with C (or more specifically C++)
    here, particularly given the history of Delphi as a language.

    Even the name gives it away ("longint").

    That was also Lawrence's guess.

    I plonked that guy ages ago, so I don't see his responses. I
    expect he knows even less about Delphi than

    But the hypothesis that they wanted to follow
    C/C++ is obviously not true.

    You'll need to qualify that statement more before its veracity
    is even within reach of being ascertained.

    Obviously they were not following C and C++ in the sense that
    the syntax (and much of the semantics) are based on Pascal, not
    C. Clearly they wanted things like fundamental integral types
    to line up with existing C code for calls across an FFI
    boundary. One merely need look up the history of the language
    to see that.

    And of course these things evolved over time. Wirth's own
    languages after Pascal exhibited semantics more closely
    resembling those of C than Pascal. For instance, arrays in
    Oberon do not retain their size as a fundamental aspect of their
    type, one of the big complaints from Kernighan's famous critique
    of Pascal: http://doc.cat-v.org/bell_labs/why_pascal/why_pascal_is_not_my_favorite_language.pdf

    This is arguably a bug in both Oberon and C, but no one had
    really discovered how to put slices a la Fortran into a systems
    language at the level of C or Oberon yet; possibly because they
    were tainted by APL and ALGOL 68.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.os.vms on Sat Aug 30 01:30:12 2025
    From Newsgroup: comp.os.vms

    In article <108tbpq$29q30$3@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/29/2025 5:38 PM, Dan Cross wrote:
    In article <108t0d4$249vm$11@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/29/2025 9:17 AM, Dan Cross wrote:
    In article <108g8kk$33isk$1@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/24/2025 7:27 PM, Dan Cross wrote:
    In article <108dlq4$2fi6h$4@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    On 8/19/2025 1:26 PM, Dan Cross wrote:
    In article <10823ei$3pb8v$3@dont-email.me>,
    Arne Vajh|+j <arne@vajhoej.dk> wrote:
    Whether we follow tradition and call them integer and cardinal >>>>>>>>> or more modern style and call them int and uint is less important. >>>>>>>>
    I would argue that, at this point, there's little need for a
    generic "int" type anymore, and that types representing integers >>>>>>>> as understood by the machine should explicitly include both
    signedness and width. An exception may be something like,
    `size_t`, which is platform-dependent, but when transferred
    externally should be given an explicit size. A lot of the
    guesswork and folklore that goes into understanding the
    semantics of those things just disappears when you're explicit. >>>>>>>
    The integer types should have well defined width.

    And they could also be called int32 and uint32.

    That seems to be in fashion in low level languages
    competing with C.

    Many higher level languages just define that int is 32 bit,
    but don't show it in the name.

    If by "many higher level languages" you mean languages in the
    JVM and CLR ecosystem, then sure, I guess so. But it's not
    universal, and I don't see how it's an improvement.

    That are two huge group of languages with a pretty big
    market share in business applications.

    Market share is not the same as influence, and while the JVM/CLR
    languages _do_ have a lot of users, that does not imply that all
    are good languages. In fact, only a handful of languages in
    each family have any significant adoption, and I don't think PL
    designers are mining them for much inspiration these days.

    Again, not universal, nor really an improvement over just using
    explicitly sized types.

    It is a huge domain that are totally dominated by two approaches:
    [snip]

    So? You referred to "many higher level languages". That is
    qualitatively different than "a small number of languages with a
    huge share of the market."

    Yes - that is two different statements.

    Correct...

    But they are both true.

    ...but irrelevant. I was referring to your specific statement;
    not making any point about the other.

    If you'd like to make a point about the popularity of langauges,
    by all means do so. But moving the goal posts by conflating
    dissimilar things isn't really useful.

    And the second qualifies the first in the sense that the
    many are actually some that matter not pure exotic.

    Nope. Only a few CLR/JVM langauges actually matter as far as
    programming langauge design goes. I'd say Java, Clojure, Scala,
    Kotlin, C#, and F#/F* are about it. I would have previously
    argued that M# was important in this sense as well, but Midori
    was canceled and it was basically a dialect of C# anyway.

    - Dan C.

    --- Synchronet 3.21a-Linux NewsLink 1.2