• Re: Zero-based or one-based indexing

    From James Harris@james.harris.1@gmail.com to comp.lang.misc on Fri Dec 8 19:28:26 2023
    From Newsgroup: comp.lang.misc

    On 03/12/2021 09:08, David Brown wrote:
    On 02/12/2021 22:42, James Harris wrote:
    On 02/12/2021 20:49, Dmitry A. Kazakov wrote:
    On 2021-12-02 21:31, James Harris wrote:

    ...

    But to the point, are you comfortable with the idea of the A(2) in

       x = A(2) + 0

    meaning the same mapping result as the A(2) in

       A(2) = 0

    ?

    Yes, in both cases the result is the array element corresponding to
    the index 2. That is the semantics of A(2).

    Cool. If A were, instead, a function that, say, ended with

      return v

    then what would you want those A(2)s to mean and should they still mean
    the same as each other? The latter expression would look strange to many.


    Do you mean like returning a reference in C++ style?

    Hi David, apologies for not replying before. I was just now looking for
    old posts that were outstanding in some way. (There may be many which I
    have yet to reply to like your one.)

    I probably left your post until I found out about C++ references and
    never got round to reading up on them.



    int a[10];

    void foo1(int i, int x) {
    a[i] = x;
    }

    int& A(int i) {
    return a[i];
    }

    void foo2(int i, int x) {
    A(i) = x;
    }

    foo1 and foo2 do the same thing, and have the same code. Of course,
    foo2 could add range checking, or offsets (for 1-based array), or have multiple parameters for multi-dimensional arrays, etc. And in practice
    you'd make such functions methods of a class so that the class owns the
    data, rather than having a single global source of the data.

    I see at https://www.geeksforgeeks.org/references-in-cpp/ code which
    includes

    void swap(int& first, int& second)
    {
    int temp = first;
    first = second;
    second = temp;
    }

    That's not what I was thinking about. I don't care for it because in a
    call such as

    swap(a, b)

    it's not clear in the syntax that the arguments a and b can be modified
    - a calamity of a design, IMO. :-(

    But in your case you are referring to a /returned/ value. That appears
    to be OK except that to match what I had in mind I think there should be
    a const in there somewhere. To illustrate, I was proposing that in a
    function, f, one could have

    return h

    which would /conceptually/ return the address of h (which I guess in
    Algol terms means it would return h rather than the value of h).
    Crucially, and perhaps at variance with Algol (I don't know) the value
    of h (i.e. the value at the returned address) would be read-only to the caller.

    The caller would be able to use the address returned as it could any
    other address, but it could not write over the referenced value. If the
    callee returned with something like

    return a[4]

    then it would conceptually return the address of a[4] and, again, the
    value at the returned address would be read-only in the caller.

    What I've said so far is by default but overwriting would be possible.
    To conceptually return the address of a variable which /could/ be
    overwritten one would use the rw modifier as in

    return rw h

    or

    return rw a[4]

    I'll say no more just now as this is an old topic but I wanted to at
    least make a reply.
    --
    James Harris



    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From David Brown@david.brown@hesbynett.no to comp.lang.misc on Sat Dec 9 15:33:54 2023
    From Newsgroup: comp.lang.misc

    On 08/12/2023 20:28, James Harris wrote:
    On 03/12/2021 09:08, David Brown wrote:
    On 02/12/2021 22:42, James Harris wrote:
    On 02/12/2021 20:49, Dmitry A. Kazakov wrote:
    On 2021-12-02 21:31, James Harris wrote:

    ...

    But to the point, are you comfortable with the idea of the A(2) in

        x = A(2) + 0

    meaning the same mapping result as the A(2) in

        A(2) = 0

    ?

    Yes, in both cases the result is the array element corresponding to
    the index 2. That is the semantics of A(2).

    Cool. If A were, instead, a function that, say, ended with

       return v

    then what would you want those A(2)s to mean and should they still mean
    the same as each other? The latter expression would look strange to
    many.


    Do you mean like returning a reference in C++ style?

    Hi David, apologies for not replying before. I was just now looking for
    old posts that were outstanding in some way. (There may be many which I
    have yet to reply to like your one.)

    I probably left your post until I found out about C++ references and
    never got round to reading up on them.


    I saw my post was dated 03.12 (or 12.03, for any date-backwards
    Americans in the audience) and thought it was strange that I'd forgotten
    the post from 5 days ago. Then I noticed the year...

    I'll try to reply, but forgive me if I've forgotten details of the thread!



    int a[10];

    void foo1(int i, int x) {
         a[i] = x;
    }

    int& A(int i) {
         return a[i];
    }

    void foo2(int i, int x) {
         A(i) = x;
    }

    foo1 and foo2 do the same thing, and have the same code.  Of course,
    foo2 could add range checking, or offsets (for 1-based array), or have
    multiple parameters for multi-dimensional arrays, etc.  And in practice
    you'd make such functions methods of a class so that the class owns the
    data, rather than having a single global source of the data.

    I see at https://www.geeksforgeeks.org/references-in-cpp/ code which includes

    void swap(int& first, int& second)
    {
        int temp = first;
        first = second;
        second = temp;
    }

    That's not what I was thinking about. I don't care for it because in a
    call such as

      swap(a, b)

    it's not clear in the syntax that the arguments a and b can be modified
    - a calamity of a design, IMO. :-(


    That is a reasonable view. It is not uncommon in C++ programming to
    have a rule that you use pointers when the operands will be changed, and
    only use references as "const T&" types. Since the function can't
    change data that is passed by const reference, from the caller viewpoint
    it is just like passing by value. The only real difference is the
    efficiency - whether a real value is passed, or an address pointing to
    the value.

    But in your case you are referring to a /returned/ value. That appears
    to be OK except that to match what I had in mind I think there should be
    a const in there somewhere. To illustrate, I was proposing that in a function, f, one could have

      return h

    which would /conceptually/ return the address of h (which I guess in
    Algol terms means it would return h rather than the value of h).
    Crucially, and perhaps at variance with Algol (I don't know) the value
    of h (i.e. the value at the returned address) would be read-only to the caller.

    That would be returning a const reference, in C++ terms. And like const reference parameters, it is semantically very similar to returning a
    value, but with possible efficiency differences. The only thing you
    need to be careful about is whether the object pointed to still exists -
    you don't want to return a reference to a local object!


    The caller would be able to use the address returned as it could any
    other address, but it could not write over the referenced value. If the callee returned with something like

      return a[4]

    then it would conceptually return the address of a[4] and, again, the
    value at the returned address would be read-only in the caller.

    What I've said so far is by default but overwriting would be possible.
    To conceptually return the address of a variable which /could/ be overwritten one would use the rw modifier as in

      return rw h

    or

      return rw a[4]

    I'll say no more just now as this is an old topic but I wanted to at
    least make a reply.




    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Andy Walker@anw@cuboid.co.uk to comp.lang.misc on Sat Dec 9 21:40:12 2023
    From Newsgroup: comp.lang.misc

    On 08/12/2023 19:28, James Harris wrote:
    [...] To illustrate, I was
    proposing that in a function, f, one could have
    return h
    which would /conceptually/ return the address of h (which I guess in
    Algol terms means it would return h rather than the value of h).

    In Algol terms, it would return "h" coerced to the declared
    type of the function. That could be "h" itself, if it already has
    that type, but more generally could involve any of the coercions
    available to the compiler, singly or combined together as defined
    in the syntax by the Revised Report. Some notes:

    -- An applied occurrence of an identifier in Algol /always/ means
    a priori the object defined by the defining occurrence of that
    identifier.

    -- The return value from a function is a "strong" position; the
    compiler knows exactly, from the declaration of the function,
    what type is required. So all available coercions can be used.
    This is in contrast to other positions, such as operands and
    the LHS of an assignment, where only some coercions are allowed.
    This is all defined by the syntax, which is carefully designed
    to be unambiguous.

    -- If "h" is a variable, ie an address in the computer, then "h"
    /is/ that address. If you want to use instead the value at that
    address, then "h" must be dereferenced, almost always implicitly,
    in accordance with the syntax.

    -- Trying to explain all this always makes Algol seem much more
    complicated than it really is. IRL, everything just works, and
    does so in a natural and convenient way. C-style languages go
    around the houses to achieve the same effects, but we are all
    [sadly] used to that.

    Crucially, and perhaps at variance with Algol (I don't know) the
    value of h (i.e. the value at the returned address) would be
    read-only to the caller.

    Algol has no concept of "read-only variables". There were
    some proposals for "in" and "out" parameters, but they never got any
    real traction. So, in the present context, it depends on what the
    returned value is. Eg, a procedure returning int of course returns
    something "read only"; you can't overwrite [eg] 2 with 3. If OTOH
    it returns a variable [such as a "ref int"], a place in the computer,
    then you can [also of course] change what value is stored there.
    Thus, "2 := 3" is forbidden, but "int h := 2; ...; h := 3;" is fine.
    Then you can't change "h" [it will remain the same place], but you
    can [of course] change whether a pointer points at "h" or at some
    other place. [The use of "letter aleph" in the RR, which creates
    identifiers known to the OS but that a programmer cannot access in
    the program, solves many, but not all, of the real-life problems for
    which other languages need "const".]
    --
    Andy Walker, Nottingham.
    Andy's music pages: www.cuboid.me.uk/andy/Music
    Composer of the day: www.cuboid.me.uk/andy/Music/Composers/Richards
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From James Harris@james.harris.1@gmail.com to comp.lang.misc on Tue Dec 12 16:00:21 2023
    From Newsgroup: comp.lang.misc

    On 09/12/2023 14:33, David Brown wrote:
    On 08/12/2023 20:28, James Harris wrote:
    On 03/12/2021 09:08, David Brown wrote:
    On 02/12/2021 22:42, James Harris wrote:
    On 02/12/2021 20:49, Dmitry A. Kazakov wrote:
    On 2021-12-02 21:31, James Harris wrote:

    ...

    But to the point, are you comfortable with the idea of the A(2) in >>>>>>
        x = A(2) + 0

    meaning the same mapping result as the A(2) in

        A(2) = 0

    ?

    Yes, in both cases the result is the array element corresponding to
    the index 2. That is the semantics of A(2).

    Cool. If A were, instead, a function that, say, ended with

       return v

    then what would you want those A(2)s to mean and should they still mean >>>> the same as each other? The latter expression would look strange to
    many.


    Do you mean like returning a reference in C++ style?

    Hi David, apologies for not replying before. I was just now looking
    for old posts that were outstanding in some way. (There may be many
    which I have yet to reply to like your one.)

    I probably left your post until I found out about C++ references and
    never got round to reading up on them.


    I saw my post was dated 03.12 (or 12.03, for any date-backwards
    Americans in the audience) and thought it was strange that I'd forgotten
    the post from 5 days ago.  Then I noticed the year...

    At the time I had to drop out of Usenet for a while but was aware that
    there was a number of posts which should be replied to. I'll try to get
    to some of the others, as well.
    --
    James Harris


    --- Synchronet 3.20a-Linux NewsLink 1.114