• Re: technology discussion =?utf-8?Q?=E2=86=92?= does the world need a "

    From yeti@21:1/5 to Lawrence D'Oliveiro on Fri Jul 5 09:12:00 2024
    Lawrence D'Oliveiro <[email protected]d> writes:

    I think we already have enough of C.

    No.

    --
    Trust me, I know what I'm doing...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to BGB on Fri Jul 5 12:20:29 2024
    BGB <[email protected]> writes:

    On 7/5/2024 3:09 AM, Keith Thompson wrote:
    BGB <[email protected]> writes:
    On 7/4/2024 8:05 PM, Lawrence D'Oliveiro wrote:
    It’s called “Rust”.


    If anything, I suspect may make sense to go a different direction:
    Not to a bigger language, but to a more narrowly defined language.

    Basically, to try to distill what C does well, keeping its core
    essence intact.


    Goal would be to make it easier to get more consistent behavior across
    implementations, and also to make it simpler to implement (vs an
    actual C compiler); with a sub-goal to allow for implementing a
    compiler within a small memory footprint (as would be possible for K&R
    or C89).


    Say for example:
    Integer type sizes are defined;
    Nominally, integers are:
    Twos complement;
    Little endian;
    Wrap on overflow.
    Dropped features:
    VLAs
    Multidimensional arrays (*1)
    Bitfields
    ...
    Simplified declaration syntax (*2):
    {Modifier|Attribute}* TypeName Declarator


    *1: While not exactly that rare, and can be useful, it is debatable if
    they add enough to really justify their complexity and relative
    semantic fragility. If using pointers, one almost invariably needs to
    fall back to doing "arr[y*N+x]" or similar anyways, so it is arguable
    that it could make sense to drop them and have people always do their
    multidimensional indexing manually.

    Note that multidimensional indexing via multiple levels of pointer
    indirection would not be effected by this.
    [...]
    Multidimensional arrays in C are not a distinct language feature.
    They are simply arrays of arrays, and all operations on them follow
    from operations on ordinary arrays and pointers.
    Are you proposing (in this hypothetical new language) to add
    an arbitrary restriction, so that arrays can have elements of
    arithmetic, pointer, struct, etc. type, but not of array type?
    I'm not sure I see the point.

    As-is, the multidimensional arrays require the compiler to realize that it needs to multiply one index by the product of all following indices.

    So, say:
    int a[4][4];
    int j, k, l;
    l=a[j][k];

    Essentially needs to be internally translated to, say:
    l=a[j*4+k];

    Eliminating multidimensional arrays eliminates the need for this
    translation logic, and the need to be able to represent this case in the typesystem handling logic (which is, as I see it, in some ways very
    different from what one needs for a struct).

    How can it be eliminated? All your plan does is force me to wrap the
    inner array in a struct in order to get anything like the convenience of
    the above:

    struct a { int a[4]; };

    struct a a[4];
    l = a[j].a[k];

    Most compilers with generate the same arithmetic (indeed exactly the
    same code) for this as for the more convenient from that you don't like.

    All you can do to eliminate this code generation is to make it so hard
    to re-write the convenient code you dislike. (And yes, I used the same
    name all over the place because you are forcing me to.)

    While eliminating structs could also simplify things; structs also tend to
    be a lot more useful.

    Indeed. And I'd have to use them for this!

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to BGB on Fri Jul 5 23:40:45 2024
    BGB <[email protected]> writes:

    On 7/5/2024 6:20 AM, Ben Bacarisse wrote:
    BGB <[email protected]> writes:

    On 7/5/2024 3:09 AM, Keith Thompson wrote:
    BGB <[email protected]> writes:
    On 7/4/2024 8:05 PM, Lawrence D'Oliveiro wrote:
    It’s called “Rust”.


    If anything, I suspect may make sense to go a different direction:
    Not to a bigger language, but to a more narrowly defined language. >>>>>
    Basically, to try to distill what C does well, keeping its core
    essence intact.


    Goal would be to make it easier to get more consistent behavior across >>>>> implementations, and also to make it simpler to implement (vs an
    actual C compiler); with a sub-goal to allow for implementing a
    compiler within a small memory footprint (as would be possible for K&R >>>>> or C89).


    Say for example:
    Integer type sizes are defined;
    Nominally, integers are:
    Twos complement;
    Little endian;
    Wrap on overflow.
    Dropped features:
    VLAs
    Multidimensional arrays (*1)
    Bitfields
    ...
    Simplified declaration syntax (*2):
    {Modifier|Attribute}* TypeName Declarator


    *1: While not exactly that rare, and can be useful, it is debatable if >>>>> they add enough to really justify their complexity and relative
    semantic fragility. If using pointers, one almost invariably needs to >>>>> fall back to doing "arr[y*N+x]" or similar anyways, so it is arguable >>>>> that it could make sense to drop them and have people always do their >>>>> multidimensional indexing manually.

    Note that multidimensional indexing via multiple levels of pointer
    indirection would not be effected by this.
    [...]
    Multidimensional arrays in C are not a distinct language feature.
    They are simply arrays of arrays, and all operations on them follow
    from operations on ordinary arrays and pointers.
    Are you proposing (in this hypothetical new language) to add
    an arbitrary restriction, so that arrays can have elements of
    arithmetic, pointer, struct, etc. type, but not of array type?
    I'm not sure I see the point.

    As-is, the multidimensional arrays require the compiler to realize that it >>> needs to multiply one index by the product of all following indices.

    So, say:
    int a[4][4];
    int j, k, l;
    l=a[j][k];

    Essentially needs to be internally translated to, say:
    l=a[j*4+k];

    Eliminating multidimensional arrays eliminates the need for this
    translation logic, and the need to be able to represent this case in the >>> typesystem handling logic (which is, as I see it, in some ways very
    different from what one needs for a struct).
    How can it be eliminated? All your plan does is force me to wrap the
    inner array in a struct in order to get anything like the convenience of
    the above:
    struct a { int a[4]; };
    struct a a[4];
    l = a[j].a[k];
    Most compilers with generate the same arithmetic (indeed exactly the
    same code) for this as for the more convenient from that you don't like.
    All you can do to eliminate this code generation is to make it so hard
    to re-write the convenient code you dislike. (And yes, I used the same
    name all over the place because you are forcing me to.)


    It is not so much a dislike of multidimensional arrays as a concept, but rather, the hair they add to the compiler and typesystem.

    Granted, one would still have other complex types, like structs and
    function pointers, so potentially the complexity savings would be
    limited.

    Then the "hair" is still there.

    While eliminating structs could also simplify things; structs also tend to >>> be a lot more useful.
    Indeed. And I'd have to use them for this!


    Errm, the strategy I would assume is, as noted:
    int a[4][4];
    ...
    l=a[j][k];
    Becomes:
    int a[16];
    ...
    l=a[j*4+k];

    That's what you want to force me to write, but I can use and array of
    arrays despite your arbitrary ban on them by simply putting the array in
    a struct.

    Anyway, sine C exists, I won't be forced to use your proposed
    alternative.

    Much like what one would typically need to do anyways if the array was heap-allocated.

    Only if you forbid variably modified types (note not VLAs).

    int (*a)[n] = malloc(m * sizeof *a);

    allows me to index a[i][j] conveniently.

    Though, the major goal for this sort of thing is mostly to try to limit the complexity required to write a compiler (as opposed to programmer convenience).

    Ah.

    Like, for example, I had tried (but failed) to write a usable C compiler in less than 30k lines (and also ideally needing less than 4MB of RAM). But,
    if the language design is simplified some, this might be a little
    closer. Might still be doable, but a C compiler in 50-75k lines is much
    less impressive.

    Why do you think this matters to other people?

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to BGB on Sat Jul 6 23:41:32 2024
    BGB <[email protected]> writes:

    On 7/5/2024 5:40 PM, Ben Bacarisse wrote:
    BGB <[email protected]> writes:

    On 7/5/2024 6:20 AM, Ben Bacarisse wrote:
    BGB <[email protected]> writes:

    While eliminating structs could also simplify things; structs also tend to
    be a lot more useful.
    Indeed. And I'd have to use them for this!


    Errm, the strategy I would assume is, as noted:
    int a[4][4];
    ...
    l=a[j][k];
    Becomes:
    int a[16];
    ...
    l=a[j*4+k];
    That's what you want to force me to write, but I can use and array of
    arrays despite your arbitrary ban on them by simply putting the array in
    a struct.
    ...
    IN most contexts, I don't really see how a struct is preferable to a multiply, but either way...

    And I can't see how an array of arrays is harder for your compiler than
    an array of structs. C's indexing requires the compiler to know that
    size of the items pointed to.

    I suspect that there is something amiss with your design if you are
    considering this limiting in order to simplify the compiler. A simple
    compiler should not care what kind of thing p points to in

    p[i]

    only what size of object p points to.

    Whole language design is still a hypothetical at this point anyways (and my actual compiler does support multidimensional arrays).

    Ah. I think that when you've written most of it, you will see that
    ruling out arrays of arrays will have not simplifying effect.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Lawrence D'Oliveiro on Sat Jul 6 23:24:17 2024
    Lawrence D'Oliveiro <[email protected]d> writes:

    On Fri, 05 Jul 2024 19:00:58 -0700, Keith Thompson wrote:

    C assumes byte addressibility, but it doesn't assume that bytes are 8
    bits.

    The PDP-10 had 36-bit words and could operate on bit fields of any size
    from 1 to 36 bits.

    But it couldn’t address them.

    And C does not assume that the hardware can address bytes. On word
    addressed machines, some pointer conversions generate code.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Keith Thompson on Sat Jul 6 20:04:17 2024
    Keith Thompson <[email protected]> writes:

    Ben Bacarisse <[email protected]> writes:

    BGB <[email protected]> writes:

    On 7/5/2024 5:40 PM, Ben Bacarisse wrote:

    [...]

    Whole language design is still a hypothetical at this point anyways (and my >>> actual compiler does support multidimensional arrays).

    Ah. I think that when you've written most of it, you will see that
    ruling out arrays of arrays will have not simplifying effect.

    Indeed. I believe (based on no direct experience) that you could write
    a fully conforming C compiler without even thinking about
    multidimensional arrays, and if you get the array code right, multidimensional arrays will just work.

    There are some corner cases that seem to require some thinking.
    For example,

    extern int x[];
    extern int y[][10];

    are both alright, but

    extern int z[10][];

    is not. There are similar cases with function parameters, and
    maybe with VLAs. Also, possibly, flexible array members (do I
    have that name right?).

    Not saying the amount of thinking needed is overpowering, but
    it does seem to be greater than zero.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Lawrence D'Oliveiro on Sat Jul 6 20:15:41 2024
    Lawrence D'Oliveiro <[email protected]d> writes:

    On Fri, 05 Jul 2024 19:00:58 -0700, Keith Thompson wrote:

    C assumes byte addressibility, but it doesn't assume that bytes are 8
    bits.

    The PDP-10 had 36-bit words and could operate on bit fields of any size
    from 1 to 36 bits.

    But it couldn't address them.

    Actually it could. There was a special form of hardware pointer
    designed specifically to address sub-word bitfields.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Kaz Kylheku on Mon Jul 8 10:53:47 2024
    Kaz Kylheku <[email protected]> writes:

    On 2024-07-07, James Kuyper <[email protected]> wrote:
    On 7/7/24 16:10, BGB wrote:
    On 7/7/2024 9:03 AM, James Kuyper wrote:
    On 7/7/24 00:55, BGB wrote:
    On 7/6/2024 5:38 PM, Keith Thompson wrote:
    ...
    No, there is no implicitly defined pointer.
    ...
    This implicit pointer need not exist at a location in memory...

    Which is why C doesn't give you access to it's location in memory -
    something you complained about earlier.

    I don't think I was claiming that one should have direct access to its
    location or value within the language, rather that their existence and
    behaviors could be acknowledged in the language design (for a "not
    quite C" language).

    I think that the existence of an implicit pointer would be a bad thing
    to acknowledge, given that the language doesn't require that it exist,
    and typical implementations don't use them. From what I understand, the
    fact that your implementation does have implicit pointers makes it a rarity.

    Ritchie's B language had arrays which contained a pointer to their
    first element. Via a hack, it was possible to relocate an array.

    Nit: Ritchie describes B as Thompson's own language. He might have been
    being very modest, but that seems unlikely.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Kaz Kylheku on Mon Jul 8 19:01:33 2024
    Kaz Kylheku <[email protected]> writes:

    On 2024-07-07, James Kuyper <[email protected]> wrote:

    On 7/7/24 16:10, BGB wrote:

    On 7/7/2024 9:03 AM, James Kuyper wrote:

    On 7/7/24 00:55, BGB wrote:

    On 7/6/2024 5:38 PM, Keith Thompson wrote:

    ...

    No, there is no implicitly defined pointer.

    ...

    This implicit pointer need not exist at a location in memory...

    Which is why C doesn't give you access to it's location in memory -
    something you complained about earlier.

    I don't think I was claiming that one should have direct access to its
    location or value within the language, rather that their existence and
    behaviors could be acknowledged in the language design (for a "not
    quite C" language).

    I think that the existence of an implicit pointer would be a bad thing
    to acknowledge, given that the language doesn't require that it exist,
    and typical implementations don't use them. From what I understand, the
    fact that your implementation does have implicit pointers makes it a rarity.

    Ritchie's B language had arrays which contained a pointer to their
    first element. Via a hack, it was possible to relocate an array.

    In C, such a thing is not simply not required; it is ruled out
    by the detailed semantic description of arrays. [...]

    Not to muddy the waters, but there are circumstances where
    it is advantageous to put an array "somewhere else" and
    simply keep a pointer to it locally.

    Having said that, it must also be said that such pointers
    are purely implementation details and have no place in
    the abstract machine. As far as the abstract machine is
    concerned, an array is just an array, and not an array
    and a pointer.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to bart on Tue Jul 9 16:58:50 2024
    bart <[email protected]> writes:

    Arrays are passed by reference:

    void F(int a[20]) {}

    int main(void) {
    int x[20];
    F(x);
    }

    This is the sort of thing that bad tutors say to students so that they
    never learn C properly. All parameter passing in C is by value. All of
    it. You just have to know (a) what the syntax means and (b) what values
    get passed.

    void F(int a[20]) ... declares a to be of type int *. Feel free to rail
    about that as much as you like but that is what that syntax means.

    The x in F(x) is converted to a pointer to x[0] since the x is not an
    operand of &, sizeof etc. F(x) passes a pointer by value. F receives a pointer value in a.

    Although the type of 'a' inside 'F' will be int* rather than
    int(*)[20].

    No. a is of type int *.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to bart on Tue Jul 9 18:22:56 2024
    bart <[email protected]> writes:

    On 09/07/2024 16:58, Ben Bacarisse wrote:
    bart <[email protected]> writes:

    Arrays are passed by reference:

    void F(int a[20]) {}

    int main(void) {
    int x[20];
    F(x);
    }
    This is the sort of thing that bad tutors say to students so that they
    never learn C properly. All parameter passing in C is by value. All of
    it. You just have to know (a) what the syntax means and (b) what values
    get passed.

    The end result is that a parameter declared with value-array syntax is
    passed using a reference rather than by value.

    And it does so because the language says, not because the ABI requires
    it. A 2-byte array is also passed by reference.

    An address value is passed by value. C has only one parameter passing mechanism. You can spin it as much as you like, but C's parameter
    passing is simple to understand, provided learner tune out voices like
    yours.

    void F(int a[20]) ... declares a to be of type int *. Feel free to rail
    about that as much as you like but that is what that syntax means.
    The x in F(x) is converted to a pointer to x[0] since the x is not an
    operand of &, sizeof etc. F(x) passes a pointer by value. F receives a
    pointer value in a.

    Although the type of 'a' inside 'F' will be int* rather than
    int(*)[20].
    No. a is of type int *.

    And that is different 'int*' how, about from having an extra space which C says is not signigicant in this context?

    Sorry, I missed what you wrote. I don't know why even brought up int
    (*)[20] but I thought you were saying that was the type of a.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to bart on Tue Jul 9 14:23:47 2024
    bart <[email protected]> writes:

    On 09/07/2024 18:22, Ben Bacarisse wrote:

    bart <[email protected]> writes:

    On 09/07/2024 16:58, Ben Bacarisse wrote:

    bart <[email protected]> writes:

    Arrays are passed by reference:

    void F(int a[20]) {}

    int main(void) {
    int x[20];
    F(x);
    }

    This is the sort of thing that bad tutors say to students so that they >>>> never learn C properly. All parameter passing in C is by value. All of >>>> it. You just have to know (a) what the syntax means and (b) what values >>>> get passed.

    The end result is that a parameter declared with value-array syntax is
    passed using a reference rather than by value.

    And it does so because the language says, not because the ABI requires
    it. A 2-byte array is also passed by reference.

    An address value is passed by value. C has only one parameter passing
    mechanism. You can spin it as much as you like, but C's parameter
    passing is simple to understand, provided learner tune out voices like
    yours.

    Little about C's type system is simple. You're doing your students a disservice if you try and hide all the quirks.

    That's what you are doing, only worse.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to BGB on Wed Jul 10 00:15:13 2024
    BGB <[email protected]> writes:

    On 7/9/2024 12:22 PM, Ben Bacarisse wrote:
    bart <[email protected]> writes:

    On 09/07/2024 16:58, Ben Bacarisse wrote:
    bart <[email protected]> writes:

    Arrays are passed by reference:

    void F(int a[20]) {}

    int main(void) {
    int x[20];
    F(x);
    }
    This is the sort of thing that bad tutors say to students so that they >>>> never learn C properly. All parameter passing in C is by value. All of >>>> it. You just have to know (a) what the syntax means and (b) what values >>>> get passed.

    The end result is that a parameter declared with value-array syntax is
    passed using a reference rather than by value.

    And it does so because the language says, not because the ABI requires
    it. A 2-byte array is also passed by reference.
    An address value is passed by value. C has only one parameter passing
    mechanism. You can spin it as much as you like, but C's parameter
    passing is simple to understand, provided learner tune out voices like
    yours.

    Though, in ABI specs, this would usually still be termed as "pass by reference"

    I am not saying that Bart is alone in getting this wrong. Any document
    that that says that C have any parameter passing mechanism other than
    pass by value is wrong. But then I doubt any ABI spec says that since
    an ABI is, almost by definition, not about the C language.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to bart on Wed Jul 10 00:35:57 2024
    bart <[email protected]> writes:

    On 09/07/2024 18:22, Ben Bacarisse wrote:
    bart <[email protected]> writes:

    On 09/07/2024 16:58, Ben Bacarisse wrote:
    bart <[email protected]> writes:

    Arrays are passed by reference:

    void F(int a[20]) {}

    int main(void) {
    int x[20];
    F(x);
    }
    This is the sort of thing that bad tutors say to students so that they >>>> never learn C properly. All parameter passing in C is by value. All of >>>> it. You just have to know (a) what the syntax means and (b) what values >>>> get passed.

    The end result is that a parameter declared with value-array syntax is
    passed using a reference rather than by value.

    And it does so because the language says, not because the ABI requires
    it. A 2-byte array is also passed by reference.
    An address value is passed by value. C has only one parameter passing
    mechanism. You can spin it as much as you like, but C's parameter
    passing is simple to understand, provided learner tune out voices like
    yours.

    Little about C's type system is simple.

    Parameter passing is relatively simple though since there is only one
    mechanism -- pass by value.

    You're doing your students a
    disservice if you try and hide all the quirks.

    If. Always with the if. There are lots of things I don't do that would
    be doing my students a disservice were I to do them. Beautiful spin!

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Kaz Kylheku on Wed Jul 10 14:23:22 2024
    Kaz Kylheku <[email protected]> writes:

    - int (f[3])(void) { }, function returning array of 3 int,
    is a constraint violation.

    Nit: this is an array of three functions. Also a constraint violation
    and a syntax error as array declarations can't be followed by {}s. The impossible declaration you want would be written

    int F(void)[3] {}

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to bart on Wed Jul 10 14:32:00 2024
    bart <[email protected]> writes:

    On 10/07/2024 00:35, Ben Bacarisse wrote:
    bart <[email protected]> writes:

    On 09/07/2024 18:22, Ben Bacarisse wrote:
    bart <[email protected]> writes:

    On 09/07/2024 16:58, Ben Bacarisse wrote:
    bart <[email protected]> writes:

    Arrays are passed by reference:

    void F(int a[20]) {}

    int main(void) {
    int x[20];
    F(x);
    }
    This is the sort of thing that bad tutors say to students so that they >>>>>> never learn C properly. All parameter passing in C is by value. All of >>>>>> it. You just have to know (a) what the syntax means and (b) what values >>>>>> get passed.

    The end result is that a parameter declared with value-array syntax is >>>>> passed using a reference rather than by value.

    And it does so because the language says, not because the ABI requires >>>>> it. A 2-byte array is also passed by reference.
    An address value is passed by value. C has only one parameter passing >>>> mechanism. You can spin it as much as you like, but C's parameter
    passing is simple to understand, provided learner tune out voices like >>>> yours.

    Little about C's type system is simple.
    Parameter passing is relatively simple though since there is only one
    mechanism -- pass by value.

    Except when it comes to arrays.

    The oddity is that, in C, one can't pass arrays to functions at all.
    That is one of the quirks that people learning C need to learn. It does
    not alter the fact that there is only parameter passing mechanism -- by
    value.

    Your plan, of course, is to take that one place where C is relatively
    simple and complicate by pretending that C as pass by reference as well
    as by value.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to bart on Wed Jul 10 08:48:05 2024
    bart <[email protected]> writes:

    I earlier asked this:

    "So if arrays aren't passed by value in C, and they aren't passed
    by reference, then how the hell ARE they passed?!"

    They aren't. C allows lots of things to be passed as an argument
    to a function: several varieties of numeric values, structs,
    unions, and pointers, including both pointers to object types and
    pointers to function types. C does not have a way for a function
    to take an argument that is either an array or a function. There
    is a way to take pointers to those things, but not the things
    themselves. Arrays and functions are second-class values in C.

    For some reason you insist on confusing your view of how the world
    is with how the world actually is. No matter how many times you
    ask the question, you're going to get the same answer, because the
    people who are answering are saying how the world actually is, and
    not how you think it is.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to bart on Thu Jul 11 00:01:55 2024
    bart <[email protected]> writes:

    On 10/07/2024 14:32, Ben Bacarisse wrote:
    bart <[email protected]> writes:

    On 10/07/2024 00:35, Ben Bacarisse wrote:
    bart <[email protected]> writes:

    On 09/07/2024 18:22, Ben Bacarisse wrote:
    bart <[email protected]> writes:

    On 09/07/2024 16:58, Ben Bacarisse wrote:
    bart <[email protected]> writes:

    Arrays are passed by reference:

    void F(int a[20]) {}

    int main(void) {
    int x[20];
    F(x);
    }
    This is the sort of thing that bad tutors say to students so that they >>>>>>>> never learn C properly. All parameter passing in C is by value. All of
    it. You just have to know (a) what the syntax means and (b) what values
    get passed.

    The end result is that a parameter declared with value-array syntax is >>>>>>> passed using a reference rather than by value.

    And it does so because the language says, not because the ABI requires >>>>>>> it. A 2-byte array is also passed by reference.
    An address value is passed by value. C has only one parameter passing >>>>>> mechanism. You can spin it as much as you like, but C's parameter >>>>>> passing is simple to understand, provided learner tune out voices like >>>>>> yours.

    Little about C's type system is simple.
    Parameter passing is relatively simple though since there is only one
    mechanism -- pass by value.

    Except when it comes to arrays.
    The oddity is that, in C, one can't pass arrays to functions at all.
    That is one of the quirks that people learning C need to learn. It does
    not alter the fact that there is only parameter passing mechanism -- by
    value.
    Your plan, of course, is to take that one place where C is relatively
    simple

    It is not that simple. It is confusing. It is error prone.

    It is simple but you can certainly confuse people by lying about it. I
    agree that it's error prone. That's why making sure your
    misrepresentation is corrected is so important.

    I earlier asked this:

    "So if arrays aren't passed by value in C, and they aren't passed by reference, then how the hell ARE they passed?!"

    And I answered that.

    I haven't had a reply yet.

    Yes you have. You have even quoted me on the subject in this very
    message: "in C, one can't pass arrays to functions at all".

    I still consider arrays in C to be 'passed' by a
    mechanism which is near-indistinguishable from actual
    pass-by-reference.

    I don't really care how you consider it, but I do care about how you misrepresent the facts in public.

    In another post you said that your language has pass by reference, and
    we also know you have implemented C. Either you are just very confused
    and your language simply has call by value (after all, you think C has
    pass by reference), or you know that pass by reference in your language
    needs something from the implementation that was not needed when you implemented C. I can't decide if you are confused or just lying.

    If somebody had proposed adding pass-by-reference for arrays, you'd say C doesn't need it, because whatever benefits it might have you, C already
    has!

    I see you are running out of statements to argue against so you have
    started to make up your own. I am sure you have thoroughly refuted this
    made up person in your head.

    Anyone proposing adding pass-by-reference for arrays would be told (by
    me at last) to start by allowing arrays to be passed by value first.
    Why anyone would propose adding pass by reference for a type that can't
    be currently be passed at all is a mystery that only you (as the
    inventor of this person) can know.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to bart on Thu Jul 11 02:29:15 2024
    bart <[email protected]> writes:

    On 11/07/2024 00:01, Ben Bacarisse wrote:
    bart <[email protected]> writes:

    On 10/07/2024 14:32, Ben Bacarisse wrote:

    I still consider arrays in C to be 'passed' by a
    mechanism which is near-indistinguishable from actual
    pass-by-reference.
    I don't really care how you consider it, but I do care about how you
    misrepresent the facts in public.
    In another post you said that your language has pass by reference, and
    we also know you have implemented C. Either you are just very confused
    and your language simply has call by value (after all, you think C has
    pass by reference), or you know that pass by reference in your language
    needs something from the implementation that was not needed when you
    implemented C. I can't decide if you are confused or just lying.


    The way it works in my language is very simple...

    I'll cut the remarks I would otherwise make as it's off topic for a C
    group.

    ...
    But when T is an array, its behaviour is more like that of my H function.

    So, my remark about arrays in C being passed by reference is understandable.

    I have always understood why you say this. It "looks a bit like it".

    But you have clarified. You have known all along that C passes
    everything by value because you have implemented it. You know how to
    implement pass by reference and your C compiler does not implement it.

    If somebody had proposed adding pass-by-reference for arrays, you'd say C >>> doesn't need it, because whatever benefits it might have you, C already
    has!
    I see you are running out of statements to argue against so you have
    started to make up your own. I am sure you have thoroughly refuted this
    made up person in your head.
    Anyone proposing adding pass-by-reference for arrays would be told (by
    me at last) to start by allowing arrays to be passed by value first.
    Why anyone would propose adding pass by reference for a type that can't
    be currently be passed at all is a mystery that only you (as the
    inventor of this person) can know.

    This is my point. Clearly true pass-by-reference for arrays wouldn't add anything in C;

    It would add the ability to pass an array to a function -- something
    that C does not have. How many times will you have to be told?

    it already works alike that!

    It does not. It works like passing a pointer by value, not like passing
    an array by reference. You have clearly shown that you know the
    difference. You are now just tolling.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Michael S on Thu Jul 11 11:56:25 2024
    Michael S <[email protected]> writes:

    On Thu, 11 Jul 2024 08:41:14 -0000 (UTC)
    Kaz Kylheku <[email protected]> wrote:
    ...
    First class functions could do something like this:

    // multiplier takes a coefficient and returns a pointer to
    // function

    int (*multiplier(int coefficient))(int) {
    // fantasy lambda syntax. Return type int is written after
    // parameter list.
    return lambda(int x) int {
    return coefficient * x;
    }
    }

    int (*doubler)(int) = multiplier(2);

    int x = doubler(42); // x becomes 84

    Even though the lambda is returned out of multiplier, whose execution
    terminates, when the returned function is invoked, it can refer to the
    coefficient, which is captured in a lexical closure.

    With a C-like typedef, we can declutter the definition of mutiplier:

    typedef int (*int_int_fn)(int);

    int_int_fn multiplier(int coefficient) {
    return lambda(int x) int {
    return coefficient * x;
    }
    }


    Thank you.
    Your example confirms my suspicion that the difference between first
    and second class of functions doesn't become material until language
    supports closures.

    That's half true, but it concentrates on something that is partly
    syntactic -- the lexical binding of names. It possible to do the same
    things with no names in sight so the term "closure" would seem rather
    odd. For example, Kaz's example could be written like this is Haskell:

    $ ghci
    GHCi, version 9.4.7: https://www.haskell.org/ghc/ :? for help
    ghci> multiplier = (*)
    ghci> doubler = multiplier 2
    ghci> doubler 42
    84

    and, indeed, one way to implement Haskell is is to tranform the code
    into combinators. Combinators were first studied by logicians like
    Haskell Curry as a way to re-write formal logics that use quantifiers
    (which bind names) into nameless forms.

    Of course, "something" is mysteriously doing the same work as the
    closures in Kaz's examples, but it not using lexical binding to it.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to bart on Thu Jul 11 04:28:13 2024
    bart <[email protected]> writes:

    On 10/07/2024 16:48, Tim Rentsch wrote:

    bart <[email protected]> writes:

    I earlier asked this:

    "So if arrays aren't passed by value in C, and they aren't passed
    by reference, then how the hell ARE they passed?!"

    They aren't. C allows lots of things to be passed as an argument
    to a function: several varieties of numeric values, structs,
    unions, and pointers, including both pointers to object types and
    pointers to function types. C does not have a way for a function
    to take an argument that is either an array or a function. There
    is a way to take pointers to those things, but not the things
    themselves. Arrays and functions are second-class values in C.

    That's a good point. It's not just arrays that can't be passed by
    value (because the language says so) but also functions (because its
    not meaningful).

    Yet, although pointers to arrays and function can be passed (without
    even doing anything special like using &), you are not allowed to say
    that anything is passed by reference in C!

    My comment is not about what people are allowed to say. It's
    about what is true. The truth is, in C, all function arguments
    are passed by value. That statement doesn't depend on how anyone
    thinks about it or what they call it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to bart on Thu Jul 11 04:35:27 2024
    bart <[email protected]> writes:

    On 11/07/2024 00:01, Ben Bacarisse wrote:

    bart <[email protected]> writes:

    On 10/07/2024 14:32, Ben Bacarisse wrote:

    I still consider arrays in C to be 'passed' by a
    mechanism which is near-indistinguishable from actual
    pass-by-reference.

    I don't really care how you consider it, but I do care about how you
    misrepresent the facts in public.

    In another post you said that your language has pass by reference, and
    we also know you have implemented C. Either you are just very confused
    and your language simply has call by value (after all, you think C has
    pass by reference), or you know that pass by reference in your language
    needs something from the implementation that was not needed when you
    implemented C. I can't decide if you are confused or just lying.

    The way it works in my language is very simple (this is what I do
    after all):

    type T = int

    proc F(T x)= # Pass by value
    println x.typestr
    end

    proc G(ref T x)= # Manual pass-by-reference
    println x^.typestr
    end

    proc H(T &x)= # Auto pass-by-reference
    println x.typestr
    end

    proc main=
    T a

    F(a)
    G(&a)
    H(a)
    end

    I've written 3 functions using pass-by-value, pass-by-value emulating pass-by-reference, and actual pass-by-reference. [...]

    No one doubts that call by reference can be implemented.
    The point is that call by reference is not what C does.
    And no amount of analogy or imagination or wishful
    thinking is going to change that.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to bart on Thu Jul 11 04:49:03 2024
    bart <[email protected]> writes:

    On 10/07/2024 19:39, Michael S wrote:

    On Wed, 10 Jul 2024 18:30:54 +0100
    bart <[email protected]> wrote:

    On 10/07/2024 16:48, Tim Rentsch wrote:

    bart <[email protected]> writes:
    >>>> I earlier asked this:

    "So if arrays aren't passed by value in C, and they aren't passed
    by reference, then how the hell ARE they passed?!"

    They aren't. C allows lots of things to be passed as an argument
    to a function: several varieties of numeric values, structs,
    unions, and pointers, including both pointers to object types and
    pointers to function types. C does not have a way for a function
    to take an argument that is either an array or a function. There
    is a way to take pointers to those things, but not the things
    themselves. Arrays and functions are second-class values in C.

    That's a good point. It's not just arrays that can't be passed by
    value (because the language says so) but also functions (because its
    not meaningful).

    Yet, although pointers to arrays and function can be passed (without
    even doing anything special like using &), you are not allowed to say
    that anything is passed by reference in C!

    The automatic conversion to a pointer, which is also a feature of
    true pass-by-reference, doesn't count.

    Not needing an explicit deref inside the callee (another
    characteristic of pass-by-reference) doesn't count either.

    It does not count, because automatic conversion to a pointer is not
    something that happens only during parameter passing. For arrays, it
    happens in all contexts except sizeof(). For functions, it happens in
    all contexts except function call. Or, may be, including function call,
    in this case (but not in case of arrays) it depends on point of view.

    Suppose that was to happen in all contexts, not just for arrays and functions, but for all types.

    That means that if A, B, C were numbers, then any call such as F(A, B,
    C) would pass the addresses of the numbers rather than their values.

    According to what people have said, C would STILL be a language that
    passed thing by value, and never by automatic reference.

    First, the scheme that you outline is either dumb or disingenuous
    (or perhaps both).

    Second, the argument you're making is purely ad hominem: it
    isn't about what is true but about what it is people will say, or
    at least what you think they would say.

    Third, none of this changes the underlying reality. Whatever
    people might say about your hypothetical scenario, or whatever it
    is you think they would say, it doesn't alter the fact that in C
    all function arguments are passed by value, and not by reference.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to bart on Thu Jul 11 06:26:18 2024
    bart <[email protected]> writes:

    On 11/07/2024 12:49, Tim Rentsch wrote:

    bart <[email protected]> writes:

    According to what people have said, C would STILL be a language that
    passed thing by value, and never by automatic reference.

    First, the scheme that you outline is either dumb or disingenuous
    (or perhaps both).

    Second, the argument you're making is purely ad hominem: it
    isn't about what is true but about what it is people will say, or
    at least what you think they would say.

    Third, none of this changes the underlying reality. Whatever
    people might say about your hypothetical scenario, or whatever it
    is you think they would say, it doesn't alter the fact that in C
    all function arguments are passed by value, and not by reference.

    People don't write software based on the the precise, pedantic details
    of what a language reference says, which are always to use the same
    carefully selected set of terms.

    They want to write programs that do useful tasks.

    If that task calls for a function that manipulates arrays as though
    they were passed by reference, then, guess what, they will use a C
    function that the standard says always passes things by value.

    For that purpose, in the mind of the user, it does the same job as 'by
    by reference'. That it does so by some other quirks (array decay, and
    the ability to index pointers as thought they were arrays), is by the
    by.

    I understand that in this newsgroup, most posters are only interested
    in what the Standard says and little else, and will pounce upon any
    turns of phrase, any nomenclature, that deviate even slightly from
    what it says in that document.

    I also understand that this is not comp.std.c

    Meanwhile, the internet abounds with quotes like this about C:

    "When we pass the address of an array while calling a function then
    this is called function call by reference."

    "Basically, in C, function parameters that are arrays are passed by reference, by default."

    Yes, I get that such lax informality would annoy the people here.

    You have proven once again that your goal is not to inform
    but to annoy. Congratulations. Mission accomplished.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Michael S on Thu Jul 11 07:02:36 2024
    Michael S <[email protected]> writes:

    On Wed, 10 Jul 2024 08:48:05 -0700
    Tim Rentsch <[email protected]> wrote:

    bart <[email protected]> writes:

    I earlier asked this:

    "So if arrays aren't passed by value in C, and they aren't passed
    by reference, then how the hell ARE they passed?!"

    They aren't. C allows lots of things to be passed as an argument
    to a function: several varieties of numeric values, structs,
    unions, and pointers, including both pointers to object types and
    pointers to function types. C does not have a way for a function
    to take an argument that is either an array or a function. There
    is a way to take pointers to those things, but not the things
    themselves. Arrays and functions are second-class values in C.

    I'd like to see an example of the language that permits ahead-of-time compilation and has functions as first-class values.

    C is almost that language. Pointers to functions are first class
    in C. If for every C function definition a pattern like this:

    static int
    foo_implementation( int x ){
    return x > 0 ? -x : x;
    }

    int (*foo)( int ) = foo_implementation;

    is used, and there are no other references to the _implementation
    names, then "functions" like foo() are essentially first-class
    functions. The "function" foo can be assigned into. It can be
    called just like an actual C function. The type of a "function"
    is not like an actual function type, and so for example how the
    address-of operator works is different for "functions" than it is
    for actual C functions. Also pre-declarations for "functions"
    obviously need to be different than they would be for actual C
    functions. If the necessary adjustments are made, we would have
    a language with first-class "functions".

    Incidentally, whether a language has closures is orthogonal to
    the question of whether functions are first class. Closures
    might or might not be interoperable with functions (they are
    in some languages, and not in others). But that needn't have
    any bearing on whether functions (or closures) are first class.

    Note: strictly speaking a closure is a run-time value, not a
    compile-time definition. I trust my readers are able to make
    the needed linguistic accommodations.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to BGB on Thu Jul 11 14:29:41 2024
    BGB <[email protected]> writes:

    On 7/11/2024 9:02 AM, Tim Rentsch wrote:

    Michael S <[email protected]> writes:

    On Wed, 10 Jul 2024 08:48:05 -0700
    Tim Rentsch <[email protected]> wrote:

    bart <[email protected]> writes:

    I earlier asked this:

    "So if arrays aren't passed by value in C, and they aren't passed
    by reference, then how the hell ARE they passed?!"

    They aren't. C allows lots of things to be passed as an argument
    to a function: several varieties of numeric values, structs,
    unions, and pointers, including both pointers to object types and
    pointers to function types. C does not have a way for a function
    to take an argument that is either an array or a function. There
    is a way to take pointers to those things, but not the things
    themselves. Arrays and functions are second-class values in C.

    I'd like to see an example of the language that permits ahead-of-time
    compilation and has functions as first-class values.

    C is almost that language. Pointers to functions are first class
    in C. If for every C function definition a pattern like this:

    static int
    foo_implementation( int x ){
    return x > 0 ? -x : x;
    }

    int (*foo)( int ) = foo_implementation;

    is used, and there are no other references to the _implementation
    names, then "functions" like foo() are essentially first-class
    functions. The "function" foo can be assigned into. It can be
    called just like an actual C function. The type of a "function"
    is not like an actual function type, and so for example how the
    address-of operator works is different for "functions" than it is
    for actual C functions. Also pre-declarations for "functions"
    obviously need to be different than they would be for actual C
    functions. If the necessary adjustments are made, we would have
    a language with first-class "functions".

    Incidentally, whether a language has closures is orthogonal to
    the question of whether functions are first class. Closures
    might or might not be interoperable with functions (they are
    in some languages, and not in others). But that needn't have
    any bearing on whether functions (or closures) are first class.

    Note: strictly speaking a closure is a run-time value, not a
    compile-time definition. I trust my readers are able to make
    the needed linguistic accommodations.

    FWIW, there was a proposal to add C++ style lambdas to C23, but
    apparently didn't get in. [...]

    IMO the more C ignores or moves away from C++ the better.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to Janis Papanagnou on Fri Jul 12 15:42:52 2024
    On Fri, 12 Jul 2024 13:12:53 +0200
    Janis Papanagnou <[email protected]> wrote:

    But maybe he has looked up some things, since lately he's squirming
    by introducing terms like "_true_ pass-by-reference" [emphasis by me] obviously trying to bend the semantics of the established technical "pass-by-reference" term to fit his argument. (Introducing new terms
    for existing mechanisms or bending semantics of existing terms with
    well established meaning is certainly not helpful in any way.)

    But, yes, that person is a phenomenon.

    Janis


    I don't share your optimistic belief that the term "pass by reference"
    is really established. Very few terms in computer science (science?
    really?) are established firmly. Except, may be, in more theoretical
    branches of it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Michael S on Sat Jul 13 02:01:22 2024
    Michael S <[email protected]> writes:

    On Fri, 12 Jul 2024 13:12:53 +0200
    Janis Papanagnou <[email protected]> wrote:

    But maybe he has looked up some things, since lately he's squirming
    by introducing terms like "_true_ pass-by-reference" [emphasis by me]
    obviously trying to bend the semantics of the established technical
    "pass-by-reference" term to fit his argument. (Introducing new terms
    for existing mechanisms or bending semantics of existing terms with
    well established meaning is certainly not helpful in any way.)

    But, yes, that person is a phenomenon.

    I don't share your optimistic belief that the term "pass by reference"
    is really established. Very few terms in computer science (science?
    really?) are established firmly. Except, may be, in more theoretical branches of it.

    The terms

    call by name
    call by value
    call by reference
    call by value-result

    are all well-defined and firmly established, going back more than
    60 years. I learned all of these in standard early course in
    computer science sometime in the early 1970s. Of course I can't
    be sure about the source after all these years, but I expect
    they were defined in the textbook we were using in the class.

    Much later, probably under the influence of people learning
    by reading blogs rather than books, some of these terms were
    expressed as, eg, "pass by value" or "pass by reference".
    However there is no indication that the change was meant to
    express a different meaning, except insofar as the person(s)
    using the revised terms were confused.

    Anyone who refuses to stick to the firmly established meanings
    is in all likelihood just someone who enjoys being fractious.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Tim Rentsch on Sat Jul 13 13:35:02 2024
    Tim Rentsch <[email protected]> writes:

    Michael S <[email protected]> writes:

    On Fri, 12 Jul 2024 13:12:53 +0200
    Janis Papanagnou <[email protected]> wrote:

    But maybe he has looked up some things, since lately he's squirming
    by introducing terms like "_true_ pass-by-reference" [emphasis by me]
    obviously trying to bend the semantics of the established technical
    "pass-by-reference" term to fit his argument. (Introducing new terms
    for existing mechanisms or bending semantics of existing terms with
    well established meaning is certainly not helpful in any way.)

    But, yes, that person is a phenomenon.

    I don't share your optimistic belief that the term "pass by reference"
    is really established. Very few terms in computer science (science?
    really?) are established firmly. Except, may be, in more theoretical
    branches of it.

    The terms

    call by name
    call by value
    call by reference
    call by value-result

    are all well-defined and firmly established, going back more than
    60 years. I learned all of these in standard early course in
    computer science sometime in the early 1970s. Of course I can't
    be sure about the source after all these years, but I expect
    they were defined in the textbook we were using in the class.

    Much later, probably under the influence of people learning
    by reading blogs rather than books, some of these terms were
    expressed as, eg, "pass by value" or "pass by reference".

    I think it's reasonable to assume that this change of term was partly
    motivated simply by the meaning of the words. Call by value (to pick
    one) is an odd term to use about a parameter and/or argument. The
    function or procedure is called, but the arguments are passed and
    subsequently accessed. Nowadays, sentences like "Specifications of
    parameters called by value must be supplied" just feel a bit strange, at
    least to me.

    Had I been CS King, I would have promulgated the terms "accessed by
    value", "accessed by name" and so on since it's the access method that
    really what matters to my mind.

    However there is no indication that the change was meant to
    express a different meaning, except insofar as the person(s)
    using the revised terms were confused.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to BGB on Sat Jul 13 14:43:08 2024
    BGB <[email protected]> writes:

    On 7/13/2024 4:01 AM, Tim Rentsch wrote:

    Michael S <[email protected]> writes:

    On Fri, 12 Jul 2024 13:12:53 +0200
    Janis Papanagnou <[email protected]> wrote:

    But maybe he has looked up some things, since lately he's squirming
    by introducing terms like "_true_ pass-by-reference" [emphasis by me]
    obviously trying to bend the semantics of the established technical
    "pass-by-reference" term to fit his argument. (Introducing new terms
    for existing mechanisms or bending semantics of existing terms with
    well established meaning is certainly not helpful in any way.)

    But, yes, that person is a phenomenon.

    I don't share your optimistic belief that the term "pass by reference"
    is really established. Very few terms in computer science (science?
    really?) are established firmly. Except, may be, in more theoretical
    branches of it.

    The terms

    call by name
    call by value
    call by reference
    call by value-result

    are all well-defined and firmly established, going back more than
    60 years. I learned all of these in standard early course in
    computer science sometime in the early 1970s. Of course I can't
    be sure about the source after all these years, but I expect
    they were defined in the textbook we were using in the class.

    Much later, probably under the influence of people learning
    by reading blogs rather than books, some of these terms were
    expressed as, eg, "pass by value" or "pass by reference".
    However there is no indication that the change was meant to
    express a different meaning, except insofar as the person(s)
    using the revised terms were confused.

    Anyone who refuses to stick to the firmly established meanings
    is in all likelihood just someone who enjoys being fractious.

    As I see it, they are not exactly the same:
    "call by reference", is from the POV of how arguments themselves are
    passed to functions during a function call;
    "pass by reference" has more to do with the data or object being
    conveyed (usually means that a pointer to the object is being passed,
    but generally used in cases where no explicit pointer exists).

    The problem is "pass by reference" never got any sort of definitely
    established meaning and people use it to mean what they think it
    means. I don't see any point in trying to decide whether the two
    terms mean exactly the same thing, because what people think "pass
    by value" means can vary from person to person.

    "Call by reference" would be N/A for C, since this in not how C
    function calls work.

    C uses call by value exclusively.

    Whereas something like object instance semantics in Java, could be interpreted as an example of the latter (versus primitive arguments
    which are still by-value in Java).

    Java also uses call by value exclusively. What confuses some people
    is that there are two kinds of values: things like integers, where
    the values are represented directly; and objects, where objects are
    referred to by what is called pointer semantics: the "value" of an
    object variable is in effect a handle to the object memory, which is
    stored somewhere else. Both integers and object handles are passed
    by value. The difference is that with integers (and maybe some
    other primitive types) everything about the item is right there in
    the value, whereas with objects most of what makes up the state of
    the object is somewhere else, and the "value" is only a link to
    that. But in terms of what variables hold, and what expressions
    produce, Java has call-by-value semantics for all parameters and
    all arguments.

    (Disclaimer: I am not a Java expert. I believe what I said about
    Java is right but it may be either incomplete or a little bit off.
    For that matter it might be completely wrong. :) But certainly
    there are languages that behave in the way described above.)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to bart on Sat Jul 13 18:44:36 2024
    bart <[email protected]> writes:

    On 12/07/2024 12:44, Janis Papanagnou wrote:

    On 11.07.2024 22:37, bart wrote:

    On 11/07/2024 21:29, Keith Thompson wrote:

    bart <[email protected]> writes:

    This my first comment on the subject:

    "Arrays are passed by reference:
    ...
    Although ..."

    And that statement was incorrect, even with the "Although".

    So arrays are passed by value? Gotcha.

    Neither is true. - Tertium datur!

    "Array passing" is in "C" realized using a pointer passing
    mechanism where the pointer is passed "by value".

    Neither an array is passed [by value] nor there's a "call
    by reference" mechanism in "C".

    So how are the elements of the caller's array accessed?

    That is irrelevant to the question because array elements
    are not arguments to the function.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Ben Bacarisse on Wed Jul 17 01:09:48 2024
    Ben Bacarisse <[email protected]> writes:

    Tim Rentsch <[email protected]> writes:

    Michael S <[email protected]> writes:

    On Fri, 12 Jul 2024 13:12:53 +0200
    Janis Papanagnou <[email protected]> wrote:

    But maybe he has looked up some things, since lately he's squirming
    by introducing terms like "_true_ pass-by-reference" [emphasis by me]
    obviously trying to bend the semantics of the established technical
    "pass-by-reference" term to fit his argument. (Introducing new terms
    for existing mechanisms or bending semantics of existing terms with
    well established meaning is certainly not helpful in any way.)

    But, yes, that person is a phenomenon.

    I don't share your optimistic belief that the term "pass by reference"
    is really established. Very few terms in computer science (science?
    really?) are established firmly. Except, may be, in more theoretical
    branches of it.

    The terms

    call by name
    call by value
    call by reference
    call by value-result

    are all well-defined and firmly established, going back more than
    60 years. I learned all of these in standard early course in
    computer science sometime in the early 1970s. Of course I can't
    be sure about the source after all these years, but I expect
    they were defined in the textbook we were using in the class.

    Much later, probably under the influence of people learning
    by reading blogs rather than books, some of these terms were
    expressed as, eg, "pass by value" or "pass by reference".

    I think it's reasonable to assume that this change of term was partly motivated simply by the meaning of the words. Call by value (to pick
    one) is an odd term to use about a parameter and/or argument. The
    function or procedure is called, but the arguments are passed and subsequently accessed. Nowadays, sentences like "Specifications of parameters called by value must be supplied" just feel a bit strange, at least to me.

    I partly agree with you, but only partly.

    It seems likely that terms such as "pass by value" were introduced
    by someone, or someones, who thought those terms were more
    descriptive than the original terms such as "call by value".

    But I think it's wrong to conclude that "pass by value" is a better
    choice than call by value, etc, because it focuses on what is going
    on in the implementation rather than what is meant in the abstract
    semantics.

    Under call by reference, for example, there are implications not
    just for what information is conveyed but also how the variable is
    used within the body of the function in question. Looking at an
    assignment 'x := 3;' has a very different meaning if the variable x
    is a call-by-value parameter than if x is a call-by-name parameter
    (and different again if x is a call-by-reference parameter). And I
    think it's worth remembering that when the term "call by name" was
    introduced it wasn't really understood how to implement it.

    Also consider the evaluation mode call-by-value-result. Here there
    is a difference in what information is conveyed to the function, and
    also a difference in the meaning of a use of the variable within the
    function body, but also a difference in what happens when a function
    return is done. It's more important to understand the semantics of
    the parameter mode than it is to know the details of how the
    semantics are accomplished.

    Of course I agree that the example sentence "Specifications of
    parameters called by value must be supplied" sounds a bit off, but
    that's because it is misusing language, treating the word "call" as
    a verb rather than as an inseparable part of a compound adjective.
    Written more grammatically as "Specifications of call-by-value
    parameters must be supplied", the sentence sounds just fine. Or
    maybe better, "Any call-by-value parameters must be identified as
    such." But either way, choosing a compound adjective form of
    expression appropriately ties the evaluation mode to the function
    parameter, and not to unimportant details of an implementation.

    Had I been CS King, I would have promulgated the terms "accessed by
    value", "accessed by name" and so on since it's the access method that
    really what matters to my mind.

    I have two objections. One is that it's too local. Two is that
    it's too specific. (Also I don't like that there is an implied verb
    phrasing rather than a compound adjective phrasing.) Too local:
    there is a tacit assumption that all accesses are the same, whereas
    they may not be. Example: a lazy parameter that is evaluated on
    first use, then simply copies the previously computed value on
    subsequent uses. Moreover the half-lazy argument might already have
    been evaluated before the function is called. Too specific: access
    suggests an imperative environment, but there are other kinds of
    environments. In logic programming a typical parameter mode is call
    by unification; if instead it were referred to as "accessed by
    unification" that would sound odd. Ideally we would have a phrasing
    that makes sense for all different sorts of parameter evaluation
    methods, and not just a few that have been used historically in
    imperative languages.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to bart on Wed Jul 17 16:42:49 2024
    bart <[email protected]> writes:

    [...]

    Because as AFAIK this whole subthread seems to about people trying
    to catch me out on some pedantry.

    All it needed was for someone to agree that yes, arrays are
    /effectively/ passed by reference, [...]

    To recap, the discussion concerns function parameters declared
    using an array-style declarator.

    I'm perfectly willing to agree that you think of such parameters
    as being effectively call-by-reference arrays.

    My objection is to your insistence that other people must agree
    with that view. You can think of it any way you like, but that
    doesn't make it true, nor does it imply that other people have to
    hold the same point of view. So all you have to do is stop
    insisting that your point of view is the only reasonable one.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to bart on Mon Aug 12 15:36:54 2024
    bart <[email protected]> writes:

    On 06/07/2024 19:28, James Kuyper wrote:
    [...]

    It is that conversion [from array designator to a pointer to the
    first element of the array] which creates the illusion of array
    indexing, but since it's been converted to a pointer, it is
    actually pointer indexing.

    Isn't that how all languages work 'under the hood'?

    First, no, it isn't.

    Second, it's the wrong way to think about it. People who always
    think about what's going on 'under the hood' are forever doomed
    to program in a glorified assembly language. The big problem of
    programming in assembly language is it doesn't scale. Any program
    above a certain size must develop and build on abstractions for it
    to be developed effectively. Constantly thinking is assembly
    language greatly interferes with that.

    The net affect from the user's point of view is that you have an
    array object, and use 'indexing' to access its individual
    elements.

    That's wrong. For some users, sure. But not all, and not "the
    user". Beginners may think of it that way, but more experienced
    C developers do not, at least not always. This is why it's
    important that descriptions of how C works not disguise these
    details, because it will have the effect of confusing beginning
    programmers and likely slowing down their understanding, which
    ultimately is a disservice to the C programming community.

    You should feel free to think any way you like. But it's wrong
    to insist that everyone else thinks the way you do. They don't.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Bart on Thu Aug 15 01:43:38 2024
    Bart <[email protected]> writes:

    [on comparing array arguments in C with call-by-reference]

    [...] the differences [between C rules and true call-by-reference]
    can be summarised here; [...]

    Call Array access in callee

    C call-by-value F(A) A[i]

    true call-by-reference H(A) A[i]

    What the user has to write is what's important, and here it is clear
    that they write the same thing [in the two cases shown].


    The comparison above is misleading because it is incomplete.
    Let's compare the two modes more fully:


    C call-by-value call-by-reference
    =============== =================
    at call:

    (array argument) F(A) H(A)

    (pointer argument) F(p) (disallowed)

    (null argument) F(0) (disallowed)


    inside function:

    (access) A[i] A[i]

    (update) A[i] = ... A[i] = ...

    sizeof A (pointer size) (array size)

    A++ (changes A variable) (disallowed)

    A = (new value) (changes A variable) (disallowed)


    The more complete comparion illustrate why C semantics should not
    be thought of as call-by-reference.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Bart on Thu Aug 15 15:33:38 2024
    Bart <[email protected]> writes:

    On 15/08/2024 09:43, Tim Rentsch wrote:
    Bart <[email protected]> writes:

    [on comparing array arguments in C with call-by-reference]

    [...] the differences [between C rules and true call-by-reference]
    can be summarised here; [...]

    Call Array access in callee

    C call-by-value F(A) A[i]

    true call-by-reference H(A) A[i]

    What the user has to write is what's important, and here it is clear
    that they write the same thing [in the two cases shown].

    The comparison above is misleading because it is incomplete.
    Let's compare the two modes more fully:


    C call-by-value call-by-reference
    =============== =================
    at call:

    (array argument) F(A) H(A)

    (pointer argument) F(p) (disallowed)

    My posts were about passing *arrays* and the fact that C's pass-by-value
    was remarkably similar to pass-by-reference.

    Which is why, presumably, you didn't show the differences. Your
    post was all polemic not part of a collegiate discussion of the
    similarities and differences.

    However your entry for pointers is not correct:

    No, the entry is correct. H(p) would be (is?) disallowed when H's
    parameter is a reference to an array.

    you can pass pointers by
    reference (in C, it means passing a T** type instead of T* to emulate
    that).

    H's parameter is /not/ what you claim "emulates" a reference to a
    pointer -- it's a hypothetical reference to an array.

    Maybe you missed what Tim was doing. He is showing a fuller comparison
    for one F and one H. A different function could, in this hypothetical
    C with call-by-reference, be passed a pointer, but then it could not be
    passed an array.

    (null argument) F(0) (disallowed)

    Pass-by-reference necessarily requires an lvalue at the call-site

    Yes, that is one of the differences you failed to illustrate.

    since it effectively applies & to the argument.

    No. Passing a reference is /not/ like using & to pass a pointer.

    inside function:

    (access) A[i] A[i]

    (update) A[i] = ... A[i] = ...

    sizeof A (pointer size) (array size)

    That's one of the small differences. But you only get the array size in a language where the array type includes its length. Otherwise, you only get
    it if it's part of the parameter type.

    A++ (changes A variable) (disallowed)

    (In my language ++A is allowed. I'm not sure why, it's likely a bug.)

    In the hypothetical C with call-by-reference, it's another difference
    you chose not to show.

    A = (new value) (changes A variable) (disallowed)

    This is allowed too in my language, if the array has a fixed size. It reassigns the whole array.

    Your language (for which we have no reference material) is beside the
    point. This is another difference you failed to point out in your
    comparison.

    In C you can't do A = B for other reasons, since arrays aren't manipulated
    by value.

    One way or another, this is a difference you failed to illustrate. If
    this hypothetical C is very close to C then the difference is as Tim
    posted. But in a another quasi-C that permits array assignment there
    would still be a difference: the pointer assignment would be disallowed
    but the array assignment (by reference) would be permitted.

    ...
    The more complete comparion illustrate why C semantics should not
    be thought of as call-by-reference.

    It was made clear more than once that it wasn't exact
    call-by-reference.

    So why did you give only one side of the comparison? You have nothing
    to lose by being open about the differences if your objective is an
    open, collegiate discussion of C. By presenting a polemic, you make the
    whole exchange more antagonistic than it needs to be.

    It was also made clear that there were enough similarities that adding real call-by-reference arrays to C would buy you very little.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Bart on Thu Aug 15 14:36:00 2024
    Bart <[email protected]> writes:

    On 15/08/2024 09:43, Tim Rentsch wrote:

    Bart <[email protected]> writes:

    [on comparing array arguments in C with call-by-reference]

    [...] the differences [between C rules and true call-by-reference]
    can be summarised here; [...]

    Call Array access in callee

    C call-by-value F(A) A[i]

    true call-by-reference H(A) A[i]

    What the user has to write is what's important, and here it is clear
    that they write the same thing [in the two cases shown].

    The comparison above is misleading because it is incomplete.
    Let's compare the two modes more fully:


    C call-by-value call-by-reference
    =============== =================
    at call:

    (array argument) F(A) H(A)

    (pointer argument) F(p) (disallowed)

    My posts were about passing *arrays* and the fact that C's
    pass-by-value was remarkably similar to pass-by-reference.

    I see. So your point is, if we ignore all the ways that the two
    modes are different then they are exactly the same.

    Brilliant deduction, Dr. Watson.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Bart on Fri Aug 16 01:08:15 2024
    Bart <[email protected]> writes:

    On 15/08/2024 15:33, Ben Bacarisse wrote:
    Bart <[email protected]> writes:

    On 15/08/2024 09:43, Tim Rentsch wrote:
    Bart <[email protected]> writes:

    C call-by-value call-by-reference
    =============== =================
    at call:

    (array argument) F(A) H(A)

    (pointer argument) F(p) (disallowed)

    My posts were about passing *arrays* and the fact that C's pass-by-value >>> was remarkably similar to pass-by-reference.
    Which is why, presumably, you didn't show the differences. Your
    post was all polemic not part of a collegiate discussion of the
    similarities and differences.

    However your entry for pointers is not correct:
    No, the entry is correct. H(p) would be (is?) disallowed when H's
    parameter is a reference to an array.

    Sorry, what language does the right-hand column pertain to? /Any/ language that has call-by-reference, or Tim's hypthetical language?

    Tim said that case was "disallowed". You call that an error on his
    part. What language did you have in mind that permits such a gross
    warping of types? I would describe /any/ language that allowed it as
    having a design error.

    Or any that could be used to prove him right?

    In general there is no reason, in a language with true call-by-reference,
    why any parameter type T (which has the form U*, a pointer to anything), cannot be passed by reference. It doesn't matter whether U is an array type or not.

    I can't unravel this. Take, as a concrete example, C++. You can't pass
    a pointer to function that takes an array passed by reference. You can,
    of course, pass a pointer by reference, but that is neither here nor
    there.

    you can pass pointers by
    reference (in C, it means passing a T** type instead of T* to emulate
    that).
    H's parameter is /not/ what you claim "emulates" a reference to a
    pointer -- it's a hypothetical reference to an array.

    In my original post it was G() that was C emulating pass-by-reference.

    It wasn't stated that p was an array pointer, only pointer, but it doesn't make any difference in H which we can assume is not C, and therefore
    doesn't have C's hangups about arrays and pointers.

    The whole point if Tim's post was to point out how call-by-reference
    would be significantly different to what C has right now. That requires imaging "C with call-by-reference".

    Maybe you missed what Tim was doing. He is showing a fuller comparison
    for one F and one H. A different function could, in this hypothetical
    C with call-by-reference, be passed a pointer, but then it could not be
    passed an array.

    Neither of you have explained this well. Are you both projecting C's craziness with arrays and pointers onto this hypothetical language?

    If so, then if this fantasy language has true pass-by-reference, then let
    it have real value-arrays too!

    It might, but it would be closer to C if it did not. And C++ is not a
    fantasy language but it has reference parameters that behave as
    illustrated.

    (null argument) F(0) (disallowed)

    Pass-by-reference necessarily requires an lvalue at the call-site
    Yes, that is one of the differences you failed to illustrate.

    I illustrated some conveniences which C's array-passing idiom which match those of true pass-by-reference.


    since it effectively applies & to the argument.
    No. Passing a reference is /not/ like using & to pass a pointer.

    Funny, in my language that is EXACTLY how it is implemented. Instead of my writing:

    F(&x) and in F having to write: *x

    you instead write:

    F(x) and in F you write: x

    Your whole point (which to some extent I accept) is that what the user
    writes is what matters. Passing a reference is /not/ like using & to
    pass a pointer.

    So it will insert & and * operators for you. Why, how would /you/ do it? (I'm talking about this level of language; higher level ones might do everthing with references anyway, and might not have & or * operators.)



    inside function:

    (access) A[i] A[i]

    (update) A[i] = ... A[i] = ...

    sizeof A (pointer size) (array size)

    That's one of the small differences. But you only get the array size in a >>> language where the array type includes its length. Otherwise, you only get >>> it if it's part of the parameter type.

    A++ (changes A variable) (disallowed)

    (In my language ++A is allowed. I'm not sure why, it's likely a bug.)
    In the hypothetical C with call-by-reference, it's another difference
    you chose not to show.

    Yes, as I said, I concentrate on the ones which allowed you to write F(A), and A[i] inside F, just like pass-by-reference, rather than F(&A), and (*A[i]) inside F. Did I claim it was full by pass-by-reference?

    A = (new value) (changes A variable) (disallowed)

    This is allowed too in my language, if the array has a fixed size. It
    reassigns the whole array.
    Your language (for which we have no reference material) is beside the
    point. This is another difference you failed to point out in your
    comparison

    It doesn't matter; any call-by-reference worth its salt will allow you to change variables in the caller. That's half the point it!

    C with call-by-reference should treat array references just like C
    arrays. A reference should behave like the thing it references.

    C doesn't have A=B syntax for arrays, but it can do memcpy for the same effect.



    In C you can't do A = B for other reasons, since arrays aren't manipulated >>> by value.
    One way or another, this is a difference you failed to illustrate. If
    this hypothetical C is very close to C then the difference is as Tim
    posted. But in a another quasi-C that permits array assignment there
    would still be a difference: the pointer assignment would be disallowed
    but the array assignment (by reference) would be permitted.

    What pointer assignment? You're mixing actual C with fantasy C. You can't
    do that: if you add array assignment to C, then it changes everything.

    Indeed, but you brought up assignable arrays in your language so I
    wanted to show how, even in such an extended C, it remains a difference
    you were glossing over.

    So why did you give only one side of the comparison? You have nothing
    to lose by being open about the differences if your objective is an
    open, collegiate discussion of C. By presenting a polemic, you make the
    whole exchange more antagonistic than it needs to be.

    These were my original comments on the subject made to DB:

    DB:
    . In C, there is no "pass by reference" or "return by reference". It is
    all done by value.

    BC:

    Arrays are passed by reference:

    void F(int a[20]) {}

    int main(void) {
    int x[20];
    F(x);
    }

    Although the type of 'a' inside 'F' will be int* rather than int(*)[20].

    It was in reply to DB which appear to imply that arrays were passed by
    value. Obviously they're not passed by value, so what then? (Please, don't rerun the thread! This is where everyone jumped in.)

    I'm not sure why you bring this up. I think you have subsequently
    acknowledged that arrays are not passed by reference in C (nothing is)
    so if you don't want to rerun the thread, what does this old exchange
    add? And of your question "so what then?" is not rhetorical, what was
    wrong with the answers you got before (including from me)?

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to David Brown on Fri Aug 16 11:00:54 2024
    David Brown <[email protected]> writes:

    On 16/08/2024 02:08, Ben Bacarisse wrote:
    Bart <[email protected]> writes:

    In general there is no reason, in a language with true call-by-reference, >>> why any parameter type T (which has the form U*, a pointer to anything), >>> cannot be passed by reference. It doesn't matter whether U is an array type >>> or not.
    I can't unravel this. Take, as a concrete example, C++. You can't pass
    a pointer to function that takes an array passed by reference. You can,
    of course, pass a pointer by reference, but that is neither here nor
    there.

    In C++, you can't pass arrays as parameters at all - the language inherited C's handling of arrays. You can, of course, pass objects of std::array<> type by value or by reference, just like any other class types.

    The best way to think about C++ (in my very non-expert opinion) is to
    consider references as values that are passed by, err..., value. But
    you seem prepared to accept that some things can be "passed by reference"
    in C++. So if this:

    #include <iostream>

    void g(int &i) { std::cout << i << "\n"; }

    int main(void)
    {
    int I{0};
    g(I);
    }

    shows an int object, I, being passed to g, why does this

    #include <iostream>

    void f(int (&ar)[10]) { std::cout << sizeof ar << "\n"; }

    int main(void)
    {
    int A[10];
    f(A);
    }

    not show an array, A, being passed to f?

    As I said, I don't think it's wise to look at it this way, but I am just borrowing your use of terms to try to tease out what you are getting at.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Michael S on Fri Aug 16 11:17:43 2024
    Michael S <[email protected]> writes:

    On Fri, 16 Aug 2024 01:08:15 +0100
    Ben Bacarisse <[email protected]> wrote:

    Bart <[email protected]> writes:

    On 15/08/2024 15:33, Ben Bacarisse wrote:
    Bart <[email protected]> writes:

    On 15/08/2024 09:43, Tim Rentsch wrote:
    Bart <[email protected]> writes:

    C call-by-value
    call-by-reference =============== =================
    at call:

    (array argument) F(A) H(A)

    (pointer argument) F(p) (disallowed)

    My posts were about passing *arrays* and the fact that C's
    pass-by-value was remarkably similar to pass-by-reference.
    Which is why, presumably, you didn't show the differences. Your
    post was all polemic not part of a collegiate discussion of the
    similarities and differences.

    However your entry for pointers is not correct:
    No, the entry is correct. H(p) would be (is?) disallowed when H's
    parameter is a reference to an array.

    Sorry, what language does the right-hand column pertain to? /Any/
    language that has call-by-reference, or Tim's hypthetical language?


    Tim said that case was "disallowed". You call that an error on his
    part. What language did you have in mind that permits such a gross
    warping of types? I would describe /any/ language that allowed it as
    having a design error.

    Or any that could be used to prove him right?

    In general there is no reason, in a language with true
    call-by-reference, why any parameter type T (which has the form U*,
    a pointer to anything), cannot be passed by reference. It doesn't
    matter whether U is an array type or not.

    I can't unravel this. Take, as a concrete example, C++. You can't
    pass a pointer to function that takes an array passed by reference.
    You can, of course, pass a pointer by reference, but that is neither
    here nor there.

    IMHO, C++ is a particularly bad example.

    It's a bad example of a programming language, but that is exactly why
    it's a good example of something very like C but with a reference
    mechanism.

    Yes, C++ has call-by-reference misfeature. But arrays in C++ are
    2nd class citizen, same as in C. They can't be assigned and can't be
    passed to callee, neither by value nor by reference.

    See my reply to David. If it has call-by-reference at all (and I agree
    that passing reference values is a better way to think about this) then
    why do say that arrays can't be passed by reference? I'd say either
    that nothing can (it's all just passing reference values) or arrays
    /can/ indeed be "passed by reference" just like, say, int objects.

    Also, I suspect that if you ask Ken Thompson, he will tell you that C++
    does not really have 'call by reference'. Instead, it has references as
    1st class object, so, naturally, values of references can be used
    during 'call by value'.

    I used to teach C++, and the only way to avoid a class full of puzzled
    students is to avoid taking about "by reference" and "by value": all
    argument passing is like local variable initialisation. In essence,
    everything is still passed by value.

    So I agree with the general idea, but I would not say that references
    are first class values, and reference objects are certainly not first
    class objects (for example, you can't pass one "by reference"!).

    I have enough of respect to KT to consider that his POV is not a
    nonsense.


    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Bart on Sat Aug 17 07:41:01 2024
    Bart <[email protected]> writes:

    On 16/08/2024 01:08, Ben Bacarisse wrote:

    Bart <[email protected]> writes:

    On 15/08/2024 15:33, Ben Bacarisse wrote:

    Bart <[email protected]> writes:

    On 15/08/2024 09:43, Tim Rentsch wrote:

    Bart <[email protected]> writes:

    C call-by-value call-by-reference >>>>>> =============== ================= >>>>>> at call:

    (array argument) F(A) H(A)

    (pointer argument) F(p) (disallowed)

    My posts were about passing *arrays* and the fact that C's pass-by-value >>>>> was remarkably similar to pass-by-reference.

    Which is why, presumably, you didn't show the differences. Your
    post was all polemic not part of a collegiate discussion of the
    similarities and differences.

    However your entry for pointers is not correct:

    No, the entry is correct. H(p) would be (is?) disallowed when H's
    parameter is a reference to an array.

    Sorry, what language does the right-hand column pertain to? /Any/ language >>> that has call-by-reference, or Tim's hypthetical language?

    Tim said that case was "disallowed". You call that an error on his
    part. What language did you have in mind that permits such a gross
    warping of types? I would describe /any/ language that allowed it as
    having a design error.

    You or he would have to go into more detail, such as an actual
    example, to demonstrate whatever it is that you think is wrong about
    passing a pointer argument by-reference.

    I assume here that the language in the right column is not C.

    Or any that could be used to prove him right?

    In general there is no reason, in a language with true call-by-reference, >>> why any parameter type T (which has the form U*, a pointer to anything), >>> cannot be passed by reference. It doesn't matter whether U is an array
    type or not.

    I can't unravel this. Take, as a concrete example, C++. You can't pass
    a pointer to function that takes an array passed by reference. You can,
    of course, pass a pointer by reference, but that is neither here nor
    there.

    OK. So why do you agree with this:

    C call-by-value call-by-reference >>>>>> =============== ================= >>>>>> (pointer argument) F(p) (disallowed)

    What is 'pointer argument' here?

    Try thinking harder. Everyone else understood.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Bart on Sat Aug 17 18:22:25 2024
    Bart <[email protected]> writes:

    On 17/08/2024 15:41, Tim Rentsch wrote:

    Bart <[email protected]> writes:

    OK. So why do you agree with this:

    C call-by-value call-by-reference
    =============== =================
    (pointer argument) F(p) (disallowed)

    What is 'pointer argument' here?

    Try thinking harder. Everyone else understood.

    I could equally say that everyone understood what was meant by
    implicit cast'.

    It would be a useful exercise for you to compare and contrast
    those two statements, listing their similarities and differences.

    But here you really have to explain what you mean by a pointer
    argument, since there is no reason why such a type can't be passed
    by reference.

    Lacking such an explanation, I'd have to say still that
    'disallowed' is generally incorrect.

    What is incorrect is your understanding of what was meant.

    Let me elaborate on that. Some of the people who post here are
    interested in listening, and usually make an effort to understand in
    cases where a first reading leaves them confused. Others, not so
    much. More generally, there is a spectrum of interest/effort, with
    people who make a large effort at one end, and people who make
    little or not effort at the other end.

    Somewhat paradoxically, it is the people who are most intent on
    listening who are the ones most worth listening to. Conversely,
    people who don't make much of an effort to listen and understand
    are usually not worth listening to.

    You are definitely closer to the no effort end of the spectrum than
    you are to the other end. You are much more focused on what you
    want to say than you are in what the other person is saying.
    That's a lot of the reason people dismiss your comments. It also
    reduces the chance that you will get useful responses. Your first
    response up above is a case in point. It's typical of you. Given
    this entirely predictable reaction, I have very little incentive to
    try to explain anything, because I don't think you're going to hear
    the explanation.

    I don't expect any of the above to change the way you act, but just
    in case, here is a suggestion. When you read something that seems
    not to make sense, ask yourself a question: What might have been
    meant here so that this statement is right? If you don't look for
    alternative interpretations you won't ever find any. On the flip
    side, the more often you look for alternative interpretations and
    the more effort you put into doing so, the more likely you are to
    have meaningful interactions with other people in the group, unlike
    the meaningless interactions you usually have.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Bart on Mon Aug 19 01:01:14 2024
    Bart <[email protected]> writes:

    On 16/08/2024 01:08, Ben Bacarisse wrote:
    Bart <[email protected]> writes:

    On 15/08/2024 15:33, Ben Bacarisse wrote:
    Bart <[email protected]> writes:

    On 15/08/2024 09:43, Tim Rentsch wrote:
    Bart <[email protected]> writes:

    C call-by-value call-by-reference >>>>>> =============== ================= >>>>>> at call:

    (array argument) F(A) H(A)

    (pointer argument) F(p) (disallowed)

    My posts were about passing *arrays* and the fact that C's pass-by-value >>>>> was remarkably similar to pass-by-reference.
    Which is why, presumably, you didn't show the differences. Your
    post was all polemic not part of a collegiate discussion of the
    similarities and differences.

    However your entry for pointers is not correct:
    No, the entry is correct. H(p) would be (is?) disallowed when H's
    parameter is a reference to an array.

    Sorry, what language does the right-hand column pertain to? /Any/ language >>> that has call-by-reference, or Tim's hypthetical language?
    Tim said that case was "disallowed". You call that an error on his
    part. What language did you have in mind that permits such a gross
    warping of types? I would describe /any/ language that allowed it as
    having a design error.

    You or he would have to go into more detail, such as an actual example, to demonstrate whatever it is that you think is wrong about passing a pointer argument by-reference.

    No one has said any such thing, so I can't see how any more detail could
    help. I suspect you've lost track of the point being made.

    I assume here that the language in the right column is not C.

    Obviously.

    Or any that could be used to prove him right?

    In general there is no reason, in a language with true call-by-reference, >>> why any parameter type T (which has the form U*, a pointer to anything), >>> cannot be passed by reference. It doesn't matter whether U is an array type >>> or not.
    I can't unravel this. Take, as a concrete example, C++. You can't pass
    a pointer to function that takes an array passed by reference. You can,
    of course, pass a pointer by reference, but that is neither here nor
    there.

    OK. So why do you agree with this:

    C call-by-value call-by-reference >>>>>> =============== ================= >>>>>> (pointer argument) F(p) (disallowed)

    What is 'pointer argument' here?

    I can't see what is confusing you about this. I agree with the above
    for exactly the reasons I wrote. It would be wrong (and is wrong in
    C++) to pass a pointer where an array reference is expected.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to David Brown on Mon Aug 19 00:54:03 2024
    David Brown <[email protected]> writes:

    On 16/08/2024 12:00, Ben Bacarisse wrote:
    David Brown <[email protected]> writes:

    On 16/08/2024 02:08, Ben Bacarisse wrote:
    Bart <[email protected]> writes:

    In general there is no reason, in a language with true call-by-reference, >>>>> why any parameter type T (which has the form U*, a pointer to anything), >>>>> cannot be passed by reference. It doesn't matter whether U is an array type
    or not.
    I can't unravel this. Take, as a concrete example, C++. You can't pass >>>> a pointer to function that takes an array passed by reference. You can, >>>> of course, pass a pointer by reference, but that is neither here nor
    there.

    In C++, you can't pass arrays as parameters at all - the language inherited >>> C's handling of arrays. You can, of course, pass objects of std::array<> >>> type by value or by reference, just like any other class types.
    The best way to think about C++ (in my very non-expert opinion) is to
    consider references as values that are passed by, err..., value. But
    you seem prepared to accept that some things can be "passed by reference"
    in C++.

    That seems a subtle distinction - I'll have to think about it a little. I like your description of arguments being like local variable initialisation
    - it makes sense equally well regardless of whether the parameter is "int", "int*", or "int&". (It's probably best not to mention the other one in
    this group...)

    So if this:
    #include <iostream>
    void g(int &i) { std::cout << i << "\n"; }
    int main(void)
    {
    int I{0};
    g(I);
    }
    shows an int object, I, being passed to g, why does this
    #include <iostream>
    void f(int (&ar)[10]) { std::cout << sizeof ar << "\n"; }
    int main(void)
    {
    int A[10];
    f(A);
    }
    not show an array, A, being passed to f?

    That's backwards compatibility with C array handling at play.

    I'm not sure how this answers my question. Maybe you weren't answering
    it and were just making a remark...

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Ben Bacarisse on Sun Aug 18 18:03:41 2024
    Ben Bacarisse <[email protected]> writes:

    David Brown <[email protected]> writes:

    On 16/08/2024 12:00, Ben Bacarisse wrote:

    David Brown <[email protected]> writes:

    On 16/08/2024 02:08, Ben Bacarisse wrote:

    Bart <[email protected]> writes:

    In general there is no reason, in a language with true
    call-by-reference, why any parameter type T (which has the form
    U*, a pointer to anything), cannot be passed by reference. It
    doesn't matter whether U is an array type or not.

    I can't unravel this. Take, as a concrete example, C++. You
    can't pass a pointer to function that takes an array passed by
    reference. You can, of course, pass a pointer by reference, but
    that is neither here nor there.

    In C++, you can't pass arrays as parameters at all - the language
    inherited C's handling of arrays. You can, of course, pass
    objects of std::array<> type by value or by reference, just like
    any other class types.

    The best way to think about C++ (in my very non-expert opinion) is
    to consider references as values that are passed by, err...,
    value. But you seem prepared to accept that some things can be
    "passed by reference" in C++.

    That seems a subtle distinction - I'll have to think about it a
    little. I like your description of arguments being like local
    variable initialisation - it makes sense equally well regardless of
    whether the parameter is "int", "int*", or "int&". (It's probably
    best not to mention the other one in this group...)

    So if this:
    #include <iostream>
    void g(int &i) { std::cout << i << "\n"; }
    int main(void)
    {
    int I{0};
    g(I);
    }
    shows an int object, I, being passed to g, why does this
    #include <iostream>
    void f(int (&ar)[10]) { std::cout << sizeof ar << "\n"; }
    int main(void)
    {
    int A[10];
    f(A);
    }
    not show an array, A, being passed to f?

    That's backwards compatibility with C array handling at play.

    I'm not sure how this answers my question. Maybe you weren't
    answering it and were just making a remark...

    My guess is he didn't understand the question. The code shown
    has nothing to do with backwards compatibility with C array
    handling.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Bart on Mon Aug 19 02:30:15 2024
    Bart <[email protected]> writes:

    On 19/08/2024 01:01, Ben Bacarisse wrote:
    Bart <[email protected]> writes:


    You or he would have to go into more detail, such as an actual example, to >>> demonstrate whatever it is that you think is wrong about passing a pointer >>> argument by-reference.
    No one has said any such thing, so I can't see how any more detail could
    help. I suspect you've lost track of the point being made.

    Probably, and perhaps not just me! But I'd still quite like to know exactly what it is that is marked as 'disallowed'.

    I don't know how to explain it any better. If you really want to know,
    maybe you could say what /you/ think was incorrectly marked as
    disallowed so I can see how you were interpreting the table. You
    obviously had something in mind or you could not have said Tim was
    wrong.

    I can't unravel this. Take, as a concrete example, C++. You can't pass >>>> a pointer to function that takes an array passed by reference. You can, >>>> of course, pass a pointer by reference, but that is neither here nor
    there.

    OK. So why do you agree with this:

    C call-by-value call-by-reference >>>>>>>> =============== ================= >>>>>>>> (pointer argument) F(p) (disallowed)

    What is 'pointer argument' here?
    I can't see what is confusing you about this. I agree with the above
    for exactly the reasons I wrote.

    Do you mean: 'You can't pass a pointer to a function that takes an array passed by reference'?

    Yes. As you say below, there would be a good reason not to allow that
    in a C-like language with call-by reference added.

    It would be wrong (and is wrong in
    C++) to pass a pointer where an array reference is expected.

    Well, putting aside pass-by-reference, that would be wrong in C too, if you interpret 'array reference' to be a type like T(*)[], and a 'pointer' a
    type like T*.

    I'm not sure what this true remark adds. Everything that is in
    discussion relates to call-by-reference where that clearly does not just
    mean "passing a pointer".

    With pass-by-reference added to C, there would be stronger type checking,
    so if something is disallowed, it would be for a good reason, not just because Tim said so.

    Or maybe, just maybe, Tim said it for good reason.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to David Brown on Mon Aug 19 14:14:35 2024
    David Brown <[email protected]> writes:

    On 19/08/2024 03:03, Tim Rentsch wrote:
    Ben Bacarisse <[email protected]> writes:

    David Brown <[email protected]> writes:

    On 16/08/2024 12:00, Ben Bacarisse wrote:

    David Brown <[email protected]> writes:
    ...
    In C++, you can't pass arrays as parameters at all - the language
    inherited C's handling of arrays. You can, of course, pass
    objects of std::array<> type by value or by reference, just like
    any other class types.

    The best way to think about C++ (in my very non-expert opinion) is
    to consider references as values that are passed by, err...,
    value. But you seem prepared to accept that some things can be
    "passed by reference" in C++.

    That seems a subtle distinction - I'll have to think about it a
    little. I like your description of arguments being like local
    variable initialisation - it makes sense equally well regardless of
    whether the parameter is "int", "int*", or "int&". (It's probably
    best not to mention the other one in this group...)

    So if this:
    #include <iostream>
    void g(int &i) { std::cout << i << "\n"; }
    int main(void)
    {
    int I{0};
    g(I);
    }
    shows an int object, I, being passed to g, why does this
    #include <iostream>
    void f(int (&ar)[10]) { std::cout << sizeof ar << "\n"; }
    int main(void)
    {
    int A[10];
    f(A);
    }
    not show an array, A, being passed to f?

    That's backwards compatibility with C array handling at play.

    I'm not sure how this answers my question. Maybe you weren't
    answering it and were just making a remark...
    My guess is he didn't understand the question. The code shown
    has nothing to do with backwards compatibility with C array
    handling.

    I had intended to make a brief remark and thought that was all that was needed to answer the question. But having thought about it a bit more (prompted by these last two posts), and tested the code (on the assumption that the gcc writers know the details better than I do), you are correct -
    I did misunderstand the question. I was wrong in how I thought array reference parameters worked in C++, and the way Ben worded the question re-enforced that misunderstanding.

    I'm sorry I wasn't more clear.

    I interpreted his question as saying that the code "f" does not show an
    array type being passed by reference, with the implication that the
    "sizeof" showed the size of a pointer, not the size of an array of 10 ints, and asking why C++ was defined that way. The answer, as I saw it, was that C++ made reference parameters to arrays work much like pointer parameters
    to arrays, and those work like in C for backwards compatibility.

    Ah. Then is was an answer to the question you thought I was asking.

    The trouble is, it never occurred to me you would not know that C++
    array references behave just like all other references -- as aliases to
    the objects they reference. So I was asking for some explanation of how
    you were using terms: "if this is 'passing an int', in what sense is this
    not 'passing an array'?".

    (I hope you don't think I'm being rude. C++ is a gruesomely huge
    language, littered with special cases and array reference must be almost
    never used, especially now. But I started with the first release of
    Cfront, so I learned all the primitive bits first. It's the new bits I
    can't fathom.)

    Of course, it turns out I was completely wrong about how array type
    reference parameters work in C++. It's not something I have had use for in my own C++ programming or something I have come across in other code that I can remember, and I had made incorrect assumptions about it. Now that I corrected that, it all makes a lot more sense.

    And so I presume Ben was actually asking why I /thought/ this was not
    passing an array type (thus with its full type information, including its size). Then answer there is now obvious - I thought that because I had jumped to incorrect conclusions about array reference parameters in
    C++.

    Well, it was little more like I thought you were maybe using the term
    "passing by reference" is some way that I'd missed. That's why I
    started with a brief explanation of how I used to explain it.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Bart on Tue Aug 20 00:33:38 2024
    Bart <[email protected]> writes:

    On 19/08/2024 02:30, Ben Bacarisse wrote:
    Bart <[email protected]> writes:

    On 19/08/2024 01:01, Ben Bacarisse wrote:
    Bart <[email protected]> writes:


    You or he would have to go into more detail, such as an actual example, to
    demonstrate whatever it is that you think is wrong about passing a pointer
    argument by-reference.
    No one has said any such thing, so I can't see how any more detail could >>>> help. I suspect you've lost track of the point being made.

    Probably, and perhaps not just me! But I'd still quite like to know exactly >>> what it is that is marked as 'disallowed'.
    I don't know how to explain it any better. If you really want to know,
    maybe you could say what /you/ think was incorrectly marked as
    disallowed so I can see how you were interpreting the table.

    I think I already said that several times!

    But I need to use concrete code, and there is no existing mainstream
    language with pass-by-reference that is simple enough to use for such examples. Except for mine and that is not acceptable here.

    So I'll use an extended C where a '&' in front of a parameter's base-type marks it as pass-by-reference.

    First an example written in standard C:

    #include <stdio.h>

    void F(int* p) {
    printf("%d\n", *p);
    ++p;
    }

    int main(void) {
    int A[] = {10,20,30};
    int* p = &A[0];

    F(p);
    printf("%d\n", *p);
    }

    This passes a normal pointer. The output is 10 10 from both printfs,
    because the ++p within F does not affect the original pointer in 'main'.

    Now the same program, but using pass-by-reference for 'p'; I won't show the whole thing, as the program looks exactly the same except for this line:

    void F(&int* p) {

    The output should now be 10 20 (as verified using my language; if
    interested, that is shown below, and below that is the standard C that
    might be generated by a transpiler from this fantasy C).

    So this is passing a pointer, by reference, and it is allowed!

    I can't imagine why you though this was what either Tim or I were
    talking about, but if that is genuinely what you thought he was saying
    was "disallowed" so be it. We could spend ages arguing about how you
    could possibly have thought this (especially as you wrote the original example), but nothing will be gained by doing that.

    Or maybe, just maybe, Tim said it for good reason.

    And yet, he continues to be cagey about it, and you're defending him. Just give me a freakin' example!

    WHAT EXACTLY IS IT THAT IS DISALLOWED?

    Good grief! You gave the example yourself! I'm not being cagey -- it
    never occurred to me that you could possibly be thinking about anything
    other the code you yourself posted and talked about!

    You: "I'm asking people to compare the first and third functions and
    their calls, and to see if there's any appreciable difference
    between them."

    Your first and third functions:

    int sum_byvalue(T* A, int n) {
    int i, sum=0;
    for (i=0; i<n; ++i) sum += A[i];
    return sum;
    }

    int sum_bytrueref(T (&A)[], int n) {
    int i, sum=0;
    for (i=0; i<n; ++i) sum += A[i];
    return sum;
    }

    and the caller uses:

    enum {N = 10};
    T A[N] = {10,20,30,40,50,60,70,80,90,100};
    ...
    total += sum_byvalue (A, N);
    ...
    total += sum_bytrueref(A, N)

    A post later and you used shorter names to show the similarities you
    wanted everyone to focus on -- the accesses in the functions. You used
    F for the function with a T* parameter and H for the function with a
    T(&)[10] parameter -- the true call-by-reference parameter that
    "sum_bytrueref" has a post earlier.

    Call Array access in callee
    (1) C call-by-value F(A) A[i]
    ...
    (3) true call-by-reference H(A) A[i]

    Tim just extended this by showing more call differences and more
    differences in access in the callee. The bit you so totally
    misunderstood was:

    C call-by-value call-by-reference
    =============== =================
    at call:
    (array argument) F(A) H(A)
    (pointer argument) F(p) (disallowed)
    (null argument) F(0) (disallowed)

    F (your name) can be called with an array argument (A) but not with a
    pointer argument (including a null pointer constant). Do you agree now
    that H(p) and H(0) are disallowed?

    How you thought that those last two rows of (this part of) the table
    could refer to a /different/ function (with a T*& parameter) -- a
    function that no one had posted up to that point -- is beyond me, but apparently you did. What's more you decided to put no effort in to try
    to work out what was being said. Instead you just said Tim was wrong
    and implied that I was defending the indefensible out of some sort of
    blind obedience.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Keith Thompson on Sun Sep 1 18:09:28 2024
    Keith Thompson <[email protected]> writes:

    Kaz Kylheku <[email protected]> writes:

    On 2024-07-12, bart <[email protected]> wrote:

    It's clearly not by value. It's apparently not by reference. You
    can't get away with saying they are not passed, as clearly
    functions *can* access array data via parameters.

    Actually, you probably can get away with saying that it is "passed
    by reference".

    The formal term that doesn't apply is "call by reference"; that's
    what C doesn't have.

    "call by reference" emphasizes that the function call mechanism
    provides the reference semantics for a formal parameter, not that
    some arbitrary means of passage of the data has reference
    semantics.

    [...]

    I know that "call by reference" is the usual formal term, but I
    personally prefer "pass by reference".

    The terms "call by reference" and "call by value" emphasize the
    call, implying that all arguments in a given call are passed with
    the same mechanism. In some languages that's true (C argument
    passing is purely by value, and Fortran, as I understand it, is
    purely by reference), but in others (C++, Pascal, Ada) you can
    select by-value or by-reference for each parameter. "Pass by (reference|value)" feels more precise.

    I haven't checked, but I suspect the terms "call by (reference|value)" predate languages that allowed the mechanism to be specified for each parameter.

    I suspect that your guess here is influenced more by what you would
    like to be true than what is likely to be true.

    What is likely to be true is that these terms entered the language
    at essentially the same time as the original Algol. Algol 60 has
    both call by name and call by value, referred to by those names in
    the Algol 60 Report, and selectable on a per-parameter basis.

    By contrast the precursor to Algol 60, the International Algebraic
    Language or IAL for short (and referred to after the fact as Algol
    58) did not use either term, and described the coupling between
    arguments and parameters only in somewhat vague English prose that
    left unclear exactly what the binding mechanism(s) were to be.
    (There was a description for functions and a separate description
    for procedures, not quite the same, and both not completely clear
    exactly what the mechanism was meant to be.)

    Thus it seems likely that the terms call by name, call by value,
    and perhaps other similar terms, first arose during the discussions
    of the Algol 60 working group in the late 1950s, and entered the
    general lexicon with or perhaps slightly before the publication of
    the Algol 60 Report, which describes and allows both call by name
    and call by value, selectable on a per-parameter base, and referred
    to by those names in the published Algol 60 Report.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Keith Thompson on Mon Sep 2 12:10:16 2024
    Keith Thompson <[email protected]> writes:

    Tim Rentsch <[email protected]> writes:
    Keith Thompson <[email protected]> writes:
    Kaz Kylheku <[email protected]> writes:
    On 2024-07-12, bart <[email protected]> wrote:
    It's clearly not by value. It's apparently not by reference. You
    can't get away with saying they are not passed, as clearly
    functions *can* access array data via parameters.

    Actually, you probably can get away with saying that it is "passed
    by reference".

    The formal term that doesn't apply is "call by reference"; that's
    what C doesn't have.

    "call by reference" emphasizes that the function call mechanism
    provides the reference semantics for a formal parameter, not that
    some arbitrary means of passage of the data has reference
    semantics.

    [...]

    I know that "call by reference" is the usual formal term, but I
    personally prefer "pass by reference".

    The terms "call by reference" and "call by value" emphasize the
    call, implying that all arguments in a given call are passed with
    the same mechanism. In some languages that's true (C argument
    passing is purely by value, and Fortran, as I understand it, is
    purely by reference), but in others (C++, Pascal, Ada) you can
    select by-value or by-reference for each parameter. "Pass by
    (reference|value)" feels more precise.

    I haven't checked, but I suspect the terms "call by (reference|value)"
    predate languages that allowed the mechanism to be specified for each
    parameter.

    I suspect that your guess here is influenced more by what you would
    like to be true than what is likely to be true.

    I was influenced by what I thought made the most sense.

    What is likely to be true is that these terms entered the language
    at essentially the same time as the original Algol. Algol 60 has
    both call by name and call by value, referred to by those names in
    the Algol 60 Report, and selectable on a per-parameter basis.

    By contrast the precursor to Algol 60, the International Algebraic
    Language or IAL for short (and referred to after the fact as Algol
    58) did not use either term, and described the coupling between
    arguments and parameters only in somewhat vague English prose that
    left unclear exactly what the binding mechanism(s) were to be.
    (There was a description for functions and a separate description
    for procedures, not quite the same, and both not completely clear
    exactly what the mechanism was meant to be.)

    Thus it seems likely that the terms call by name, call by value,
    and perhaps other similar terms, first arose during the discussions
    of the Algol 60 working group in the late 1950s, and entered the
    general lexicon with or perhaps slightly before the publication of
    the Algol 60 Report, which describes and allows both call by name
    and call by value, selectable on a per-parameter base, and referred
    to by those names in the published Algol 60 Report.

    Yes, that does seem likely.

    I'm mildly disappointed. Since arguments are *passed* and functions/procedures are *called*, surely it would have made more sense
    to use "pass by value" rather than "call by value", especially in a
    language where the mechanism can vary per parameter.

    All that is, I think, due to subsequent changes in (English) language
    use. In Algol 60, procedures were invoked and /parameters/ were called
    by value or name. Maybe the term was intended to reflect the idea that
    the code in the body "called for the value" of the parameter.

    The word "call" now refers, almost universally, to invoking a function
    or procedure. As a result, the idea of "calling a parameter" reads
    oddly, but at the time I'm sure it seemed perfectly reasonable.

    There is a nice historical irony here. Call by name would often have to
    be implemented as something akin to passing a "thunk" (a parameterless
    lambda) so the parameter would indeed be "called" (in the modern sense)
    when the value as "called for" (in the Algol sense) in the procedure.

    (Yes, this is my opinion.)

    If there's some reason why "call by value" actually made more sense than "pass by value", I'm not aware of it.

    Since the phrase "pass by value" is now in common use, I'll continue to
    use that term in preference to "call by value" (likewise "by
    reference").

    I use those terms too. It would be confusing these days to talk about
    calling a parameter, and the phrase "call by value" suggests (as it
    never did at the time) something so do with the function calling
    mechanism in general. This is compounded by the fact that modern
    programming languages has almost universally settled on calling all
    parameters by value (to the use the old phrase) so, usually, the terms
    can, in fact, be used to talk about the function calling mechanism.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Ben Bacarisse on Sun Sep 15 23:56:07 2024
    Ben Bacarisse <[email protected]> writes:

    Keith Thompson <[email protected]> writes:

    Tim Rentsch <[email protected]> writes:

    Keith Thompson <[email protected]> writes:

    Kaz Kylheku <[email protected]> writes:

    On 2024-07-12, bart <[email protected]> wrote:

    It's clearly not by value. It's apparently not by reference. You >>>>>> can't get away with saying they are not passed, as clearly
    functions *can* access array data via parameters.

    Actually, you probably can get away with saying that it is "passed
    by reference".

    The formal term that doesn't apply is "call by reference"; that's
    what C doesn't have.

    "call by reference" emphasizes that the function call mechanism
    provides the reference semantics for a formal parameter, not that
    some arbitrary means of passage of the data has reference
    semantics.

    [...]

    I know that "call by reference" is the usual formal term, but I
    personally prefer "pass by reference".

    The terms "call by reference" and "call by value" emphasize the
    call, implying that all arguments in a given call are passed with
    the same mechanism. In some languages that's true (C argument
    passing is purely by value, and Fortran, as I understand it, is
    purely by reference), but in others (C++, Pascal, Ada) you can
    select by-value or by-reference for each parameter. "Pass by
    (reference|value)" feels more precise.

    I haven't checked, but I suspect the terms "call by (reference|value)" >>>> predate languages that allowed the mechanism to be specified for each
    parameter.

    I suspect that your guess here is influenced more by what you would
    like to be true than what is likely to be true.

    I was influenced by what I thought made the most sense.

    What is likely to be true is that these terms entered the language
    at essentially the same time as the original Algol. Algol 60 has
    both call by name and call by value, referred to by those names in
    the Algol 60 Report, and selectable on a per-parameter basis.

    By contrast the precursor to Algol 60, the International Algebraic
    Language or IAL for short (and referred to after the fact as Algol
    58) did not use either term, and described the coupling between
    arguments and parameters only in somewhat vague English prose that
    left unclear exactly what the binding mechanism(s) were to be.
    (There was a description for functions and a separate description
    for procedures, not quite the same, and both not completely clear
    exactly what the mechanism was meant to be.)

    Thus it seems likely that the terms call by name, call by value,
    and perhaps other similar terms, first arose during the discussions
    of the Algol 60 working group in the late 1950s, and entered the
    general lexicon with or perhaps slightly before the publication of
    the Algol 60 Report, which describes and allows both call by name
    and call by value, selectable on a per-parameter base, and referred
    to by those names in the published Algol 60 Report.

    Yes, that does seem likely.

    I'm mildly disappointed. Since arguments are *passed* and
    functions/procedures are *called*, surely it would have made more sense
    to use "pass by value" rather than "call by value", especially in a
    language where the mechanism can vary per parameter.

    All that is, I think, due to subsequent changes in (English) language
    use. In Algol 60, procedures were invoked and /parameters/ were called
    by value or name. Maybe the term was intended to reflect the idea that
    the code in the body "called for the value" of the parameter.

    The word "call" now refers, almost universally, to invoking a function
    or procedure. As a result, the idea of "calling a parameter" reads
    oddly, but at the time I'm sure it seemed perfectly reasonable.

    This view simply doesn't match the language and phrasing used
    during the time Algol was being developed. Both the Algol 60
    report and the preliminary IAL report (aka Algol 58) routinely
    use the word call in connection with outside use of a procedure.
    Algol 60 uses the word "invoke" exactly twice: once in relation
    to procedures (where "call" is also used), and once in relation
    to functions. Algol 58 uses the word call pretty much the same
    way that Algol 60 does, but doesn't use the word "invoke" at all;
    the verb "initiate" a procedure in Algol 58 turned into "invoke"
    a procedure in Algol 60. Clearly using "call" was already well
    established in the late 1950s, and "invoke" came later.

    Algol 58 (loosely) defined the semantics of procedure call by
    textual expansion of the procedure body at the call site,
    substituting the text of actual parameters for each occurrence of
    the corresponding formal parameter in the procedure body. The
    actual rules are more complicated, due to there being different
    "styles" (my word) of parameters, and because there were output
    parameters as well as input parameters. Basically though the
    meaning was what would later be termed "call by name", with some
    restrictions on what forms of actual parameters were allowed.

    Algol 60 simplified the rules by reducing the number of cases to
    just two: either the actual parameter was textually substituted
    for the formal parameter in the expansion (call by name), or the
    value of the actual parameter expression was in effect assigned
    to a local variable corresponding to the formal parameter (call
    by value), which did not have a corresponding case in Algol 58.
    The "call by" in "call by name" and "call by value" refers to how
    the expansion is done in elaborating the procedure call. The
    "call by" is not what sort of thing is passed, but what action is
    taken in doing the substitution/expansion.

    (Yes, this is my opinion.)

    If there's some reason why "call by value" actually made more sense
    than "pass by value", I'm not aware of it.

    Since the phrase "pass by value" is now in common use, I'll
    continue to use that term in preference to "call by value"
    (likewise "by reference").

    I use those terms too. It would be confusing these days to talk
    about calling a parameter, and the phrase "call by value" suggests
    (as it never did at the time) something so do with the function
    calling mechanism in general.

    Yes it did. It is only now that we have a different idea about
    how functions and procedures are called that it seems like it
    doesn't. But in Algol 60 it certainly did have something to do
    with how a function reference was elaborated (aka called).

    This is compounded by the fact that modern programming languages
    has almost universally settled on calling all parameters by value
    (to the use the old phrase) so, usually, the terms can, in fact,
    be used to talk about the function calling mechanism.

    The rationale here seems circular to me, and also not an accurate
    picture of the programming language landscape.

    Passing a pointer by value is not the same as a call be reference.

    Passing a lambda by value is not the same as a call by name.

    Shortly after Algol 60, FORTRAN adopted call by value/result,
    also called call by copy in/copy out. Ada has INOUT, does
    it not?

    Logic programming languages have call by unification.

    All of these cases show why "pass by" is not a good universal
    fit.

    At their lowest level, computers are simply slinging bits around.
    In some sense everything is done in terms of "values". Thinking
    in terms of what "value" is "passed" serves to reinforce an
    imperative mind set, and there is already too much of that. For
    these reasons and more I disdain the hoi polloi phrasing of "pass
    by" for distinguishing different parameter modalities.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Tim Rentsch on Mon Sep 16 22:41:26 2024
    Tim Rentsch <[email protected]> writes:

    Ben Bacarisse <[email protected]> writes:

    Keith Thompson <[email protected]> writes:

    Tim Rentsch <[email protected]> writes:

    Keith Thompson <[email protected]> writes:

    Kaz Kylheku <[email protected]> writes:

    On 2024-07-12, bart <[email protected]> wrote:

    It's clearly not by value. It's apparently not by reference. You >>>>>>> can't get away with saying they are not passed, as clearly
    functions *can* access array data via parameters.

    Actually, you probably can get away with saying that it is "passed >>>>>> by reference".

    The formal term that doesn't apply is "call by reference"; that's >>>>>> what C doesn't have.

    "call by reference" emphasizes that the function call mechanism
    provides the reference semantics for a formal parameter, not that
    some arbitrary means of passage of the data has reference
    semantics.

    [...]

    I know that "call by reference" is the usual formal term, but I
    personally prefer "pass by reference".

    The terms "call by reference" and "call by value" emphasize the
    call, implying that all arguments in a given call are passed with
    the same mechanism. In some languages that's true (C argument
    passing is purely by value, and Fortran, as I understand it, is
    purely by reference), but in others (C++, Pascal, Ada) you can
    select by-value or by-reference for each parameter. "Pass by
    (reference|value)" feels more precise.

    I haven't checked, but I suspect the terms "call by (reference|value)" >>>>> predate languages that allowed the mechanism to be specified for each >>>>> parameter.

    I suspect that your guess here is influenced more by what you would
    like to be true than what is likely to be true.

    I was influenced by what I thought made the most sense.

    What is likely to be true is that these terms entered the language
    at essentially the same time as the original Algol. Algol 60 has
    both call by name and call by value, referred to by those names in
    the Algol 60 Report, and selectable on a per-parameter basis.

    By contrast the precursor to Algol 60, the International Algebraic
    Language or IAL for short (and referred to after the fact as Algol
    58) did not use either term, and described the coupling between
    arguments and parameters only in somewhat vague English prose that
    left unclear exactly what the binding mechanism(s) were to be.
    (There was a description for functions and a separate description
    for procedures, not quite the same, and both not completely clear
    exactly what the mechanism was meant to be.)

    Thus it seems likely that the terms call by name, call by value,
    and perhaps other similar terms, first arose during the discussions
    of the Algol 60 working group in the late 1950s, and entered the
    general lexicon with or perhaps slightly before the publication of
    the Algol 60 Report, which describes and allows both call by name
    and call by value, selectable on a per-parameter base, and referred
    to by those names in the published Algol 60 Report.

    Yes, that does seem likely.

    I'm mildly disappointed. Since arguments are *passed* and
    functions/procedures are *called*, surely it would have made more sense
    to use "pass by value" rather than "call by value", especially in a
    language where the mechanism can vary per parameter.

    All that is, I think, due to subsequent changes in (English) language
    use. In Algol 60, procedures were invoked and /parameters/ were called
    by value or name. Maybe the term was intended to reflect the idea that
    the code in the body "called for the value" of the parameter.

    The word "call" now refers, almost universally, to invoking a function
    or procedure. As a result, the idea of "calling a parameter" reads
    oddly, but at the time I'm sure it seemed perfectly reasonable.

    This view simply doesn't match the language and phrasing used
    during the time Algol was being developed. Both the Algol 60
    report and the preliminary IAL report (aka Algol 58) routinely
    use the word call in connection with outside use of a procedure.
    Algol 60 uses the word "invoke" exactly twice: once in relation
    to procedures (where "call" is also used), and once in relation
    to functions. Algol 58 uses the word call pretty much the same
    way that Algol 60 does, but doesn't use the word "invoke" at all;
    the verb "initiate" a procedure in Algol 58 turned into "invoke"
    a procedure in Algol 60. Clearly using "call" was already well
    established in the late 1950s, and "invoke" came later.

    Algol 58 (loosely) defined the semantics of procedure call by
    textual expansion of the procedure body at the call site,
    substituting the text of actual parameters for each occurrence of
    the corresponding formal parameter in the procedure body. The
    actual rules are more complicated, due to there being different
    "styles" (my word) of parameters, and because there were output
    parameters as well as input parameters. Basically though the
    meaning was what would later be termed "call by name", with some
    restrictions on what forms of actual parameters were allowed.

    Algol 60 simplified the rules by reducing the number of cases to
    just two: either the actual parameter was textually substituted
    for the formal parameter in the expansion (call by name), or the
    value of the actual parameter expression was in effect assigned
    to a local variable corresponding to the formal parameter (call
    by value), which did not have a corresponding case in Algol 58.
    The "call by" in "call by name" and "call by value" refers to how
    the expansion is done in elaborating the procedure call. The
    "call by" is not what sort of thing is passed, but what action is
    taken in doing the substitution/expansion.

    (Yes, this is my opinion.)

    If there's some reason why "call by value" actually made more sense
    than "pass by value", I'm not aware of it.

    Since the phrase "pass by value" is now in common use, I'll
    continue to use that term in preference to "call by value"
    (likewise "by reference").

    I use those terms too. It would be confusing these days to talk
    about calling a parameter, and the phrase "call by value" suggests
    (as it never did at the time) something so do with the function
    calling mechanism in general.

    Yes it did. It is only now that we have a different idea about
    how functions and procedures are called that it seems like it
    doesn't. But in Algol 60 it certainly did have something to do
    with how a function reference was elaborated (aka called).

    This is compounded by the fact that modern programming languages
    has almost universally settled on calling all parameters by value
    (to the use the old phrase) so, usually, the terms can, in fact,
    be used to talk about the function calling mechanism.

    The rationale here seems circular to me, and also not an accurate
    picture of the programming language landscape.

    Passing a pointer by value is not the same as a call be reference.

    Passing a lambda by value is not the same as a call by name.

    Shortly after Algol 60, FORTRAN adopted call by value/result,
    also called call by copy in/copy out. Ada has INOUT, does
    it not?

    Logic programming languages have call by unification.

    All of these cases show why "pass by" is not a good universal
    fit.

    At their lowest level, computers are simply slinging bits around.
    In some sense everything is done in terms of "values". Thinking
    in terms of what "value" is "passed" serves to reinforce an
    imperative mind set, and there is already too much of that. For
    these reasons and more I disdain the hoi polloi phrasing of "pass
    by" for distinguishing different parameter modalities.

    Your disdain is noted, so I see no point in my making any technical
    points.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Janis Papanagnou on Tue Sep 17 06:15:46 2024
    Janis Papanagnou <[email protected]> writes:

    [excerpted for brevity]

    In the domain of German speaking countries - isn't Tim located there?
    (I somehow got the impression) - we've heard about "Parameterubergabe";
    [..] means passing, transferring, handing over, transmitting, etc.

    Because of that - and because I could not follow the thoughts of Tim's
    last paragraph with his conclusion; I didn't find it convincing - I'd
    think that "passing" would fit better, also in the light of historic
    usage [hereabouts], even though I've often heared (and also used) the
    phrase "call by" in the English CS domain in the past (and probably
    still used to it).

    If you have something to say to me please respond to my posting
    directly.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Janis Papanagnou on Tue Sep 17 12:52:20 2024
    Janis Papanagnou <[email protected]> writes:

    On 17.09.2024 15:15, Tim Rentsch wrote:

    Janis Papanagnou <[email protected]> writes:

    [excerpted for brevity]

    In the domain of German speaking countries - isn't Tim located there?
    (I somehow got the impression) - we've heard about "Parameterubergabe";
    [..] means passing, transferring, handing over, transmitting, etc.

    Because of that - and because I could not follow the thoughts of Tim's
    last paragraph with his conclusion; I didn't find it convincing - I'd
    think that "passing" would fit better, also in the light of historic
    usage [hereabouts], even though I've often heared (and also used) the
    phrase "call by" in the English CS domain in the past (and probably
    still used to it).

    If you have something to say to me please respond to my posting
    directly.

    I respond at the place that appears most appropriate for what
    I want to say in the context I want to reply to. I'm not here
    to serve your, umm, "standards" (to avoid the word "idee fixe");
    and you just have to accept that[*], I fear.

    I'm sure others here have no problem to go upward the thread
    hierarchy one more level to find your text that I deliberately
    didn't quote for the reason (still quoted above) I mentioned;
    I don't think they're worth quoting, they provide no argument,
    they were fuzzy. (Of course all only IMO.)

    My statement was meant as a request, not a demand. I asked
    because I wasn't sure if you had something in particular to
    say to me or if you were just talking more or less aimlessly.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Keith Thompson on Thu Sep 26 09:37:55 2024
    Keith Thompson <[email protected]> writes:

    Tim Rentsch <[email protected]> writes:

    Ben Bacarisse <[email protected]> writes:

    Keith Thompson <[email protected]> writes:

    Tim Rentsch <[email protected]> writes:

    Keith Thompson <[email protected]> writes:

    [...]

    I know that "call by reference" is the usual formal term, but
    I personally prefer "pass by reference".

    The terms "call by reference" and "call by value" emphasize
    the call, implying that all arguments in a given call are
    passed with the same mechanism. In some languages that's
    true (C argument passing is purely by value, and Fortran, as
    I understand it, is purely by reference), but in others (C++,
    Pascal, Ada) you can select by-value or by-reference for each
    parameter. "Pass by (reference|value)" feels more precise.

    I haven't checked, but I suspect the terms "call by
    (reference|value)" predate languages that allowed the
    mechanism to be specified for each parameter.

    I suspect that your guess here is influenced more by what
    you would like to be true than what is likely to be true.

    I was influenced by what I thought made the most sense.

    What is likely to be true is that these terms entered the
    language at essentially the same time as the original Algol.
    Algol 60 has both call by name and call by value, referred to
    by those names in the Algol 60 Report, and selectable on a
    per-parameter basis.

    By contrast the precursor to Algol 60, the International
    Algebraic Language or IAL for short (and referred to after the
    fact as Algol 58) did not use either term, and described the
    coupling between arguments and parameters only in somewhat
    vague English prose that left unclear exactly what the binding
    mechanism(s) were to be. (There was a description for
    functions and a separate description for procedures, not quite
    the same, and both not completely clear exactly what the
    mechanism was meant to be.)

    Thus it seems likely that the terms call by name, call by
    value, and perhaps other similar terms, first arose during the
    discussions of the Algol 60 working group in the late 1950s,
    and entered the general lexicon with or perhaps slightly before
    the publication of the Algol 60 Report, which describes and
    allows both call by name and call by value, selectable on a
    per-parameter base, and referred to by those names in the
    published Algol 60 Report.

    Yes, that does seem likely.

    I'm mildly disappointed. Since arguments are *passed* and
    functions/procedures are *called*, surely it would have made
    more sense to use "pass by value" rather than "call by value",
    especially in a language where the mechanism can vary per
    parameter.

    All that is, I think, due to subsequent changes in (English)
    language use. In Algol 60, procedures were invoked and
    /parameters/ were called by value or name. Maybe the term was
    intended to reflect the idea that the code in the body "called
    for the value" of the parameter.

    The word "call" now refers, almost universally, to invoking a
    function or procedure. As a result, the idea of "calling a
    parameter" reads oddly, but at the time I'm sure it seemed
    perfectly reasonable.

    This view simply doesn't match the language and phrasing used
    during the time Algol was being developed. Both the Algol 60
    report and the preliminary IAL report (aka Algol 58) routinely
    use the word call in connection with outside use of a procedure.
    Algol 60 uses the word "invoke" exactly twice: once in relation
    to procedures (where "call" is also used), and once in relation
    to functions. Algol 58 uses the word call pretty much the same
    way that Algol 60 does, but doesn't use the word "invoke" at all;
    the verb "initiate" a procedure in Algol 58 turned into "invoke"
    a procedure in Algol 60. Clearly using "call" was already well
    established in the late 1950s, and "invoke" came later.

    Algol 58 (loosely) defined the semantics of procedure call by
    textual expansion of the procedure body at the call site,
    substituting the text of actual parameters for each occurrence of
    the corresponding formal parameter in the procedure body. The
    actual rules are more complicated, due to there being different
    "styles" (my word) of parameters, and because there were output
    parameters as well as input parameters. Basically though the
    meaning was what would later be termed "call by name", with some
    restrictions on what forms of actual parameters were allowed.

    Algol 60 simplified the rules by reducing the number of cases to
    just two: either the actual parameter was textually substituted
    for the formal parameter in the expansion (call by name), or the
    value of the actual parameter expression was in effect assigned
    to a local variable corresponding to the formal parameter (call
    by value), which did not have a corresponding case in Algol 58.
    The "call by" in "call by name" and "call by value" refers to how
    the expansion is done in elaborating the procedure call. The
    "call by" is not what sort of thing is passed, but what action is
    taken in doing the substitution/expansion.

    (Yes, this is my opinion.)

    If there's some reason why "call by value" actually made more
    sense than "pass by value", I'm not aware of it.

    Since the phrase "pass by value" is now in common use, I'll
    continue to use that term in preference to "call by value"
    (likewise "by reference").

    I use those terms too. It would be confusing these days to talk
    about calling a parameter, and the phrase "call by value" suggests
    (as it never did at the time) something so do with the function
    calling mechanism in general.

    Yes it did. It is only now that we have a different idea about
    how functions and procedures are called that it seems like it
    doesn't. But in Algol 60 it certainly did have something to do
    with how a function reference was elaborated (aka called).

    This is compounded by the fact that modern programming languages
    has almost universally settled on calling all parameters by value
    (to the use the old phrase) so, usually, the terms can, in fact,
    be used to talk about the function calling mechanism.

    The rationale here seems circular to me, and also not an accurate
    picture of the programming language landscape.

    Passing a pointer by value is not the same as a call be reference.

    Passing a lambda by value is not the same as a call by name.

    Shortly after Algol 60, FORTRAN adopted call by value/result,
    also called call by copy in/copy out. Ada has INOUT, does
    it not?

    Logic programming languages have call by unification.

    All of these cases show why "pass by" is not a good universal
    fit.

    How? All I see is that you've used the word "call" rather than
    "pass" in each instance -- and in each instance, I find "pass"
    clearer (except perhaps in the case of "call by name", for reasons
    I won't go into for the moment).

    At their lowest level, computers are simply slinging bits around.
    In some sense everything is done in terms of "values". Thinking
    in terms of what "value" is "passed" serves to reinforce an
    imperative mind set, and there is already too much of that. For
    these reasons and more I disdain the hoi polloi phrasing of "pass
    by" for distinguishing different parameter modalities.

    I honestly do not understand the argument you're making in favor of
    "call by" over "pass by". ("Hoi polloi"? Seriously?)

    Procedures and functions are "called", yes? They're not "passed",
    except perhaps as an argument to another procedure or function.

    Arguments to procedures and functions are "passed", yes? Would it
    make sense to say that an argument is "called"? (I note that the
    Algol 60 report never refers to parameters being "called" other than
    in the phrases "call by value" and "call by name".)

    If you think that "calling an argument" or "calling a parameter"
    makes sense, perhaps that's the root of the disagreement. Do you?

    In most languages that supports by both by-value and by-reference
    mechanisms, a single call can have one by-value argument and one
    by-reference argument, or any other combination. Using C++ as a
    convenient example:

    void func(int by_value, int& by_reference) { /* ... */ }
    int x, y;
    func(x, y);

    In the third line, there is just one call, but two arguments,
    corresponding to two parameters. It's not the call that's by-value
    or by-reference, it's each argument that's *passed* (using the
    mechanism specified on the parameter).

    Other than historical precedent from Algol and friends, why do you
    think it's better to use "call by value" and "call by reference"
    rather than "pass by value" and "pass by reference", when the
    mechanism applies individually to each argument, not to the call as
    a whole?

    Do you object to using the word "pass" (without "by ...") to refer
    to the arguments to a function? If not, why do you object to "pass
    by ..." to refer to the mechanism?

    After reading your message I spent several hours thinking about how
    to answer before starting to write a reply. I ask that you take a
    commensurate amount of time considering my comments before composing
    any followup.

    I think it's fair to say we are looking at this question from
    different perspectives. I see where you're coming from; I get
    why you're saying what you say. For the other direction my guess
    is that my perspective either isn't apparent or isn't one that
    makes sense to you. Let me see if I can shed some light on that.

    The "call by" in Algol 60 is used to characterize /parameters/ of
    a function definition. It's important that "call" is used in the
    active voice; parameters are not "called". The word "call" has
    changed in meaning since its use in the Algol 60 report, so let's
    consider some plausible alternatives (always in the active voice):

    associate by
    elaborate by
    expand by
    instantiate by
    substitute by

    For an example, let's suppose we have a by-name parameter (and for
    now let's use the "associate by" phrasing). Writing in a made-up
    C-like language that allows different parameter modalities, we
    could write

    void
    by_name_example( unsigned by_name i, double by_name v ){
    for( i = 0; i < 100; i++ ) v = 1. / ((i+1)*(i+1));
    }

    and a call

    unsigned foo;
    double terms[100];

    by_name_example( foo, terms[foo] );

    In calling by_name_example(), we associate argument 'foo' with
    parameter 'i', and associate argument 'terms[foo]' with 'v'.
    The associations are done by-name of course, because of how
    the two parameters are declared.

    Some history could be helpful here. In the Algol 60 report,
    function calls were explained, or defined, as a kind of textual
    substitution. In effect the body of a function definition would
    be substituted for the call. (The original description uses a
    different phrasing but the effect is the same.) Because of that
    the phrasing "call by" makes sense: arguments for different kinds
    of parameters are expanded or substituted differently. The
    meanings of the different parameter modes were explained in terms
    of the abstract semantics, and not in terms of how they might be
    implemented. Indeed, when the Algol 60 report was first published
    it wasn't yet understood how to implement call by name. (Or
    perhaps it was discovered just slightly before publication, I'm
    not sure of the exact timing.)

    Here is an example function with a call by reference parameter:

    void
    accumulate( unsigned v, unsigned by_reference total ){
    total += v;
    }

    Now let's consider some calls:

    unsigned long foo = 0;
    accumulate( 3, 0 );
    accumulate( 5, foo );

    Are these calls legal or not legal? (Either answer is possible.)
    This illustrates the point that it isn't so important /what/ is
    conveyed as it is /how/ the call is done. Saying these are "pass
    by reference" emphasizes /what kind of information/ is conveyed
    but downplays the more important aspect of /how an argument is
    associated with the parameter/.

    A different example, with a FORTRAN-style parameter mode (which is
    call by value-result, aka call by copy in/copy out):

    int
    exchange( unsigned by_in_out x, unsigned by_in_out y ){
    unsigned a = x, b = y;
    x = b, y = a;
    /* ... some other stuff ... */
    }

    This function exchanges its arguments, and also does some other
    stuff. However, it's important that updating of the arguments
    happens only when the function returns; if "other stuff" makes
    use of the arguments (not by way of the parameters x and y but via
    some other path), it will see the original values of those
    arguments, not the values assigned on the second line of the
    function. Any call by value-result parameters changes not only
    what happens at the call but also what happens at the return;
    using "pass by" is not evocative of that meaning.

    Suppose we modify the exchange function slightly:

    int
    exchange_two( unsigned by_in_out x, unsigned by_in_out y ){
    unsigned a = x, b = y;
    x = b, y = a;
    if( something ) longjmp( some_jmp_buff, 23 );
    }

    If the longjmp() is done, are the arguments corresponding to the
    parameters x and y updated or not? (Either answer is possible.)
    Here again "pass by" emphasizes what kind of information is
    conveyed, now how the call (and return, and possibly the longjump)
    is done. A by value-result parameter affects the semantics of
    /calling/ a function, and so "call by value-result" is more
    suggestive of what is going on than "pass by value-result".

    Not all programming languages are procedural. "Pass by" tacitly
    assumes a procedural semantics for function calls: it's passive
    rather than active, and suggests only conveying of data (and not
    doing anything else). Programs written in Prolog do something
    very different when they call a "function" (Prolog calls them
    something else but operationally it resembles a function call).
    In Prolog the semantics of how arguments are associated with
    parameters is referred to as "call by unification"; how arguments
    interact with the function definition is deeply intertwined with
    how "function" calls work in Prolog. "Pass by" doesn't begin to
    capture what is going on with how arguments interact with the
    bodies of "functions" in Prolog; among other things, parameters
    are not necessarily independent, and arguments can't always be
    considered only individually (which is not the case for call by
    value, call by reference, and call by name).

    Saying "pass by" sort of works okay for parameters that are
    by-value or by-reference. It doesn't work as well for "by name"
    parameters (certainly it is not a name that is being passed), and
    really falls down for call by value-result, let alone what happens
    with call by unification. Parameters are call-by because they can
    affect how the function is called, both going in and going out.
    Call-by shows an abstract semantics perspective rather than an
    implementation perspective, and because of that applies more
    universally than pass-by, which doesn't make sense outside of
    a certain limited procedural context.

    I guess I'll stop here. I've made a fairly substantial effort to
    convey my perspective, but I'm not sure the effort will succeed.
    So let me ask this: how would you describe my perspective, and
    how would you say it's different from yours? Or has reading my
    explanation allowed you to view the question from a different
    perspective?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Keith Thompson on Tue Oct 29 08:07:23 2024
    Keith Thompson <[email protected]> writes:

    I won't ask you to reply to this.

    I didn't ask you to reply to my posting.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)